26.刪除有序陣列中的重複項(簡單)
83.刪除排序鍊錶中的重複元素(簡單)
27.移除元素(簡單)
283.移動零(簡單)
我們知道對於陣列來說,在尾部插入、刪除元素是比較高效的,時間複雜度是 o(1),但是如果在中間或者開頭插入、刪除元素,就會涉及資料的搬移,時間複雜度為 o(n),效率較低。
所以上篇文章 常數時間刪除/查詢陣列中的任意元素 就講了一種技巧,把待刪除元素交換到最後乙個,然後再刪除,就可以避免資料搬移。
那麼這篇文章我們換乙個場景,來講一講如何在原地修改陣列,避免資料的搬移。
先講講如何對乙個有序陣列去重,先看下題目:
函式簽名如下:
intremoveduplicates(intnums);
簡單解釋一下什麼是原地修改:
如果不是原地修改的話,我們直接 new 乙個int
陣列,把去重之後的元素放進這個新陣列中,然後返回這個新陣列即可。
但是原地刪除,不允許我們 new 新陣列,只能在原陣列上操作,然後返回乙個長度,這樣就可以通過返回的長度和原始陣列得到我們去重後的元素有哪些了。
這種需求在陣列相關的演算法題中時非常常見的,通用解法就是我們前文 雙指標技巧 中的快慢指標技巧。
我們讓慢指標slow
走在後面,快指標fast
走在前面探路,找到乙個不重複的元素就告訴slow
並讓slow
前進一步。這樣當fast
指標遍歷完整個陣列nums
後,nums[0..slow]
就是不重複元素。
intremoveduplicates(intnums)
int slow = 0, fast = 0;
while (fast < nums.length)
fast++;
}// 陣列長度為索引 + 1
return slow + 1;
}
看下演算法執行的過程:
再簡單擴充套件一下,如果給你乙個有序鍊錶,如何去重呢?這是力扣第 83 題,其實和陣列去重是一模一樣的,唯一的區別是把陣列賦值操作變成操作指標而已:
listnode deleteduplicates(listnode head)
// fast++
fast = fast.next;
}// 斷開與後面重複元素的連線
這是力扣第 27 題,看下題目:
函式簽名如下:
intremoveelement(intnums,intval);
題目要求我們把nums
中所有值為val
的元素原地刪除,依然需要使用 雙指標技巧 中的快慢指標:
如果fast
遇到需要去除的元素,則直接跳過,否則就告訴slow
指標,並讓slow
前進一步。
這和前面說到的陣列去重問題解法思路是完全一樣的,就不畫 gif 了,直接看**:
intremoveelement(intnums,intval)
fast++;
}return slow;
}
注意這裡和有序陣列去重的解法有乙個重要不同,我們這裡是先給nums[slow]
賦值然後再給slow++
,這樣可以保證nums[0..slow-1]
是不包含值為val
的元素的,最後的結果陣列長度就是slow
。
這是力扣第 283 題,我來描述下題目:
給你輸入乙個陣列nums
,請你原地修改,將陣列中的所有值為 0 的元素移到陣列末尾,函式簽名如下:
voidmovezeroes(intnums);
比如說給你輸入nums = [0,1,4,0,2]
,你的演算法沒有返回值,但是會把nums
陣列原地修改成[1,4,2,0,0]
。
結合之前說到的幾個題目,你是否有已經有了答案呢?
題目讓我們將所有 0 移到最後,其實就相當於移除nums
中的所有 0,然後再把後面的元素都賦值為 0 即可。
voidmovezeroes(intnums)
}// 見上文**實現
intremoveelement(intnums,intval);
至此,四道「原地修改」的演算法問題就講完了,其實核心還是快慢指標技巧,你學會了嗎? LeetCode 陣列 刪除有序陣列重複元素
給定乙個排序陣列,你需要在原地刪除重複出現的元素,使得每個元素只出現一次,返回移除後陣列的新長度。不要使用額外的陣列空間,你必須在原地修改輸入陣列並在使用 o 1 額外空間的條件下完成。給定陣列 nums 1,1,2 函式應該返回新的長度 2,並且原陣列 nums 的前兩個元素被修改為 1,2。採用...
LeetCode 陣列 刪除有序陣列重複元素
給定乙個排序陣列,你需要在原地刪除重複出現的元素,使得每個元素只出現一次,返回移除後陣列的新長度。不要使用額外的陣列空間,你必須在原地修改輸入陣列並在使用 o 1 額外空間的條件下完成。給定陣列 nums 1,1,2 函式應該返回新的長度 2,並且原陣列 nums 的前兩個元素被修改為 1,2。採用...
LeetCode 陣列 刪除有序陣列重複元素
給定乙個排序陣列,你需要在原地刪除重複出現的元素,使得每個元素只出現一次,返回移除後陣列的新長度。不要使用額外的陣列空間,你必須在原地修改輸入陣列並在使用 o 1 額外空間的條件下完成。給定陣列 nums 1,1,2 函式應該返回新的長度 2,並且原陣列 nums 的前兩個元素被修改為 1,2。複製...