每日一恋 - LeetCode 82 & 83. Remove Duplicates from Sorted List(删除排序链表中的重复元素)

83 删除排序链表中的重复元素 题目描述

给定一个排序链表,删除所有重复的元素,使得每个元素只出现一次。

示例 1:

输入: 1->1->2
输出: 1->2

示例 2:

输入: 1->1->2->3->3
输出: 1->2->3

分析

这道题,如果这样想:每次只比较相邻的两个结点,如果不同则向前移动;如果相同,则将删除相邻的第二个结点。循环结束就删除了所有重复的元素。

public ListNode deleteDuplicates(ListNode head) {

    if (head == null)
        return null;

    ListNode prev = head;
    while (prev.next != null) {
        if (prev.val == prev.next.val)  // 相同,删除之
            prev.next = prev.next.next;
        else // 不同,跳过
            prev = prev.next;
    }

    return head;
}

82 删除排序链表中的重复元素 II 题目描述

给定一个排序链表,删除所有含有重复数字的节点,只保留原始链表中 没有重复出现 的数字。

示例 1:

输入: 1->2->3->3->4->4->5
输出: 1->2->5

示例 2:

输入: 1->1->1->2->3
输出: 2->3

分析

递归版本

和前面那道题不同的地方在于,这里要删除所有重复的数字。递归版本,这道题分为两种情况,一种是删除本结点以及后面若干相同结点,另一种是不删除当前结点(当前结点和后面的结点不同),连接到后面处理过的链表,递归下去,直到结点个数只有一个的时候结束。

public ListNode deleteDuplicates(ListNode pHead) {
    // 个数等于 0 和 1 ,返回pHead
    if (pHead == null || pHead.next == null)
        return pHead;

    // 当前结点重复
    if (pHead.val == pHead.next.val) { 
        ListNode node = pHead.next;
        // 删完连续相同的结点
        while (node != null && node.val == pHead.val) node = node.next;
        return deleteDuplicates(node);
    }
    else // 当前结点不重复
        pHead.next = deleteDuplicates(pHead.next);

    return pHead;
}

非递归版

由于头结点也有可能被删除,所以要定义一个新结点,连接上新的链表。然后定义一个前驱指针和一个现指针,每当前驱指针指向新建结点时,现指针就从下一个位置往下遍历,遇到相同的则继续往下,遇到不同的则前驱指针指向下一个不同的元素,如果现指针判断的第一个元素就不相同,则把前驱指针向下移一位。

public ListNode deleteDuplicates(ListNode pHead) {
    if (pHead == null || pHead.next == null)
        return pHead;

    ListNode start = new ListNode(0);
    start.next = pHead;
    ListNode pre = start;
    while (pre.next != null) {
        ListNode cur = pre.next;
        while (cur.next != null && cur.next.val == cur.val) cur = cur.next;
        if (cur != pre.next) pre.next = cur.next;
        else pre =pre.next;
    }
    return pHead;
}

如果文章里有说得不对的地方请前辈多多指正~ 与君共勉~

猜你喜欢

转载自blog.csdn.net/smartnijun/article/details/81744774