今天刷了一道比较简单的链表题,感觉还是不顺手,下面和大家来分享一下经验吧!
题目如下:
Given a sorted linked list, delete all duplicates such that each element appear only once.
Example 1:
Input: 1->1->2
Output: 1->2
Example 2:
Input: 1->1->2->3->3
Output: 1->2->3
题意分析:
给定一个有序的链表,删除所有的重复元素,并确保每个元素只出现一次。
解答如下:
方法一(非递归法)
首先,用两个指针分别指向链表前面两个节点,其次,通过比较它们的值,如果值相等则改变 ->next来“跳过”重复节点,最后,返回头节点指针。
class Solution{
public:
ListNode* deleteDuplicates(ListNode* head){
ListNode* cur = head;
ListNode* nex;
while( cur ){
nex = cur -> next;
if ( nex && cur -> val == nex -> val ) //nex要放在前方,要确保nex不为空,否则无法用 ->val
cur ->next = nex -> next; //这里不可以cur = nex,否则无法处理连续的3个重复值
else
cur = nex;
}
return head;
}
};
提交后的结果如下:
方法二(递归法)
首先,判断是否至少有两个节点,若没有则直接返回head,否则对head->next调用递归函数,并赋值给head->next。递归这一块可能比较不好理解,所以先看后面一句,返回的时候,head节点先跟其后的节点进行比较,如果值相同,那么返回后面的一个节点,相当于当前的head节点就被跳过了,而如果不同的话,还是返回head结点,因此进行实质上的删除操作是在最后一句进行的,再来看第二句,对head后面的节点调用递归函数,那么递归回溯返回来的链表就不会有重复项了,然后再接到head节点后面,最后到第三句的时候再来检查一下head是否又duplicate了。
注:实际上递归一直走到了末尾结点,再不断的回溯回来,进行删除重复结点。
class Solution {
public:
ListNode* deleteDuplicates(ListNode* head) {
if (!head || !head->next) return head;
head->next = deleteDuplicates(head->next); //递归调用
return (head->val == head->next->val) ? head->next : head; //回溯过程中“跳过”重复节点
}
};
提交后的结果如下:
日积月累,与君共进,增增小结,未完待续。