Leecode两数-四数之和题解
最近两天做了两数之和,四数之和,并且之前也做过三数之和,感觉这几道题解法都差不多,并且用同样的方法能求解n数之和。
给定一个整数数组 nums
和一个目标值 target
,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标。
你可以假设每种输入只会对应一个答案。但是,数组中同一个元素不能使用两遍。
示例:
1 2 3 4
| 给定 nums = [2, 7, 11, 15], target = 9
因为 nums[0] + nums[1] = 2 + 7 = 9 所以返回 [0, 1]
|
题解(哈希表)
分析:
利用哈希map,key存放数字,value存放索引,遍历数组,依次取一个数,然后计算出另外一个数,如果哈希map中存在,直接取出索引,返回结果,如果不存在,向哈希map中添加当前元素和对应的下标。
具体步骤如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| class Solution { public int[] twoSum(int[] nums, int target) { HashMap<Integer,Integer> map = new HashMap(); for(int i = 0; i < nums.length;i++){ int num2 = target - nums[i]; if(map.containsKey(num2)){ return new int[] { map.get(num2), i }; }else{ map.put(nums[i],i); } } return null; } }
|
给你一个包含 n 个整数的数组 nums
,判断 nums
中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?请你找出所有满足条件且不重复的三元组。
注意:答案中不可以包含重复的三元组。
示例:
1 2 3 4 5 6 7
| 给定数组 nums = [-1, 0, 1, 2, -1, -4],
满足要求的三元组集合为: [ [-1, 0, 1], [-1, -1, 2] ]
|
题解(排序,双指针)
分析:
此题要求出三个数的和为0的结果集,则只需对原数组排序,然后从最小的数开始选,接着设置左右指针,如果当前三个数和为0,将这三个数加入结果集,继续寻找,如果当前三个数和大于0,右指针左移,小于0,左指针右移。
具体步骤如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
| class Solution { public List<List<Integer>> threeSum(int[] nums) { int len = nums.length; List<List<Integer>> ans = new ArrayList(); if(nums == null || len <3) return ans; Arrays.sort(nums); for(int i = 0 ; i < len;i++){ if(nums[i] > 0) break; if(i > 0 && nums[i] == nums[i-1]) continue; int left = i + 1; int right = len - 1; while(left < right){ int sum = nums[i] + nums[left] + nums[right]; if( sum == 0){ ans.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--; } if(sum > 0) right--; if(sum < 0) left++; } } return ans; } }
|
给定一个包含 n 个整数的数组 nums
和一个目标值 target
,判断 nums
中是否存在四个元素 a,b,c 和 d ,使得 a + b + c + d 的值与 target
相等?找出所有满足条件且不重复的四元组。
注意:
答案中不可以包含重复的四元组。
示例:
1 2 3 4 5 6 7 8
| 给定数组 nums = [1, 0, -1, 0, -2, 2],和 target = 0。
满足要求的四元组集合为: [ [-1, 0, 0, 1], [-2, -1, 1, 2], [-2, 0, 0, 2] ]
|
题解(排序,双指针)
分析:
此题要求出四个数的和为target的结果集,则只需对原数组排序,然后将四数之和降为三数之和,接着设置左右指针,如果当前四个数和为target,将这四个数加入结果集,继续寻找,如果当前四个数和大于target,右指针左移,小于0,左指针右移,具体步骤见代码注释。
具体步骤如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64
| class Solution { public List<List<Integer>> fourSum(int[] nums, int target) { List<List<Integer>> res = new ArrayList(); if(nums == null || nums.length < 4){ return res; } Arrays.sort(nums); int l = nums.length; for(int i = 0; i < l - 3; i++){ if( i > 0 && nums[i] == nums[i-1]){ continue; } if(nums[i] + nums[i + 1] + nums[i + 2] + nums[i + 3] > target){ break; } if(nums[i] + nums[l - 3] + nums[l - 2] + nums[l - 1] < target){ continue; } for(int j = i + 1; j < l - 2; j++){ if(j > i + 1 && nums[j] == nums[j - 1]){ continue; } if(nums[i] + nums[j] + nums[j + 1] + nums[j + 2] > target){ break; } if(nums[i] + nums[j] + nums[l - 1] + nums[l - 2] < target){ continue; } int left = j + 1; int right = l - 1; while(left < right){ int sum = nums[i] + nums[j] + nums[left] + nums[right]; if(sum == target){ res.add(Arrays.asList(nums[i],nums[j],nums[left],nums[right])); while(left < right && nums[left] == nums[left + 1]){ left++; } left++; while(left < right && nums[right] == nums[right - 1]){ right--; } right--; }else if(sum > target){ right--; }else{ left++; } } } } return res; } }
|
由三数之和和四数之和可以得出n数之和的解法,思想是一样的,都是枚举,去重,再将最后两个数的和转换为双指针,降低时间复杂度