删除链表元素:哨兵节点

删除链表元素:哨兵节点

83. 删除排序链表中的重复元素Ⅰ

题目描述

给定一个排序链表,删除全部重复的元素,使得每一个元素只出现一次指针

这是一道标星为简单的题,难度不是很大。须要注意的几点是:code

  • 链表已经排好序,这样子的话,寻找重复元素,只要看下一个是否与前一个相等就行了。
  • 还有一点是:删除的元素不会是第一个节点。

代码实现

public static ListNode deleteDuplicates(ListNode head){
        //已排序的链表
        ListNode currNode = head;
        //若是后一值和前一值相等,前一值的next指向后一值的next
        while(currNode!=null&&currNode.next!=null){
            if(currNode.val==currNode.next.val){
                currNode.next = currNode.next.next;
            }else{
                //不相等的状况,就让前指针向后移
                currNode = currNode.next;
            }
        }
        return head;
    }

复杂度分析

  • 时间复杂度:O(n) ,n是节点个数
  • 空间复杂度:O(1)

203.移除链表元素

题目描述

删除链表中等于给定值val的全部节点。排序

个人初步想法是:element

  • 定义两个先后指针,后一个指针表明当前状态curr,前一个指针表明上一个prev.
  • 若是当前的值为val,就让prev.next=curr.next,向后遍历:curr=curr.next。
  • 这样表明的val值的节点就相应删除。

固然,我并无考虑要删除的多个元素都出如今头节点的状况,若是考虑这点,哨兵节点的好处就体现出来了。leetcode

哨兵节点的利用

当要删除的一个或多个节点位于链表的头部时,能够利用哨兵节点,使链表标准化,即便链表永不为空,永不无头,简化插入和删除的操做。rem

  • 能够定义一个哨兵节点,做为一个伪头,假设它是sentinel:ListNode sentinel = new ListNode(0);
  • 让它指向“真头”head:sentinel.next = head;
  • 定义两个指针,一个为前向指针prev,一个为当前指针curr。
    • curr的值若是就是指定值,让prev的下一节点指向当前节点的下一系节点。
    • curr的值若是不是指定值,就让表明上一节点的指针prev指向当前指针。
    • curr始终是要向后遍历的。
  • 最后返回sentinel.next。(prev和sentinel指向同一地址,prev已经将链表操做完成)

代码实现

public ListNode sentinelRemove(ListNode head,int val){
       //建立哨兵节点,指向head
       ListNode sentinel = new ListNode(0);
       sentinel.next = head;
       //定义两个指针,前向指向哨兵节点,当前指向head
       ListNode prev = sentinel;
       ListNode curr = head;
       while(curr!=null){
           if(curr.val == val){
               //当前节点值就是指定值,则让上一个节点的next指向下一个节点
               prev.next = curr.next;
           }else{
               //上一个节点向后移
               prev = curr;
           }
           //遍历下一节点
           curr = curr.next;
       }
       //返回哨兵节点的下一节点
       return sentinel.next;
   }

复杂度分析

  • 时间复杂度:O(n)
  • 空间复杂度:O(1)

82.删除排序链表中的重复元素Ⅱ

题目描述

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

一样是删除链表中的重复元素,第一道题是保留一个便可,这个题的意思就是一个不留。须要注意的是:it

  • 链表依旧已排序。
  • 删除的节点多是头节点。

这道题,咱们仍是能够利用哨兵节点:io

代码实现

public ListNode deleteDuplicates(ListNode head) {
        //建立哨兵节点,指向head
        ListNode sentinel = new ListNode(0);
        sentinel.next = head;
        ListNode prev = sentinel,curr = head;
        //当前位置且下一位置都不为空
        while(curr!=null&&curr.next!=null){
            //若是下一位和这位重复
            if(curr.val == curr.next.val){
                //向后寻找,知道curr为不重复的元素
                int val = curr.val;
                while(curr!=null&&curr.val==val){
                    curr = curr.next;
                }
                //删去重复元素
                prev.next = curr;
            }else{
                //不重复的状况
                //两个指针分别向后移动
                prev = curr;
                curr = curr.next;
            }
        }
        return sentinel.next;
    }

复杂度分析

  • 时间复杂度 :O(n)
  • 空间复杂度 :O(1)

参考连接:
https://leetcode-cn.com/problems/remove-linked-list-elements/solution/yi-chu-lian-biao-yuan-su-by-leetcode/

https://leetcode-cn.com/problems/remove-duplicates-from-sorted-list/solution/shan-chu-pai-xu-lian-biao-zhong-de-zhong-fu-yuan-s/

相关文章
相关标签/搜索