Leetcode 15.3Sum 三数之和
3Sum 其实就是 twoSum的衍生题,相比较2Sum,寻找在一个数组中可以组成特定数字的两个数,3Sum要求我们寻找在一个数组中和为0的三个数。同样我们也可以通过哈希表的方式来实现,但是通过双指针的方式其实更加优雅一些。
首先我们将会对数组进行排序,这里就消耗了nlogn的复杂度,所以这道题解法复杂度也就是O(nlogn)。
一般我们在处理多个变量最后构成某个条件的题的时候,我们就是循环其中的一个变量然后根据当前这个变量的位置来继续确定后续的变量。首先我们循环固定三个数字中的第一个数,既然我们需要三数之和为0,那么肯定需要有负数和正数,我们就让第一个数为负数,所以我们就从0开始向后遍历。不断的确定了第一个数之后,这个问题就被化简成为了两数之和的问题,我们可以使用双指针的模式,也可以使用哈希表,让我们看看java的双指针解法实现吧。
class solution{
public List<List<Integer>> threeSum(int[] nums) {
List<List<Integer>> ret = new ArrayList<>();
if (nums == null || nums.length < 3)
return ret;
int len = nums.length;
Arrays.sort(nums);
for (int i = 0; i < len; i++) {
if (nums[i] > 0)
break;
//当Nums[i] 已经成为正数的时候后面肯定不可能有构成0的组合了
if (i > 0 && nums[i] == nums[i - 1])
continue;
//跳过重复的相同数字
int begin = i + 1;
int end = len - 1;
while (begin < end) {
int sum = nums[i] + nums[begin] + nums[end];
if (sum == 0) {
//找到了
List<Integer> list = new ArrayList<>();
list.add(nums[i]);
list.add(nums[begin]);
list.add(nums[end]);
ret.add(list);
begin++;
end--;
while (begin < end && nums[begin] == nums[begin - 1])
begin++;
//跳过重复的相同数组
while (begin < end && nums[end] == nums[end + 1])
end--;
} else if (sum > 0)
end--;
//当前组合大于0就向左移动右指针
else
begin++;
//当前组合小于0就向右移动左指针
}
}
return ret;
}
}