删除链表中的重复元素

题目:lq82:删除排序链表中的重复元素 II

给定一个已排序的链表的头head,删除原始链表中所有重复数字的节点,只留下不同的数字,返回已排序的链表。

 解析:

方法一:一次遍历

首先我们看到此题中的链表是排好序的,那说明重复的元素都是连在一起的,我们可以构建一个dump指向头结点,然后用cur从dump开始通过判断cur.next以及cur.next.next对应的元素是否相同,如果相同,那么我们就需要一个子循环来找出当前连续相同的元素,知道节点x不相等时,将cur.next指向x,然后接着遍历,如果不同,那说明链表中cur.next的值只有一个,我们cur = cur.next接着遍历即可。

细节

需要注意 cur.next 以及 cur.next.next 可能为空节点,如果不加以判断,可能会产生运行错误。

代码:

class Solution {
    public ListNode deleteDuplicates(ListNode head) {
        if (head == null) {
            return head;
        }
        
        ListNode dummy = new ListNode(0, head);

        ListNode cur = dummy;
        while (cur.next != null && cur.next.next != null) {
            if (cur.next.val == cur.next.next.val) {
                int x = cur.next.val;
                while (cur.next != null && cur.next.val == x) {
                    cur.next = cur.next.next;
                }
            } else {
                cur = cur.next;
            }
        }

        return dummy.next;
    }
}

方法二:递归

1.1 递归函数定义
递归最基本的是要明白递归函数的定义! 我反复强调过这一点。

递归函数直接使用题目给出的函数 deleteDuplicates(head) ,它的含义是 删除以 head 作为开头的有序链表中,值出现重复的节点。

1.2 递归终止条件
终止条件就是能想到的基本的、不用继续递归处理的case。

如果 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);。

方法三:双端队列

我们通过一个双端队列来遍历链表记录当前的top值,然后判断是否相同,如果相同则剔除原来队列中的值,如果不相同就放入队列,最后遍历队列再构建链表。(此方法需要控制的细节太多,需要反复尝试,不是一种很好的解决办法)

代码:

public ListNode deleteDuplicates(ListNode head) {
        Deque queue = new LinkedList();
        ListNode cur = head;
        ListNode top = new ListNode(-1);
        ListNode newhead = new ListNode(-1);
        ListNode newcur = newhead;
        while(cur!=null){
            if(queue.isEmpty()&&cur.val != top.val){
                ListNode node = new ListNode(cur.val);
                queue.addLast(node);
                top = cur;
                cur = cur.next;
            }else if(queue.isEmpty()&&cur.val == top.val){
                cur = cur.next;
            }
            else if(cur.val == top.val){
                ListNode n = (ListNode) queue.getLast();
                if(cur.val == n.val){
                    queue.removeLast();
                    cur = cur.next;
                }else {
                    cur =cur.next;
                }
            }else {
                ListNode node = new ListNode(cur.val);
                queue.addLast(node);
                top = cur;
                cur = cur.next;
            }
        }
//        for(int i=0;i< queue.size();i++){
//            cur.next = queue.
//        }
        while (!queue.isEmpty()){
            newcur.next = (ListNode) queue.pollFirst();
            newcur = newcur.next;
        }
        newhead.printListnode();
        return newhead.next;
    }

猜你喜欢

转载自blog.csdn.net/XZB119211/article/details/128095817
今日推荐