LCR 007. 三数之和
解题思路
定义:定义一个名为Solution的类,并且在这个类中维护一个成员变量res,用于存储所有满足条件的三元组。 主方法:threeSum方法是解决问题的入口点。它调用threeSumTarget方法来计算所有和为0的三元组。 转化为两数之和:threeSumTarget方法首先对输入数组nums进行排序,然后遍历每个元素nums[i],并把问题转化为找出数组中的两个数,使得两数之和为target - nums[i]。这是因为我们希望nums[i] + nums[j] + nums[k] == target,即如果确定了nums[i],我们只需要在剩下的数组中找到两个数之和为target - nums[i]。 寻找两数之和:使用twoSumTarget方法来找出所有和为特定target值的元素对。因为数组已经排序,所以可以用双指针技术,一个从剩余数组的起始位置开始,一个从数组结束的位置开始遍历。 去重:在threeSumTarget和twoSumTarget方法中,该代码使用while循环来跳过重复的元素,以避免在结果集res中出现重复的三元组。 收集结果:每当在twoSumTarget找到符合条件的元组时,就会创建一个新的数组a,将成对的元素(也就是找到的两个数)添加到a中,然后将nums[i](当前遍历的元素)添加到a,最后将完整的三元组添加到结果列表res中。 返回结果:最后返回填充好的结果列表res,它包含了所有不重复的符合条件(三个数之和等于目标值target)的三元组
class Solution { List < List < Integer > > res = new ArrayList < > ( ) ; public List < List < Integer > > threeSum ( int [ ] nums) { return threeSumTarget ( nums, 0 ) ; } List < List < Integer > > threeSumTarget ( int [ ] nums, int target) { Arrays . sort ( nums) ; for ( int i = 0 ; i < nums. length; i++ ) { List < List < Integer > > temp = twoSumTarget ( nums, i + 1 , target - nums[ i] ) ; for ( List < Integer > t: temp) { t. add ( nums[ i] ) ; res. add ( t) ; } while ( i < nums. length - 1 && nums[ i] == nums[ i + 1 ] ) { i++ ; } } return res; } List < List < Integer > > twoSumTarget ( int [ ] nums, int start, int target) { List < List < Integer > > res = new ArrayList < > ( ) ; int left = start; int right = nums. length - 1 ; while ( left < right) { int sum = nums[ left] + nums[ right] ; int l = nums[ left] ; int r = nums[ right] ; if ( sum == target) { List < Integer > a = new ArrayList < > ( ) ; a. add ( nums[ left] ) ; a. add ( nums[ right] ) ; res. add ( a) ; while ( left < right && nums[ left] == l) { left++ ; } while ( left < right && nums[ right] == r) { right-- ; } } else if ( sum < target) { while ( left < right && nums[ left] == l) { left++ ; } } else if ( sum > target) { while ( left < right && nums[ right] == r) { right-- ; } } } return res; } }