算法_ 删除排序链表中的重复元素 II (#82)

147 阅读2分钟

题目

给个升序的链表,删除里面所有相同数字的的节点,返回删除重复元素后的升序链表。

image.png

就是里面相同的元素全部删掉一个都不留,上篇文章题目还留了一个原始数字节点。

分析一波

定义一个哨兵节点p, 指向头节点head的前一个节点,再定义一个q;
如果p.next和p.next.next的值相等(也就是p后面的第一个和第二个节点相等),
就让q等于p的下下一个节点,然后设置一个循环,
判断q的值和p的下一个节点的值是否相等,
相等的话, 就让q等于q的下一个节点(q往后走一步),
再判断q的值是否等于p的下一个节点。
等于的话就继续上面的循环,
让q一直往后走去跟p的下一个节点的值进行对比,
否则:让q等于p的下一个节点,这样,中间相同的节点直接就被全部删除了,一个不剩。

否则(p.next和p.next.next的值不相等),就让p等于p的下一个节点,也就是p往后走一步。

实践,上代码分析

/**
 * @param {ListNode} head
 * @return {ListNode}
 */
var deleteDuplicates = function(head) {
    if(!head) return head;
    let list=new ListNode(-1,head),q=list,p;
    while(q.next&&q.next.next){
     if(q.next.val===q.next.next.val){
         p=q.next.next;
         do{
           p=p.next;
           //这里要主意判断是否有p
         }while(p&&(q.next.val===p.val)) 
         q.next=p;
     }else{
       q=q.next;
   
     }
    }
   return list.next;
};

判断没有head,直接返回;
定义哨兵节点q,让从-1开始,就是在头节点head的前一位,然后定义节点p;
同样使用循环while去走这个那个链表,这里的是否需要往下走的判断条件是,看是否有q的下一个节点以及q的下下一个节点;
循环里面:
如果q的下一个节点的值与q的下下节点的值相等,那么就把q的下下节点赋值给p;
里面继续用一个循环去对比q下一个节点的值和p的值,直到两者值不相等再退出内部的循环;
在内部循环外面,去把p赋值给q的下一个节点,以上这两步就是把相等的值全部删除掉了;
否则前后值不相等,就让q往前走一步,继续以上操作,看是否有相等的值;
最后然后list的下一个节点,这里要注意:因为list是个哨兵节点,是代表head的上一个节点,所以,直接返回list的话,前面会永远多一个前面定义的哨兵节点-1,所以返回list.next比较准确。