• 链表之删除单链表中的重复节点


    删除单链表中的重复节点

    力扣链接

    题目描述

    编写代码,移除未排序链表中的重复节点。保留最开始出现的节点。

     示例1:
     输入:[1, 2, 3, 3, 2, 1]
     输出:[1, 2, 3]
     示例2:
     输入:[1, 1, 1, 1, 2]
     输出:[1, 2]
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    提示:

    1. 链表长度在[0, 20000]范围内。
    2. 链表元素在[0, 20000]范围内。
    解题思路

    思路一:

    • 定义两个指针current和p来逐个遍历链表
      • current指向的元素依次与p指向的元素的下一个元素进行比较
        • 若相同则删去p的下一个元素【即使p的next指向下下个元素(p的next的next),继续循环比较】
        • 若不相同则p往后移动一个位置,继续循环比较,直到p所指元素的下一个为空【只要后一个不为空则继续比较,否则 停止本次比较】
      • 若所有元素都与后面元素比较过了,则返回当前链表head

    思路二:

    • 定义p指针遍历链表,利用set,遇到一个元素就去set中找是否包含这个元素
      • 如果set中包含了当前元素,就说明当前遍历的元素属于重复节点,则删除
        • 利用s.count查询函数,返回的是一个整数,表示查询到元素的个数
      • 如果不包含,则添加进set中,并将p指针后移

    思路三:利用标记数组,标记当前值是否出现过

    代码实现

    //提供完整的代码,可以在C编辑器中进行测试

    #include 
    #include 
    
    using namespace std;
    
    struct ListNode{
    	int val;
    	ListNode *next;
    	ListNode(int x) : val(x),next(NULL){}
    }; 
    
    class Solution{
    public:
    	//方法一: 
    	ListNode* removeDuplicateNodes(ListNode* head){
    		//判断是否需要遍历
            if(head==NULL||head->next==NULL) return head;
    		
    		ListNode* current = head;
    		while(current){//第一重循环:将第i个元素依次与后面元素进行比较(i从1到最后)
    			ListNode *p = current;
    			while(p->next){//第二重循环:与后1个比、后2个比、后三个比...与最后一个比
    				if(p->next->val == current->val){
    					p->next = p->next->next;//删除p后面这个重复的元素
    				}else{
    					p = p->next;//p后移
    				}
    			}
    			current = current->next;//将第i+1个元素开始依次与后面元素进行比较
    		}
    		return head;//这里返回的一定是head,此时的head后面的链表已经删除了重复的元素 
    	}
    
    	//方法二: 
    	ListNode* removeDuplicateNodes2(ListNode* head){
    		if(head==NULL||head->next==NULL) return head;
    		
    		set s;
    		
    		ListNode* p = head;
    		s.insert(p->val);
    		
    		while(p->next){//只要还没到最后一个元素,就遍历
    			if(s.count(p->next->val)!=0){//包含了,则重复
    				p->next = p->next->next; 
    			}else{						//不重复,添加进去、后移
    				s.insert(p->next->val);	//或者可以先后移再添加,p=p->next;s.insert(p->val);
    				p = p->next;
    			}
    		}
    		return head;
    	}
        
        //方法三:
    	 ListNode* removeDuplicateNodes3(ListNode* head){
    	 	if(head==NULL||head->next==NULL) return head;
    	 	
    	 	//利用val的值在0~20000之间,标记是否出现过 
    	 	int index[20001] = {0};
    	 	index[head->val] = 1;
    	 	
    	 	struct ListNode* q = head;
    	 	
    	 	while(q->next){
    	 		//下一个val未出现过,保存下一个val 
    	 		if(index[q->next->val]==0){
    	 			index[q->next->val] = 1;
    	 			q = q->next;
    			 }else{							//下一个val出现过,删除下一个节点 
    			 	q->next = q->next->next;
    			 }
    		 }
    		 return head;
    	 }
    	
        //链表打印函数
    	void ListPrintf(ListNode* head){
    		
    		ListNode* pos = head;
    	 
    		while(pos){
    			cout<val<<"->";
    			pos = pos->next; 
    		}
    		cout <<"NULL"<next!=NULL){
    				pos = pos->next;
    			}
    			pos->next = newNode;
    		}
    	} 
    };
    
    
    int main(){
    	ListNode* test = new ListNode(1);
    	ListNode* result;
    	
    	class Solution s;	
    	
    	s.ListBackInsert(&test,2);
    	s.ListBackInsert(&test,3);
    	s.ListBackInsert(&test,3);
    	s.ListBackInsert(&test,2);
    	s.ListBackInsert(&test,1);
    	s.ListPrintf(test);
    	
    	result = s.removeDuplicateNodes(test);
    	//result = s.removeDuplicateNodes2(test);
    	//result = s.removeDuplicateNodes3(test);
    	s.ListPrintf(result);
    
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125

    结果:
    image-20221127180021258

  • 相关阅读:
    季节性壁炉布置:让您的家温馨如冬季仙境
    网络安全(黑客)自学
    python 模拟后台点击
    令无数站长闻风丧胆的 DDoS 攻击到底是什么
    二合一的集度,任重道远
    PyCharm鼠标控制字体缩放
    docker访问外部https数字证书问题
    Deno入门:Node.js的现代替代品
    基于SSM+MySQL+Bootstrap的停车场管理系统
    RabbitMQ内容
  • 原文地址:https://blog.csdn.net/weixin_44952783/article/details/128067609