LeetCode(1)三數之和為0
阿新 • • 發佈:2018-11-27
給定一個包含 n 個整數的陣列 nums,判斷 nums 中是否存在三個元素 a,b,c ,使得 a + b + c = 0 ?找出所有滿足條件且不重複的三元組。
注意:答案中不可以包含重複的三元組。
例如, 給定陣列 nums = [-1, 0, 1, 2, -1, -4],
滿足要求的三元組集合為: [ [-1, 0, 1], [-1, -1, 2] ]
一,暴力法,直接用三個指標遍歷陣列
public static List<List<Integer>> threeSum(int[] nums) { Arrays.sort(nums); //陣列排序 List<List<Integer>> outList = new ArrayList<List<Integer>>(); //定義一個ArrayList線性表 for (int i = 0; i < nums.length; i++) { if ((i > 0 && nums[i] == nums[i - 1])) //去重,做判斷。如果符合條件就返回迴圈,對應的i直接跳過 continue; for (int j = i + 1; j < nums.length; j++) { if ((j > i + 1 && nums[j] == nums[j - 1])) //去重 continue; for (int k = j + 1; k < nums.length; k++) { if ((k > j + 1 && nums[k] == nums[k - 1])) //去重 continue; if ((nums[i] + nums[j] + nums[k] == 0)) //判斷和為零 { outList.add(Arrays.asList(nums[i],nums[j],nums[k])); //新增到ArrayList中 break; } } } } return outList; //返回找到的符合條件的陣列 }
最終測試程式碼
這時我們發現,超時了。仔細分析我們知道迴圈太多了,而且都是三個for巢狀,這樣直接導致了時間複雜度飆升。
那麼我們想辦法降低下時間複雜度。
二,頭尾指標法
方法一是三個指標依次陣列後面移,那麼我們試下頭尾加指標,縮小範圍來減小時間複雜度。
public static List<List<Integer>> threeSum(int[] nums) { List<List<Integer>> res = new ArrayList<>(); Arrays.sort(nums); for (int i = 0; i + 2 < nums.length; i++) { if (i > 0 && nums[i] == nums[i - 1]) { //去重 continue; } int j = i + 1, k = nums.length - 1; int target = -nums[i]; while (j < k) { if (nums[j] + nums[k] == target) { res.add(Arrays.asList(nums[i], nums[j], nums[k])); //新增到新的陣列 j++; k--; while (j < k && nums[j] == nums[j - 1]) j++; // 各迴圈起始點不需要判斷重複 while (j < k && nums[k] == nums[k + 1]) k--; // 各迴圈起始點不需要判斷重複 } else if (nums[j] + nums[k] > target) { k--; //k左移 } else { j++; //j右移 } } } return res; }
有問題歡迎留言哦
參考:
https://leetcode.com/problems/3sum/discuss/?orderBy=recent_activity