#15 3Sum
正確解法:
在排序之後,用for loop確定最小的數,然後讓剩下兩個指標在最小數的基礎上,分列兩邊,向中間靠攏。
關於重複的考慮:對於最小的指標,只需要保證最小的指標不一樣即可。對於另外兩個指標,只有在成功塞進結果列的情況下才需要考慮,這時候,只要把重複去掉就好了。
時間複雜度O(n2)。
我的問題:
-
O(n3)次的複雜度:既然我這麼用了,其實排序並沒有帶給我積極的意義。排序本身的作用是利用這一串數字的排列,來減小時間複雜度。
-
對於重複的數字,實際有兩個bound來決定要不要繼續找數字。
-
有新的數存在
-
在a的基礎假設上,以a為動力,來移動指標
→ 用我的方法,存在一個問題,就是當這一串數字的末尾全是重複數字的時候,我無法
預知在後面是否還有新的數字存在。所以,其實從兩邊向中間的方法就可以解決這個問
題,我只要check左邊的指標永遠小於右指標就可以了。
修正後的程式碼:(只作為參考,記錄下來)
class Solution {
public List<List<Integer>> threeSum(int[] nums) {
List<List<Integer>> result = new ArrayList<>();
if(nums.length < 3){
return result;
}
Arrays.sort(nums);
if(nums[0] > 0 || nums[nums.length-1] < 0){
return result;
}
for(int i = 0; i < nums.length - 2; i++){
if(i == 0 || nums[i - 1] != nums[i]){
int j = i + 1;
int k = nums.length - 1;
while(j < k){
if(nums[i] == - (nums[j] + nums[k])){
List<Integer> current = new ArrayList<>();
current.add(nums[i]);
current.add(nums[j]);
current.add(nums[k]);
result.add(current);
// check repeated values
while(j < k && nums[j] == nums[j + 1]){
j++;
}
while(j < k && nums[k] == nums[k - 1]){
k--;
}
j++;
k--;
}else if(nums[i] < - (nums[j] + nums[k])){
// nums[j] + nums[k] can be larger
j++;
}else{
k--;
}
}
}
}
return result;
}
}