Leetcode解題思想總結篇:雙指針


Leetcode解題思想總結篇:雙指針

1概念

雙指針:快慢指針。
快指針在每一步走的步長要比慢指針一步走的步長要多。快指針通常的步速是慢指針的2倍。

在循環中的指針移動通常為:
faster = faster.next.next; slower = slower.next;

2 應用

2.1. 用來判斷鏈表是否有環以及尋找環入口

  • Linked List Cycle
  • Linked List Cycle II

是否有環:快慢指針思想,注意循環條件:(fast != null) && (fast.next != null)

尋找環的入口:快慢指針相遇的時候,distance(fast指針) = 2 * distance(slow指針),可以推導出,只要把fast重新指向頭結點,兩個指針以一樣的速度走,相遇的時候,便是環的入口。

2.2.數組尋找范圍

  • Summary Ranges

范圍的尋找,用2個指針:startend來記錄范圍。注意循環條件和判斷條件:(end + 1 < len) && (nums[end + 1] == nums[end] + 1)

2.3.鏈表或者數組中移除重復的元素

  • Remove Duplicates from Sorted List I
  • Remove Duplicates from Sorted List II

Sorted List I用兩個指針一前一后指向鏈表。維護兩個指針:

  • tail 一個指向當前不重復的最后一個元素,
  • pCur 一個進行依次掃描,遇到不重復的則更新第一個指針,繼續掃描,否則就把前面指針指向當前元素的下一個(即把當前元素從鏈表中刪除)。

Sorted List II 維護兩個指針:

  • prev前驅指針指向上一個不重復的元素
  • pCur遍歷指針
    思路類似Sorted List I,細節更多。
    尋找不重復的元素 while循環條件pCur.next != null && prev.next.val == pCur.next.val

Array數組中的解題思想一樣:

  • index指向上當前不重復的最后一個元素
  • i遍歷數組

2.4. 用來找中點或中位數

2.5. 倒數第n個

題目中含有:倒數第n個,那么設置快指針步長為n,然后快慢指針同時以同一速度走,用慢指針尋找倒數第n個

2.6. 拆分鏈表

Partition List

給定一個x的值,小於x都放在大於等於x的前面,並且不改變鏈表之間node原始的相對位置。example中 4->3->5都是大於等3的數,這保持了他們原來的相對位置。

使用鏈表最常用的雙指針:

  • 一個指向當前小於x的最后一個元素
  • 一個進行往前掃描。如果元素大於x,那么繼續前進,否則,要把元素移到前面,並更新第一個指針。

Reorder List

思路:
1.利用快慢兩個指針將鏈表一分為二;
2.針對第二個子鏈表求倒序;
3.利用merge思想將兩個子鏈表合並。

3 相關題目

4 注意

  1. 通常需要特別留意鏈表長度的奇偶性
  2. 如果快指針步速為慢指針步速2倍,循環條件為:faster.next!=null && faster.next.next!=null
  3. 當自行設置快指針步長時, 要考慮步長值等於鏈表長度的特殊情況
  4. 查找倒數第n個時,如果要求刪除鏈表元素時,不要忘記記錄應被刪除元素的前一個元素
  5. 對於鏈表的題目,常常都會用到Two Pointers的思想。鏈表注意構建dummy頭結點。在Java中,由於沒有free函數,所以在刪除一個節點的時候,無法用node = null來刪除一個節點,需要用前一個節點來指向刪除節點的下一個prev.next = node.next這樣來刪除node節點。

5 參考


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM