刪除鏈表元素:哨兵節點

刪除鏈表元素:哨兵節點

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/

相關文章
相關標籤/搜索