题目
给定一个有序链表,删除所有重复的元素,使得每个元素只出现一次。
示例:
给定 1 -> 1 -> 2,返回 1 -> 2.
给定 1 -> 1 -> 2 -> 3 -> 3,返回 1 -> 2 -> 3。
难度:容易
编程语言:C++
分析
程序框架为:
1 2 3 4 5 6 7 8 9 10 11 12 13
| struct ListNode { int val; ListNode* next; ListNode(int x) : val(x), next(NULL) {} }; class Solution { public: ListNode* deleteDuplicates(ListNode* head) { } };
|
我的思路是,遍历链表的所有元素,每遍历一个元素,判断该元素值是否跟下一个元素值相同,如果相同,则删除下一个元素。
伪代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| ListNode* deleteDuplicates(ListNode* head) { ListNode* temp = head; while (temp != NULL) { if (temp->next != NULL && temp->val == temp->next->val) { // 删除 temp->next temp->next = temp->next->next; // 清空重复元素占用的内存 } // 后移 temp temp = temp->next; } return head; }
|
提交到 Leetcode,Wrong Answer! 对于输入 [1, 1, 1],正确的应该是输出 [1],我的函数输出了 [1, 1]。
原因是,不管 temp->val 是否等于 temp->next->val,在 if 处理后都会 temp = temp->next,所以实际上只删除了奇数个重复元素。即是对于输入 [1, 1, 1, 1, 1],我的函数会输出 [1, 1, 1],仅把第 2、4 个 1 删除。
上面的整个思路都错了,或者说没有想完整。应该是每遍历一个元素,判断该元素值是否跟下一个元素值相同,如果相同,则删除下一个元素。直到发现下一个元素值跟本元素值不一样,本元素的指针才后移一位。
伪代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| ListNode* deleteDuplicates(ListNode* head) { ListNode* temp = head; while (temp != NULL) { if (temp->next != NULL) { if (temp->val == temp->next->val) { temp->next = temp->next->next; // 清空重复元素占用的内存 } else { temp = temp->next; } } else { return head; } } return head; }
|
代码如下:
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
| #include <iostream> using namespace std; struct ListNode { int val; ListNode* next; ListNode(int x) : val(x), next(NULL) {} }; class Solution { public: ListNode* deleteDuplicates(ListNode* head) { ListNode* temp = head; while (temp != NULL) { if (temp->next != NULL) { if (temp->val == temp->next->val) { temp->next = temp->next->next; } else { temp = temp->next; } } else { return head; } } return head; } }; void printLinkedlist(ListNode* head) { while (head != NULL) { cout << head->val << ' '; head = head->next; } cout << endl; } int main() { ListNode n1(1); ListNode n2(1); ListNode n3(1); ListNode n4(1); ListNode n5(1); n1.next = &n2; n2.next = &n3; n3.next = &n4; n4.next = &n5; printLinkedlist(&n1); Solution sol; sol.deleteDuplicates(&n1); printLinkedlist(&n1); }
|
提交到 Leetcode,Accepted! :) 运行时间为 16ms。
另外一个经验是,尽量不要 if 里有多重判断,每个 if 只判断一个条件。每个 if 都考虑 else 分支。