赞
踩
leetcode 15.三数之和 3Sum
第一步:
判断问题类型,观察 信息之间关系,除了暴力求解,是否有稍微更好一点的解法,如果没有用最简单的方法进行暴力求解法
测试中发现有重复问题,解决重复,发现排序才可以更好的解决重复。
以此写出第一个代码
- class Solution {
- public List<List<Integer>> threeSum(int[] nums) {
- //考虑 特殊值,边界值,再优化
- //不排序的话 去重很难
- Arrays.sort(nums);
- List<List<Integer>> result = new ArrayList();
- for(int i = 0; i < nums.length-2; i++){
- //排序以后的去重,i==0是因为 第一次的值不算重复的
- if(nums[i] < 0){
- if(i==0 || i>0 && nums[i]!=nums[i-1]){
- //剩下两数之和
- int sum = 0 - nums[i];
- for(int j=i+1; j < nums.length-1; j++){
- for(int k = j+1; k < nums.length; k++){
- if(nums[j]+nums[k] == sum){
- List<Integer> list = new ArrayList();
- list.add(nums[i]);
- list.add(nums[j]);
- list.add(nums[k]);
- result.add(list);
- }
- }
- }
- }
- }
-
- }
- return result;
- }
- }
发现排序后,算法可以更加优化
因为三数之和 与 排序好的数字是有一定关系的。
-7 -3 -2 0 2 3 4 5 6 7
a b c
1.三数全正 全负 pass 如果从最左边开始试起,头部大于0就没有必要算下去了。
2.以第一个数为基准,从数组两边开始寻找值,如果a <0 c<0 停止,a > 0 , c>0 停止
b+c + a > 0 c--
b+c + a < 0 b++
循环得到 等于0 的值
特殊情况:
-7 = 2 5 ,3 4
出现重复值,如何跳过
最终解法
- class Solution {
- public List<List<Integer>> threeSum(int[] nums) {
- //考虑 特殊值,边界值,再优化
- //不排序的话 去重很难
- Arrays.sort(nums);
- List<List<Integer>> result = new ArrayList();
- for(int i = 0; i < nums.length-2; i++){ //第一层循环控制第一个基准值
- //根据有序数组特性 排除一些无效数组
- if(nums[i] > 0 || (nums[i] < 0 && nums[nums.length-1]<0)) return result;
- //排序以后的去重,i==0是因为 第一次的值不算重复的
- if(i==0 || i>0 && nums[i]!=nums[i-1]){
- //剩下两数之和
- int sum = 0 - nums[i];
- int left = i+1,right = nums.length -1;
- while(left < right){
- if(nums[left]+nums[right] == sum){
- result.add(Arrays.asList(nums[i],nums[left],nums[right]));
- //数值相等 需要考虑下一次移动,1.是否有重复数 2.没有重复数怎么移动
- //从 -4 = 2 ,2 开始 ,左右差值就至少是2了,-7 = 2 5 ,3 4为最小差值数
- //所以相等后,至少两边都要挪动一位数
- while(left < right && nums[left]==nums[left+1] ) left++;
- while(left < right && nums[right]==nums[right-1] ) right--;
- left++;
- right--;
- }else if(nums[left]+nums[right] < sum){
- //1.考虑左边移动还是右边移动 left + right + num < 0 left++
- //2.考虑重复值,知道是左起点移动后,那就是检查左边的重复值
- while(left < right && nums[left]==nums[left+1])left++;
- left++;
- }else{ //可以省略 while(l < r && nums[left]==nums[left+1])left++;
- while(left < right && nums[right]==nums[right-1])right--;
- right--;
- }
- }
- }
-
- }
- return result;
- }
- }
国外大牛解法
- class Solution {
- public List<List<Integer>> threeSum(int[] nums) {
- Arrays.sort(nums);
- List<List<Integer>> result = new ArrayList();
- for(int i = 0; i < nums.length-2; i++){
- if(i == 0 || (i > 0 && nums[i] != nums[i-1]) ){
- int left = i+1,right = nums.length -1,sum = 0 - nums[i];
- while(left < right){
- if(nums[left]+nums[right] == sum){
- result.add(Arrays.asList(nums[i],nums[left],nums[right]));
- while(left < right && nums[left]==nums[left+1] ) left++;
- while(left < right && nums[right]==nums[right-1] ) right--;
- left++;right--;
- }else if(nums[left]+nums[right] < sum)
- left++;
- else
- right--;
- }
- }
- }
- return result;
- }
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。