题目:
Given the head
of a sorted linked list, delete all nodes that have duplicate numbers, leaving only distinct numbers from the original list. Return the linked list sorted as well.
Example 1:
Input: head = [1,2,3,3,4,4,5] Output: [1,2,5]
Example 2:
Input: head = [1,1,1,2,3] Output: [2,3]
Constraints:
- The number of nodes in the list is in the range
[0, 300]
. -100 <= Node.val <= 100
- The list is guaranteed to be sorted in ascending order.
思路1:
一道比较老的题,先将loop的思路,首先确定肯定需要双指针进行,因为要和前面的值比较。同时因为头并不一定是给定的那个head,比如是[1,1,2, 3],因此先令ans为空,然后在循环的时候判断,如果为空就直接赋值给它,否则就赋值给它的next。中间循环判断我写的有一点点复杂,感觉上代码结构可以继续优化,分两种情况:当前和前一节点相同,则一直往下走,找出第一个不同的节点,进行迭代更新然后参与下一轮循环;如果是不同的话直接赋值即可。最后一个点需要进行额外判断,判断方法也很简单,如果迭代的第一个节点存在但是下一个不存在,比如[1, 1, 2, 3, 5],p节点是5,这时候q是NULL,我们从q是无法判断的,但是如果p的下一个是NULL,那么这个最后的节点就是独一无二的。如果我们只用q判断[1, 1, 2, 3, 5, 5],因为5有过循环,q这时候一定是NULL,因此我们通过p而不是通过q来判断最后一个节点。
代码1:
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode() : val(0), next(nullptr) {}
* ListNode(int x) : val(x), next(nullptr) {}
* ListNode(int x, ListNode *next) : val(x), next(next) {}
* };
*/
class Solution {
public:
ListNode* deleteDuplicates(ListNode* head) {
if (!head)
return NULL;
ListNode* p = head;
ListNode* q = p->next;
if(!q)
return p;
ListNode* ans = NULL;
ListNode* temp = ans;
while (q)
{
if (p->val != q->val)
{
if (!ans)
{
ans = p;
temp = ans;
temp->next = NULL;
}
else
{
temp->next = p;
temp = temp->next;
temp->next = NULL;
}
}
else
{
while (q&&p->val == q->val)
{
q = q->next;
}
}
p = q;
if (p&&p->next)
q = q->next;
else
q = NULL;
}
if (temp)
{
if(p && !p->next)
temp->next = p;
}
else
ans=p;
return ans;
}
};
思路2:
递归是个更加常规的思路,因为base case很明显,首先如果当前或者下一个是空,则直接返回空;如果当前和下一个不同,直接返回当前(这里对于最后一个节点的判断就很方便了,不用像loop一样需要额外考虑);如果当前和下一个节点的值相同的话,那就一直往下走,找到不同的那个节点再次递归。时间复杂度相同,但是从代码结构显然递归更适合。
代码2:
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode() : val(0), next(nullptr) {}
* ListNode(int x) : val(x), next(nullptr) {}
* ListNode(int x, ListNode *next) : val(x), next(next) {}
* };
*/
class Solution {
public:
ListNode* deleteDuplicates(ListNode* head) {
if(!head || !head->next)
return head;
if(head->val == head->next->val){
int val = head->val;
while(head && head->val == val)
head = head->next;
return deleteDuplicates(head);
}
else{
head->next = deleteDuplicates(head->next);
return head;
}
}
};