在一个有序链表中,如果说一个节点的值出现不止一次,那么把所有等于此值的节点全部删掉。
敲黑板:有序链表,那如果一个节点的值出现不止一次,那么它们必须相邻。
三种解法来做
下面用两种方法 :递归,迭代,其中迭代又分为两种方法。
递归来解
链表和树的问题,一般都可以用递归和迭代两种写法。对于这道题一定记住它是有序链表,所以值相同的节点会在一起的。
1.1 递归函数定义
递归最基本的是要明白递归函数的定义! 我反复反复强调过这一点。
递归函数直接使用题目给出的函数 deleteDuplicates(head)
,它的含义是 删除以 head
作为开头的有序链表中,值出现重复的节点。
1.2 递归终止条件
终止条件就是能想到的基本的、不用继续递归处理的情况
如果 head 为空,那么肯定没有值出现重复的节点,所以直接返回 head;
那如果 head.next
为空,那说明链表中只有一个节点,也没有值出现重复的节点,也直接返回 head 即可。
1.3 递归调用
什么时候需要递归呢?我们想一下 有两种情况:
如果 head.val != head.next.val
,说明头节点的值不等于下一个节点的值,所以当前的 head 节点必须保留下来;但是 head.next
节点要不要保留呢?我们还不知道,所以需要对 head.next`` 进行递归,即对
head.next作为头节点的链表,去除值重复的节点。所以
head.next = self.deleteDuplicates(head.next),那 如果
head.val == head.next.val,说明头节点的值等于下一个节点的值,所以当前的 head 节点必须删除掉,并且 head 之后所有与
head.val相等的节点也都需要删除;删除到哪个节点为止呢?需要用 move 指针一直向后遍历寻找到与
head.val不等的节点。此时 move 之前的节点都不保留了,因此返回
deleteDuplicates(move)`;
1.4 返回结果
题目让我们返回删除了值重复的节点后剩余的链表,结合上面两种递归调用的情况。
- 如果
head.val != head.next.val
,头结点需要保留,因此返回的是 head; - 如果
head.val == head.next.val
,头结点需要删除,需要返回的是deleteDuplicates(move);
对链表 1 -> 2 -> 2 -> 3 递归的过程如下。
class Solution {
public:
ListNode* deleteDuplicates(