題目要求我們得到所有三數之和為0的不重複三元組。如果僅是三數之和為0,可以簡單的使用三重迴圈列舉出所有三元組,並找出和為0的即可。但是施加不重複這個條件之後,就不能簡單的列舉所有三元組,(-1,0,1)和(0,-1,1)這樣的情況是不允許出現在答案裡的。
首先要解決的一點是如何保證不重複。重複的本質是陣列元素無序排列,由於陣列無序排列再加上陣列中重複的元素,很容易導致重複三元組的出現。首先考慮去掉陣列重複元素是否可行,答案是否定的,因為重複元素可能佔據三元組中的兩個值,比如:(-1,-1,2)。
那麼需要對陣列進行排序。排序後使得我們列舉的三元組 (a, b, c) 滿足 a ≤ b ≤ c,保證了只有 (a, b, c) 這個順序會被列舉到,而 (b, a, c)、(c, b, a) 等等這些不會,這樣就減少了重複。
同時,對於每一重迴圈而言,相鄰兩次列舉的元素不能相同,否則也會造成重複。舉個例子,如果排完序的陣列為[0,1,2,2,2,3],
就有可能列舉出三個(0,1,2)這樣也會出現重複。因此我們需要將第三重迴圈「跳到」下乙個不相同的元素,即陣列中的最後乙個元素 3,列舉三元組 (0, 1, 3)。
首先考慮三重迴圈解法的優化版本(雜湊表),三數之和和兩數之和類似。當三重迴圈時,前兩重迴圈固定不動,第三重迴圈就是在尋找前兩個數的相反數,這個時候用空間換時間方式將第三重迴圈去掉,結果時間複雜度將為o(n²)。
public static arraylist> threesum(int nums) }}
} }return aii;
}
雙指標法:當我們列舉陣列中的兩個元素時,如果第乙個元素是遞增的,第二個元素是遞減的,那麼就可以使用雙指標的方法。
在三數之和問題中,如果固定前兩個ab兩元素,倘若第三個元素c存在a+b+c=0(如果有,有且也只有乙個),則將b向後移動乙個位置b'繼續尋找,此時如果第三個元素存在c'滿足a+b'+c'=0,c'一定比c小,在c的左邊。即,b'>b,c'在往前一步,如果固定第乙個元素,使用雙指標開始分別指向第乙個元素後一位和陣列尾部,右指標不斷左移,左指標不斷右移。具體來說,當三數之和大於0時,右指標左移。當三數之和小於0時,左指標右移。當三數之和等於0時,同時移動左右指標。指標移動的每一次還要檢查移動前後的元素是否相等,若相等,還需要移動,直到不相等為止。
class solution }}
} return aii;
}}
總結:排序,陣列排序可以減少重複。(必須)
去重,每一重迴圈相鄰兩次列舉的元素不能相同。(必須)
空間換時間的方式去掉第三重迴圈。(雜湊表)
優化,當我們需要列舉陣列中的兩個元素時,乙個元素是遞增的另乙個元素是遞減的,考慮使用雙指標的方法。(雙指標)
leetCode n數之和 雜湊表 雙指標
示例 給定 nums 2 7,11 15 target 9因為 nums 0 nums 1 2 7 9所以返回 0,1 思路 設定乙個雜湊表map,記錄每個值對應的索引i,通過判斷target nums i 的值是否存在來確定另乙個值的位置。兩數之和 vartwosum function nums,...
15 三數之和(哨兵 雙指標)
給定乙個包含 n 個整數的陣列 nums,判斷 nums 中是否存在三個元素 a,b,c 使得 a b c 0 找出所有滿足條件且不重複的三元組。注意 答案中不可以包含重複的三元組。例如,給定陣列 nums 1,0,1,2,1,4 滿足要求的三元組集合為 1,0,1 1,1,2 class solu...
Leetcode15 三數之和(雙指標)
給定乙個包含 n 個整數的陣列 nums,判斷 nums 中是否存在三個元素 a,b,c 使得 a b c 0 找出所有滿足條件且不重複的三元組。注意 答案中不可以包含重複的三元組。例如,給定陣列 nums 1,0,1,2,1,4 滿足要求的三元組集合為 1,0,1 1,1,2 給定乙個包含 n 個...