leetcode解题笔记:Two sum系列解题思路
2017-03-27 15:06
351 查看
Two Sum
3Sum
3Sum Closest
You may assume that each input would have exactly one solution, and you may not use the same element twice.
Example:
这种解法是O(n)的时间复杂度,但要额外增加O(n)的哈希表存储空间。
其实这是
时间复杂度为O(N)
Note: The solution set must not contain duplicate triplets.
这次是寻找3个数的和为0的组合。可以接着2Sum解法三的思路来想。首先先对数组排序;然后从头开始每次取一个数作为sum,则此题变成了在后面的数组中寻找两个数其和为-sum,就和上面的过程一样。
这里还要注意一个重复的问题,当我们对数组排序后,重复的数是排列在一起的,此时若已经取过一个解后就不要再取重复的解了。
这种解法的时间复杂度为O(N*N)
其实和上面的过程一样,只不过是相等比较转换成了差值的比较。
这种解法的时间复杂度为O(N*N)
3Sum
3Sum Closest
Two Sum
Given an array of integers, return indices of the two numbers such that they add up to a specific target.You may assume that each input would have exactly one solution, and you may not use the same element twice.
Example:
Given nums = [2, 7, 11, 15], target = 9, Because nums[0] + nums[1] = 2 + 7 = 9, return [0, 1].
解法一
一下能想到的思路就是内外两个循环找和为target的两个数字,这样的复杂度是O(n*n)。解法二
想到能否用哈希表,每遍历到一个元素num,看target-num是否在hash表中,如果在就得出答案,如果不在就将当前num放入哈希表中。public int[] twoSum(int[] nums, int target) { HashMap<Integer,Integer> map= new HashMap<Integer,Integer>(); int[] result = new int[2]; for(int i=0;i<nums.length;i++){ if(map.containsKey(target-nums[i])){ result[0]=i; result[1] = map.get(target-nums[i]); break; }else{ map.put(nums[i],i); } } return result; }
这种解法是O(n)的时间复杂度,但要额外增加O(n)的哈希表存储空间。
解法三
可以换个角度来考虑问题,如果给定的数组是已排序的数组,那么就可以设定lo和hi两个指针,如果这两个数字的和比target要大,那么就lo++,否则hi–。这样排序数组需要O(NlogN),找和的过程需要O(N),但是空间是in-place的。其实这是
167. Two Sum II - Input array is sorted抛出的问题。这样我们就不用对数组排序了。
public int[] twoSum(int[] numbers, int target) { int i = 0; int j = numbers.length-1; int[] result = new int[2]; while(j>i){ if(numbers[i]+numbers[j] == target){ result[0] = i+1; result[1] = j+1; break; }else if(numbers[i]+numbers[j] < target){ i++; }else{ j--; } } return result; }
时间复杂度为O(N)
3Sum
Given an array S of n integers, are there elements a, b, c in S such that a + b + c = 0? Find all unique triplets in the array which gives the sum of zero.Note: The solution set must not contain duplicate triplets.
For example, given array S = [-1, 0, 1, 2, -1, -4], A solution set is: [ [-1, 0, 1], [-1, -1, 2] ]
这次是寻找3个数的和为0的组合。可以接着2Sum解法三的思路来想。首先先对数组排序;然后从头开始每次取一个数作为sum,则此题变成了在后面的数组中寻找两个数其和为-sum,就和上面的过程一样。
这里还要注意一个重复的问题,当我们对数组排序后,重复的数是排列在一起的,此时若已经取过一个解后就不要再取重复的解了。
public List<List<Integer>> threeSum(int[] nums) { int len = nums.length; List<List<Integer>> result = new ArrayList<List<Integer>>(); Arrays.sort(nums); for(int i=0;i<len;i++){ //防止重复解 if(i==0 || nums[i]!=nums[i-1]){ int sum = 0-nums[i]; int lo = i+1; int hi = len-1; while(lo<hi){ if(nums[lo]+nums[hi] == sum){ result.add(Arrays.asList(nums[i], nums[lo], nums[hi])); //防止重复解 while(lo<hi && nums[lo] == nums[lo+1])lo++; while(lo<hi && nums[hi] == nums[hi-1])hi--; lo++; hi--; }else if(nums[lo]+nums[hi]>sum){ hi--; }else{ lo++; } } } } return result; }
这种解法的时间复杂度为O(N*N)
3Sum Closest
Given an array S of n integers, find three integers in S such that the sum is closest to a given number, target. Return the sum of the three integers. You may assume that each input would have exactly one solution.For example, given array S = {-1 2 1 -4}, and target = 1. The sum that is closest to the target is 2. (-1 + 2 + 1 = 2).
其实和上面的过程一样,只不过是相等比较转换成了差值的比较。
public int threeSumClosest(int[] nums, int target) { int len = nums.length; if(len<3) return -1; Arrays.sort(nums); int result = nums[0]+nums[1]+nums[2]; for(int i=0;i<len-2;i++){ int lo = i+1; int hi = len-1; while(lo<hi){ int sum = nums[i]+nums[lo]+nums[hi]; if(sum == target){ return sum; }else{ if(Math.abs(sum-target) < Math.abs(target-result)){ result = sum; } if(sum>target){ hi--; }else{ lo++; } } } } return result; }
这种解法的时间复杂度为O(N*N)
总结
可以发现,two sum的解法三是适用于其他变种的,都是在数组已排序的情况下根据当前和与target的比较情况移动指针,其中也要特别注意避免重复解的问题。相关文章推荐
- LeetCode解题思路之Two Sum
- leetcode解题系列:Two Sum
- Leetcode解题笔记 1.Two Sum [Easy]
- LeetCode 2 Add Two Sum 解题报告
- leetcode 113. Path Sum II (路径和) 解题思路和方法
- LeetCode 1.Two Sum 解题报告
- leetcode解题报告(22):Two Sum II - Input array is sorted
- LeetCode个人笔记-Two Sum(1)
- leetCode 4. Median of Two Sorted Arrays 解题思路和方法
- [LeetCode]TwoSum解题报告
- leetcode系列:twosum问题
- 【LeetCode】1. Two Sum 解题报告
- [leetcode] 1. Two Sum 解题报告
- [Leetcode] 1. Two Sum 解题报告
- LeetCode 笔记系列一 Median of Two Sorted Arrays
- leetCode 112.Path Sum (路径和) 解题思路和方法
- LeetCode 1. Two Sum 解题报告
- [LeetCode] 160. Intersection of Two Linked Lists 解题思路
- [LeetCode] 307. Range Sum Query - Mutable 解题思路
- LeetCode- 1. Two Sum - 思路详解-C++