前端算法小白攻略9-leetcode(删除排序链表中的重复元素1,2)

231 阅读2分钟

题目描述1

删除排序链表中的重复元素: 存在一个按升序排列的链表,给你这个链表的头节点 head ,请你删除所有重复的元素,使每个元素 只出现一次 。

返回同样按升序排列的结果链表。

输入: head = [1,1,2]
输出: [1,2]

解题思路

  1. 要删除重复元素,肯定需要作比较,那我们就需要两个指针pre=head,cur=head.next
  2. 我们这里不借助虚头,让头节点不被删除,如果遇到重复的删除后面的即可
  3. 如果遇到重复的,就让后面的cur指针继续向后走,直至遇到和pre.val不相等的节点
  4. 如果pre和cur不重复,那么直接让pre指向的节点连接cur指向的节点即可,即pre.next=cur

开始解题

var deleteDuplicates = function(head) {
    if(!head) return null;
    let pre = head, cur = head.next;
    while(cur) {
        if(pre.val === cur.val) {
            cur = cur.next;
            if(!cur) { // 如果最后几个都是重复元素,pre直接指向为null的cur即可
                pre.next = cur;
            }
        }else {
            pre.next = cur;
            pre = cur; // 在比较过前两个不重复的元素之后,pre和cur分别向后移动1位,即可比较下一组的两个节点
            cur = cur.next;
        }
    }
    return head;
};

题目描述2

删除排序链表中的重复元素2: 存在一个按升序排列的链表,给你这个链表的头节点 head ,请你删除链表中所有存在数字重复情况的节点,只保留原始链表中 没有重复出现 的数字。

返回同样按升序排列的结果链表。

输入: head = [1,1,2]
输出: [2]

扩展思路

  1. 相比删除单个重复元素来说,本道题目是删除所有重复元素
  2. 因为头节点可能重复会被删除,所以借助虚头
  3. 同样是借助两个指针,不过这里用法不一样,虚头指针pre和比较指针cur
  4. 每次比较cur和cur.next是否重复,那么如果重复这两个都会被删除,那么保持pre在cur的前一位,如果比较到不同的节点,pre指向cur即可,cur=cur.next,那么pre就变成了下组比较的前个节点了
  5. 同题1,如果最后如果干个重复节点,那么当cur为null时,pre.next = null即可

开始解题

var deleteDuplicates = function(head) {
    if(!head) return null;
    let ret = new ListNode(-1,head),pre=ret, cur = head;
    while(cur && cur.next) {
        if(cur.val !== cur.next.val) {
            pre = cur; // 比较到不同的节点,pre指向cur即可
            cur = cur.next; // 此时pre就变成了下组比较的前个节点了
        }else {
            while(cur && cur.next && cur.val === cur.next.val) {
                cur = cur.next;
            } // 找到不重复节点cur.next
            pre.next = cur.next; // pre连接到不重复节点,这里pre指针无需移动,因为不重复节点是下组节点的比较起点
            cur = cur.next;
            if(!cur) {
                pre.next = cur;
            }
        }
    }
    return ret.next;
};