015三數之和
阿新 • • 發佈:2020-09-01
寫在前面,參考力扣官網的畫解演算法。。真的太清晰明瞭了
一、java程式碼
/* * @lc app=leetcode.cn id=15 lang=java * * [15] 三數之和 */ // @lc code=start class Solution { public List<List<Integer>> threeSum(int[] nums) { //ans接收答案 List<List<Integer>> ans=new ArrayList(); //給定nums陣列長度 int len=nums.length; //當給定陣列為空或者長度小於3則直接返回ans if(nums==null||len<3) return ans; //首先對陣列進行排序 Arrays.sort(nums);//排序 //固定i for(int i=0;i<len;i++){ //後面的也會大於0 ,所以在此處終結 if(nums[i]>0) break;//如果當前數字大於0,則三數之和必定大於0,結束迴圈 //返回for迴圈,i++ if(i>0&&nums[i]==nums[i-1]) continue;//去重 //使用左右指標指向nums[i]後面的兩端 int L=i+1; int R=len-1; //當L<R時才能繼續下面的判斷,否則i++ while(L<R){ //核心公式 int sum=nums[i]+nums[L]+nums[R]; //當sum==0是,左加右減收縮 if(sum==0){ //將當前結果存到ans中 ans.add(Arrays.asList(nums[i],nums[L],nums[R])); //當`sum==0`時,`nums[L]==nums[L+1]`,則會導致結果重複,應該跳過,`L++` while(L<R && nums[L]==nums[L+1]) L++;//去重 //當`sum==0`時,`nums[R]==nums[R-1]`,則會導致結果重複,應該跳過,`R--` while(L<R && nums[R]==nums[R-1]) R--;//去重 //左加右減 L++; R--; } else if(sum<0) L++; else if(sum>0) R--; } } return ans; } } // @lc code=end
二、解題思路
1、首先對陣列進行排序
,排序後固定一個數nums[i]
2、再使用左右指標,指向nums[i]
後面部分的兩端
,數字分別為nums[L]
和nums[R]
3、計算三個數的和sum
,判斷是否滿足為0,滿足則新增進結果集ans
(1)如果nums[i]
大於0
,則三數之後必然無法大於0,結束迴圈
(2)如果nums[i]==nums[i-1]
,則說明該數字重複,會導致結果重複,所以跳過
(3)當sum==0
時,nums[L]==nums[L+1]
,則會導致結果重複,應該跳過,L++
(4)當sum==0
時,nums[R]==nums[R-1]
,則會導致結果重複,應該跳過,R--
三、圖解
(1/12)
(2/12)
(3/12)
(4/12)
(5/12)
(6/12)
(7/12)
(8/12)
(9/12)
(10/12)
(11/12)
(12/12)