1. 程式人生 > 其它 >劍指offer一刷:雙指標

劍指offer一刷:雙指標

劍指 Offer 18. 刪除連結串列的節點

難度:簡單

沒什麼好說的,注意刪除的節點為頭節點的這一特殊情況即可。

class Solution {
    public ListNode deleteNode(ListNode head, int val) {
        if(head.val == val) return head.next;
        ListNode pre = head, cur = head.next;
        while(cur != null && cur.val != val) {
            pre = cur;
            cur = cur.next;
        }
        if(cur != null) pre.next = cur.next;
        return head;
    }
}

作者:Krahets
連結:https://leetcode.cn/leetbook/read/illustration-of-algorithm/509cy5/
來源:力扣(LeetCode)
著作權歸作者所有。商業轉載請聯絡作者獲得授權,非商業轉載請註明出處。

劍指 Offer 22. 連結串列中倒數第 k 個節點

難度:簡單

方法一:統計連結串列長度

  1. 先遍歷統計連結串列長度,記為 n
  2. 設定一個指標走 (n-k) 步,即可找到連結串列倒數第 k 個節點;

方法二:雙指標

該方法不需要像上個方法那樣統計連結串列長度。

一前一後兩個指標,前指標先走k步,然後雙指標同時移動直到前指標走過尾結點返回後指標

class Solution {
    public ListNode getKthFromEnd(ListNode head, int k) {
        ListNode former = head, latter = head;
        for(int i = 0; i < k; i++) {
            if(former == null) return null;
            former = former.next;
        }
        while(former != null) {
            former = former.next;
            latter = latter.next;
        }
        return latter;
    }
}

作者:Krahets
連結:https://leetcode.cn/leetbook/read/illustration-of-algorithm/588dhc/
來源:力扣(LeetCode)
著作權歸作者所有。商業轉載請聯絡作者獲得授權,非商業轉載請註明出處。

時間複雜度:O(N),空間複雜度:O(1)。

劍指 Offer 25. 合併兩個排序的連結串列

難度:簡單

引入偽頭節點:由於初始狀態合併連結串列中無節點,因此迴圈第一輪時無法將節點新增到合併連結串列中。解決方案:初始化一個輔助節點 dum 作為合併連結串列的偽頭節點,將各節點新增至 dum 之後。

演算法流程

  1. 初始化:偽頭節點 dum ,節點 cur 指向 dum。
  2. 迴圈合併:當 l1 或 l2 為空時跳出;
    1. 當 l1.val < l2.val 時:cur 的後繼節點指定為 l1,並 l1 向前走一步;
    2. 當 l1.val ≥ l2.val 時:cur 的後繼節點指定為 l2
      ,並 l2 向前走一步;
    3. 節點 cur 向前走一步,即 cur = cur.next。
  3. 合併剩餘尾部:跳出時有兩種情況,即 l1 為空或 l2 為空。
    1. 若 l1 ≠ null:將 l1 新增至節點 cur 之後;
    2. 否則:將 l2 新增至節點 cur 之後。
  4. 返回值:合併連結串列在偽頭節點 dum 之後,因此返回 dum.next 即可。
class Solution {
    public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
        ListNode dum = new ListNode(0), cur = dum;
        while(l1 != null && l2 != null) {
            if(l1.val < l2.val) {
                cur.next = l1;
                l1 = l1.next;
            }
            else {
                cur.next = l2;
                l2 = l2.next;
            }
            cur = cur.next;
        }
        cur.next = l1 != null ? l1 : l2;
        return dum.next;
    }
}

作者:Krahets
連結:https://leetcode.cn/leetbook/read/illustration-of-algorithm/5v6htd/
來源:力扣(LeetCode)
著作權歸作者所有。商業轉載請聯絡作者獲得授權,非商業轉載請註明出處。

時間複雜度:O(M+N),空間複雜度:O(1)。

引入偽頭節點的做法很妙,程式碼很精煉,學習學習。