Leetcode 1. Two Sum & 15. 3Sum & 16. 3Sum Closest & 18. 4Sum
来源:互联网 发布:乐高ev3编程软件简介 编辑:程序博客网 时间:2024/05/22 17:36
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.
Example:
Given nums = [2, 7, 11, 15], target = 9,Because nums[0] + nums[1] = 2 + 7 = 9,
return [0, 1].
UPDATE (2016/2/13):
The return format had been changed to zero-based indices.
Please read the above updated description carefully.
Method大体思想就一个,HashMap。
版本1,自己写的,因为<key,value> key应该唯一,因此key是index,value是值。
public class Solution { // 182ms public int[] twoSum(int[] nums, int target) { int[] res = new int[2]; HashMap<Integer,Integer> hmap = new HashMap<Integer,Integer>(); if (nums == null || nums.length<3) return res; for (int i = 0; i<nums.length; i++) { if (hmap.containsValue(target-nums[i])) { res[1] = i; for (int key : hmap.keySet()) { if (hmap.get(key)==target-nums[i]) { res[0] = key; return res; } } }else { hmap.put(i,nums[i]); } } return res; }}
必须不服,上网找来版本2:
public class Solution { public int[] twoSum(int[] numbers, int target) { if(numbers.length>=2) { HashMap<Integer,Integer> h = new HashMap<Integer,Integer>(); for(int i=0; i<numbers.length; i++){ if(!h.isEmpty() && h.containsKey(target-numbers[i])) { int[] k = {h.get(target-numbers[i]),i}; return k; } h.put(numbers[i],i); } } int[] k = {-1,-1}; return k; }}
运行时间是7ms。。仔细一看,我说哥们,你这代码key, value反过来了啊,这不符合map定义啊!!!后来一
看题,只有一个解,那意思是就算元素重复了也OK,只要输出一个解就行。
于是把自己之前的代码key, value交换了一下,6ms:
public class Solution { public int[] twoSum(int[] nums, int target) { int[] res = new int[2]; HashMap<Integer,Integer> hmap = new HashMap<Integer,Integer>(); if (nums == null || nums.length<3) return res; for (int i = 0; i<nums.length; i++) { if (hmap.containsKey(target-nums[i])) { res[1] = i; res[0] = hmap.get(target-nums[i]); return res; }else { hmap.put(nums[i],i); } } return res;
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:
- Elements in a triplet (a,b,c) must be in non-descending order. (ie, a ≤ b ≤ c)
- The solution set must not contain duplicate triplets.
A solution set is:
(-1, 0, 1)
(-1, -1, 2)
3sum网上解法大同小异。先取一个点,然后进行2sum,因为要去重,所以移动指针的时候需要判定当前
元素和之前所指的元素是否相同,如果相同则继续移动。
三个指针就有3个地方需要判断去重。
public class Solution { //8ms public List<List<Integer>> threeSum(int[] nums) { List<List<Integer>> res = new ArrayList<List<Integer>>(); int len=nums.length; if(len<3)return res; 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 begin=i+1,end=len-1; while(begin<end){ int sum=nums[i]+nums[begin]+nums[end]; if(sum==0){ List<Integer> list = new ArrayList<Integer>(); list.add(nums[i]);list.add(nums[begin]);list.add(nums[end]); res.add(list); begin++;end--; while(begin<end && nums[begin]==nums[begin-1])begin++; <span style="font-family: Arial, Helvetica, sans-serif;">// 去重</span> while(begin<end && nums[end]==nums[end+1])end--; // 去重 }else if(sum>0)end--; else begin++; } } return res; } }
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).
用一个变量代表目前的最小diff,如果sum比当前diff小,则更新,否则继续循环,最后输出最小diff。
版本一,自己写的:
public class Solution { //12ms public int threeSumClosest(int[] nums, int target) { int diff = Integer.MAX_VALUE; int sum, begin, end, res=-1; Arrays.sort(nums); for (int i=0;i<nums.length;i++) { begin=i+1;end=nums.length-1; while(begin<end) { sum = nums[i]+ nums[begin]+nums[end]; if (sum==target) return target; if(Math.abs(sum-target)<diff) { diff=Math.abs(sum-target); res=sum; } if(sum>target) end--; else begin++; } } return res; }}
版本二:
public class Solution {//10ms public int threeSumClosest(int[] nums, int target) { Arrays.sort(nums); int diff = Integer.MAX_VALUE, closest = 0; for (int k=0; k<nums.length-2; ++k) { for (int i=k+1, j=nums.length-1; i<j; ) { int sum = nums[k] + nums[i] + nums[j]; if (sum == target) { return target; } else if (sum > target) { if (sum-target < diff) { diff = sum-target; closest = sum; } --j; } else { if (target-sum < diff) { diff = target-sum; closest = sum; } ++i; } } } return closest; }}
Given an array S of n integers, are there elements a, b, c, and d in S such that
a + b + c + d = target?
Find all unique quadruplets in the array which gives the sum of target.
Note:
- Elements in a quadruplet (a,b,c,d) must be in non-descending order. (ie, a ≤ b ≤ c ≤ d)
- The solution set must not contain duplicate quadruplets.
A solution set is:
(-1, 0, 0, 1)
(-2, -1, 1, 2)
(-2, 0, 0, 2)
方法一:
延续sum系列思想,取第一个点,fix住,然后取第二个点,fix住,之后进行two pointers以前一后直到
相遇,然后移动前两个点,符合条件就输出。
去重方式同3sum。
public class Solution{ //56mspublic static List<List<Integer>> fourSum(int[] nums, int target) { if(nums==null||nums.length==0) return new ArrayList<List<Integer>>(); Arrays.sort(nums); int len=nums.length; List<List<Integer>> result=new ArrayList<List<Integer>>(); for(int i=0;i<len-3;i++){ if(i>0&&nums[i]==nums[i-1]) continue; for(int j=i+1;j<len-2;j++){ if(j>i+1&&nums[j]==nums[j-1]) continue; int sum=target-nums[i]-nums[j],slow=j+1,fast=len-1; while(slow<fast){ if(nums[slow]+nums[fast]==sum){ List<Integer> tmp=new ArrayList<Integer>(); tmp.add(nums[i]); tmp.add(nums[j]); tmp.add(nums[slow]); tmp.add(nums[fast]); result.add(tmp); while(slow<fast&&nums[slow]==nums[slow+1]) slow++; slow++; while(fast>slow&&nums[fast]==nums[fast-1]) fast--; fast--; } else if(nums[slow]+nums[fast]>sum) fast--; else slow++; } } } return result; }}
方法二:可以看到方法一用了56MS,因为有很多不用判断的情况,下面这个版本很巧妙,固定了首尾
两个元素,因为这两个元素可以帮忙判断是否需要跳过当前情况。如果首元素大于target/4,则因为元
素递增,则再往后的case不需要考虑了;如果尾元素小于targer/4,则因为元素递增,则再往前的
case不用考虑。
public class Solution { //11ms public List<List<Integer>> fourSum(int[] nums, int target) { List<List<Integer>> list = new ArrayList<List<Integer>>(); Arrays.sort(nums); int second = 0, third = 0; for(int i=0, L=nums.length; i<L-3; i++) { if(nums[i]<<2 > target) return list; // return immediately for(int j=L-1; j>i+2; j--) { if(nums[j]<<2 < target) break; // break immediately int rem = target-nums[i]-nums[j]; int lo = i+1, hi=j-1; while(lo<hi) { int sum = nums[lo] + nums[hi]; if(sum>rem) --hi; else if(sum<rem) ++lo; else { list.add(Arrays.asList(nums[i],nums[lo],nums[hi],nums[j])); while(++lo<=hi && nums[lo-1]==nums[lo]) continue; // avoid duplicate results while(--hi>=lo && nums[hi]==nums[hi+1]) continue; // avoid duplicate results } } while(j>=1 && nums[j]==nums[j-1]) --j; // skip inner loop } while(i<L-1 && nums[i]==nums[i+1]) ++i; // skip outer loop } return list; }}
至于网上的其他解法,比如backtracking,还有Ksum的通解,博主才leetcode第一遍,时间压力很大,选择
暂时跳过。目前来说选择自己能理解的方法好些。
- Leetcode 1. Two Sum & 15. 3Sum & 16. 3Sum Closest & 18. 4Sum
- 【leetcode X Sum 系列】Two Sum|3Sum|3Sum Closest|4Sum
- Two Sum & 3Sum & 3Sum Closest & 4Sum
- Two Sum,3Sum,3Sum Closest,4Sum
- LeetCode 16. 3Sum Closest LeetCode 18. 4Sum
- 第五周:[leetcode] Two Sum、3Sum、3Sum Closest、4Sum
- LeetCode 16. 3Sum Closest (Two-Pointer)
- 【C++】【LeetCode】15. 3Sum & 16. 3Sum Closest & 18. 4Sum
- leetcode 15. 3sum && 16. 3Sum Closest && 18. 4Sum
- 【Leetcode】3Sum Closest (Sum)
- leetcode 3sum closest && 4sum
- 【LeetCode】3Sum && 3Sum Closest && 4Sum
- leetcode 3Sum 3Sum Closest 4Sum
- LeetCode OJ - 3Sum、3Sum Closest、4Sum
- LeetCode 3Sum&&3Sum Closest&&4Sum
- LeetCode:3Sum, 3Sum Closest, 4Sum
- 3Sum 3Sum Closest 4Sum
- 3Sum & 3Sum Closest & 4Sum
- Deepin linux下安装netbeans
- Roman to Integer/Integer to Roman
- HDU 5459 Jesus Is Here dp+预处理
- Java实现冒泡排序算法
- oracle 新建表空间、用户
- Leetcode 1. Two Sum & 15. 3Sum & 16. 3Sum Closest & 18. 4Sum
- Block
- 使用RxBinding处理控件异步调用
- iOS集成VTK(三维计算机图形学、图像处理和可视化)
- 安全卫士第八天笔记
- javax.persistence.NonUniqueResultException: result returns more than one elements
- 2085: [Poi2010]Hamsters hash+倍增floyd
- 解析各大电子商务网站订单号的生成方式
- Java异常体系结构