Leetcode 1. Two Sum & 15. 3Sum & 16. 3Sum Closest & 18. 4Sum
2016-03-07 13:49
405 查看
1. Two Sum
Total Accepted: 196496 TotalSubmissions: 907244 Difficulty: Medium
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;
15. 3Sum
Total Accepted: 105161 TotalSubmissions: 570987 Difficulty: Medium
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.
For example, given array S = {-1 0 1 2 -1 -4},
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++; while(begin<end && nums[end]==nums[end+1])end--; }else if(sum>0)end--; else begin++; } } return res; } }
16. 3Sum Closest
Total Accepted: 69789 TotalSubmissions: 244144 Difficulty: Medium
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;int begin;int end;int 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; } }
18. 4Sum
Total Accepted: 65299 TotalSubmissions: 279841 Difficulty: Medium
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.
For example, given array S = {1 0 -1 0 -2 2}, and target = 0.
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{ //56ms public 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第一遍,时间压力很大,选择
暂时跳过。目前来说选择自己能理解的方法好些。
相关文章推荐
- 界面传值
- 另类vs2015+xamarin 的android界面乱码 解决
- JS中多种方式创建对象
- Mysql常用语句
- 如何在MyEclipse(2015)中添加ADT
- 修改浏览器地址
- Deepin linux下安装netbeans
- 关于软件工程
- nutcracker 工作流程
- 可视化分析工具Qlik进阶
- 翻翻git之---偏向iOS风格的Switch ToggleSwitch
- Spring实现AOP的4种方式
- Leet Code OJ 235. Lowest Common Ancestor of a Binary Search Tree [Difficulty: Easy]
- 翻翻git之---偏向iOS风格的Switch ToggleSwitch
- vs2015 Xamarin.Android安装
- Timus 1796. Amusement Park 聪明题
- sql isnull函数使用
- 在Eclipse里使用SVN必装Subclipse插件
- Quartz.NET开发指南教程
- jquery 替换原来的html内容