题目:删除有序链表中重复的元素
描述:删除给出链表中的重复元素(链表中元素从小到大有序),使链表中的所有元素都只出现一次
例如:给出的链表为1→1→2,返回1→2.
给出的链表为1→1→2→3→3,返回1→2→3.
思路分析:根据题意,我们分析,要删除有序链表当中重复的元素使所有重复元素只出现一次,在这个过程当中,可以选定两个链表指针i和j,通过设定i为head,j为i.next,依次通过循环将重复元素的个数减为0,如果没有发现重复的元素,令j = j.next,再次进行判断;如果发现有重复元素,令i.next = j.next,除掉重复元素,依次递归进行判断。
实例分析:1→1→2→3→3
| 链表 | 1 | 1 | 2 | 3 | 3 |
|
| i | j |
|
|
|
| 首先判断链表指针i的值等于j的值,令i.next = j.next,除掉元素1 | |||||
|
| 1 |
| 2 | 3 | 3 |
| …… | |||||
|
|
|
| i | j |
|
| 循环结束,暂无发现重复元素 | |||||
|
| 1 |
| 2 | 3 | 3 |
|
|
|
|
| i | j |
| 指针i的值等于j的值,令i.next = j.next,除掉元素3,最终返回 | |||||
| 链表 | 1 | 2 | 3 |
|
|
具体C++代码为:
/**
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
class Solution {
public:
/**
*
* @param head ListNode类
* @return ListNode类
*/
ListNode* deleteDuplicates(ListNode* head) {
// write code here
if(head == NULL)
return NULL;
for(ListNode* i = head; i != NULL; i = i->next){//挨个进行比较
for(ListNode *j = i->next; j != NULL; j = j->next){
if(i->val == j->val)
i->next = j->next;//删除重复元素
}
}
return head;
}
};
因为采用暴力法进行分析,并且设定了两个for循环进行逐个判断,所以时间复杂度为O(N^2),空间复杂度为O(1)。
我们也可以这样编写C++程序:
/**
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
class Solution {
public:
ListNode* deleteDuplicates(ListNode* head) {
ListNode * p = head;
if (p == NULL){
return head;
}
while (p->next != NULL){
if (p->val == p->next->val){//关键步骤
p->next = p->next->next;//删除结点
}
else{
p = p->next;
}
}
return head;
}
};
解法二:
思路分析:因为是一个升序的链表,所以可以设定一个结点作为头节点保存最终的结果,即在最后返回的时候,返回该结点的next值即可,使用指针cur遍历链表,因为是升序,所以当遇到两个值不相等时,可以将p和cur直接移动到下一个结点接着遍历即可,当重复结点全部删除后,方可返回最终的链表值。
具体java代码如下所示:
import java.util.*;
/*
* public class ListNode {
* int val;
* ListNode next = null;
* }
*/
public class Solution {
/**
*
* @param head ListNode类
* @return ListNode类
*/
public ListNode deleteDuplicates(ListNode head) {
ListNode node = new ListNode(-1); //创建一个头节点
node.next = head;
ListNode p= node;
ListNode cur = head;
while (cur!= null && cur.next != null) {//只要不为空,就继续
if(cur.val != cur.next.val) {//两个值不等的话
p = cur;
}
else {
while (cur.next != null && cur.val == cur.next.val)//相等的话
cur = cur.next;
p.next = cur.next;
}
cur = cur.next;
}
return node.next;//因为有头结点
}
}
只要cur链表不为空,就继续循环,所以其时间复杂度为O(N),空间复杂度为O(N)。

京公网安备 11010502036488号