Leetcode 4 雙指標篇

2022-09-16 12:12:11 字數 2221 閱讀 8461

經典解法就是用兩個指標,乙個跑得快,乙個跑得慢。如果不含有環,跑得快的那個指標最終會遇到 null,說明鍊錶不含環;如果含有環,快指標最終會超慢指標一圈,和慢指標相遇,說明鍊錶含有環。

結論:當快慢指標相遇時,讓其中任乙個指標指向頭節點,然後讓它倆以相同速度前進,再次相遇時所在的節點位置就是環開始的位置。

listnode detectcycle(listnode head) 

// 上面的**類似 hascycle 函式

if (fast == null || fast.next == null)

slow = head;

while (slow != fast)

return slow;

}

設相遇點距環的起點的距離為 m,那麼環的起點距頭結點 head 的距離為 k - m,也就是說如果從 head 前進 k - m 步就能到達環起點。

巧的是,如果從相遇點繼續前進 k - m 步,也恰好到達環起點。你甭管 fast 在環裡到底轉了幾圈,反正走 k 步可以到相遇點,那走 k - m 步一定就是走到環起點了。所以,只要我們把快慢指標中的任乙個重新指向 head,然後兩個指標同速前進,k - m 步後就會相遇,相遇之處就是環的起點了。

讓快指標一次前進兩步,慢指標一次前進一步,當快指標到達鍊錶盡頭時,慢指標就處於鍊錶的中間位置。

listnode middlenode(listnode head) 

// slow 就在中間位置

return slow;

}

當鍊表的長度是奇數時,slow 恰巧停在中點位置;如果長度是偶數,slow 最終的位置是中間偏右:

尋找鍊錶中點的乙個重要作用是對鍊錶進行歸併排序。

回想陣列的歸併排序:求中點索引遞迴地把陣列二分,最後合併兩個有序陣列。對於鍊錶,合併兩個有序鍊錶是很簡單的,難點就在於二分。

讓快指標先走 n 步,然後快慢指標開始同速前進。這樣當快指標走到鍊錶末尾 null 時,慢指標所在的位置就是倒數第 n 個鍊錶節點(n 不會超過鍊錶長度)

// 讓慢指標和快指標同步向前

while (fast != null && fast.next != null)

// slow.next 就是倒數第 n 個節點,刪除它

slow.next = slow.next.next;

return head;

}左右指標在陣列中實際是指兩個索引值,一般初始化為 left = 0, right = nums.length - 1 。

int binarysearch(int nums, int target) 

return -1;

}

只要陣列有序,就應該想到雙指標技巧。這道題的解法有點類似二分查詢,通過調節 left 和 right 可以調整 sum 的大小:

int twosum(int nums, int target) ;

} else if (sum < target) else if (sum > target)

}return new int;

}

void reversestring(char arr) 

}

這也許是雙指標技巧的最高境界了,如果掌握了此演算法,可以解決一大類子字串匹配的問題,不過「滑動視窗」稍微比上述的這些演算法複雜些。

雙指標技巧總結 :: labuladong的演算法小抄

LeetCode 4 動態規劃

揹包問題c 動態規劃 class solution for int i 1 i n i for int j 0 j w weight i j for int i w i 0 i return0 1.word break leetcode 139 class solution return res s...

leetcode 4 尋找中位數

1.題目鏈結。這個題目使用分治來寫似乎不是很好想。大概的寫法就是 我們需要使用分治一步一步的找到中位數在哪個位置。我們首先在兩個陣列各自取出一總長度一半的資料,判斷取出來的資料的最大值,確定中位數到底在哪個區間。555,語言表達能力不強,看 吧,還是很好理解的。class solution 遞迴的出...

leetcode4三數之和

給定乙個包括 n 個整數的陣列 nums 和 乙個目標值 target。找出 nums 中的三個整數,使得它們的和與 target 最接近。返回這三個數的和。假定每組輸入只存在唯一答案。例如,給定陣列 nums 1,2,1,4 和 target 1.與 target 最接近的三個數的和為 2.1 2...