雙指標的應用 從leetcode第88題說起

2021-10-04 13:40:18 字數 1439 閱讀 5115

雙指標一直是leetcode中的乙個有意思的點,刷了一些題見了很多次雙指標,合理運用雙指標可以達到乙個巧奪天工的作用,廢話不多說,請看題:

出自leetcode第88題:

給你兩個有序整數陣列 nums1 和 nums2,請你將 nums2 合併到 nums1 中,使 num1 成為乙個有序陣列。

題目說明:

初始化 nums1 和 nums2 的元素數量分別為 m 和 n 。

你可以假設 nums1 有足夠的空間(空間大小大於或等於 m + n)來儲存 nums2 中的元素。

示例:

輸入:nums1 = [1,2,3,0,0,0], m = 3

nums2 = [2,5,6], n = 3

輸出: [1,2,2,3,5,6]

解題:這道題乍一看會覺得非常簡單,並且有種似曾相識的感覺,又是陣列,又是排序,這不是找上門來送麼,不過在解題的時候,卻發現這道題並不簡單。

首先我們肯定能想到一種最通俗的辦法,那就是把兩個陣列做個合併,然後整體排序,簡單暴力,但是假如這樣做的話,陣列本身是有序的這個條件就沒用上,那麼這樣我們的時間複雜度就是o((n+m)log(n+m)),這個時間複雜度顯然是非常不理想的,那怎麼樣才能用到這個有序的條件呢,這時我們能很快想到,在歸併排序裡面的兩個有序陣列互相比較來進行合併,只需要開闢乙個新的陣列,然後通過不斷比較現有兩個陣列元素大小來交叉插入到新陣列中即可,這樣時間複雜度就直接降到了o(m+n),這便是一次很不錯的優化。

但是,我們在這個過程中新使用了o(m+n)的空間複雜度,為了降低它,我們可以將nums1這個陣列當作最後的陣列,這樣我們新申請的陣列就只要o(m)的空間複雜度,用於裝nums1這個陣列的元素,這樣又降低了空間複雜度。

可是這樣我們還是不滿足,有沒有什麼辦法又不用申請新的空間,還能保持最低的時間複雜度呢?

答案是雙指標分別從兩個陣列尾部開始遍歷,然後將比較後比較大的那個放到nums1的尾部,這樣迴圈下去,最後nums1便是我們想要的結果,當然有人會說那假如nums2元素比較多把nums1還沒放的元素覆蓋了怎麼辦?請仔細再閱讀一次題幹,nums1有足夠大的空間,所以把nums2全部放進去了以後nums1的空餘空間是剛好夠用的,所以根本不存在剛才那種意外情況,**如下(已通過leetcode):

void

merge

(int

* nums1,

int nums1size,

int m,

int* nums2,

int nums2size,

int n)

else

k--;}

//nums1有剩餘的情況

while

(i >-1

)//nums2有剩餘的情況

while

(j >-1

)}

Leetcode 題解 雙指標

雙指標 有序陣列 字串翻轉 環形鍊錶問題 雙指標主要用於遍歷陣列,兩個指標指向不同的元素,從而協同完成任務。有序陣列的 two sum1 leetcode 167.two sum ii input array is sorted easy input numbers target 9 output ...

leetcode 雙指標專題

題目 4.尋找兩個有序陣列的中位數 解析 通過2個下標來依次比較2個陣列的元素,直到走過的數量達到一半,複雜度 m n 2 答案 double findmediansortedarrays int nums1,int nums1size,int nums2,int nums2size else co...

leetcode雙指標總結

雙指標一般又分為3中應用 判斷鍊錶是否有環 一快一慢 f和 s 相遇的話就是 成環 沒有相遇就是沒成環 判斷鍊錶中環的起點 鍊錶中證明了 f指標一定比慢指標多走n圈環的長度 f s nb f 2 s 可以得到 s nb 這個時候 如果再走鍊錶起點到環起點的a步的話 也就是 環的起點 所以我們用f指標...