ksum问题
2sum:
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.
解答:
采用hashmap,从头遍历数组,如果hashmap不含有该元素,则将target减去这个元素的值和该元素的下标存入hashmap;如果hashmap含有该元素,则将hashmap中对应的下标和该元素的下标存入数组返回结果。
public class Solution {
public int[] twoSum(int[] nums, int target) {
Map<Integer, Integer> helper = new HashMap<Integer, Integer>();
int[] result = {-1, -1};
for (int i = 0; i < nums.length; i++) {
if (helper.get(nums[i]) != null) {
result[0] = helper.get(nums[i]);
result[1] = i;
return result;
} else {
helper.put(target - nums[i], i);
}
}
return result;
}
}
此题若不是返回下标,还可以采用将数组先进行排序,然后利用左右两个指针寻找相应元素。若左右两指针元素和小于target,则左指针右移,若大于则右指针左移,若相等则返回结果。
public int[] twoSum_pointer(int[] numbers, int target) {
if (numbers == null || numbers.length < 2) {
return null;
}
Arrays.sort(numbers);
int left = 0;
int right = numbers.length - 1;
int[] rst = new int[2]; while ( left < right) {
int sum = numbers[left] + numbers[right];
if( sum == target){
rst[0] = left;
rst[1] = right;
break;
} else if ( sum < target) {
left++;
} else {
right--;
}
}
return rst;
}
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:
- 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.
解答:
运用上题2sum的第二种方法,相当于把数组的每个元素当做target,然后往后寻找2sum为target相反数的两个元素。要注意的是避免重复结果。
public class Solution {
public List<List<Integer>> threeSum(int[] nums) {
List<List<Integer>> result = new LinkedList<List<Integer>>();
if (nums == null || nums.length < 3) {
return result;
}
Arrays.sort(nums);
for (int i = 0; i < nums.length - 2; i++) {
if (i > 0 && nums[i] == nums[i - 1]) {
continue;
} //避免重复元素
int left = i + 1;
int right = nums.length - 1;
while (left < right) {
if (nums[i] + nums[left] + nums[right] == 0) {
List<Integer> temp = new LinkedList<Integer>();
temp.add(nums[i]);
temp.add(nums[left]);
temp.add(nums[right]);
result.add(temp);
left++;
right--;
while(left < right && nums[left] == nums[left - 1]) {
left++;
}
while(left < right && nums[right] == nums[right + 1]) {
right--;
} //避免重复元素
} else if (nums[i] + nums[left] + nums[right] > 0) {
right--;
} else {
left++;
}
}
}
return result;
}
}
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.
解答:同样是2sum的扩展,先将数组排序,然后遍历数组,对每个元素向后寻找两个元素并求和,和等于target直接返回target,大于则左指针右移,小于则右指针左移,同时更新result值。注意,result初始值设为Integer.MAX_VALUE的一半,而不是Integer.MAX_VALUE,否则结果可能溢出而产生错误。比如:
正确代码如下:
public class Solution {
public int threeSumClosest(int[] nums, int target) {
if (nums == null || nums.length < 3) {
return -1;
}
Arrays.sort(nums);
int result = Integer.MAX_VALUE / 2;
for (int i = 0; i < nums.length - 2; i++) {
int left = i + 1;
int right = nums.length - 1;
while (left < right) {
int temp = nums[i] + nums[left] + nums[right];
if (temp == target) {
return temp;
} else if (temp < target) {
left++;
} else {
right--;
}
if (Math.abs(temp - target) < Math.abs(result - target)) {
result = temp;
}
}
}
return result;
}
}
4sum:
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循环嵌套,固定两个数组元素,再用左右两指针扫另外两个元素,根据sum与target大小关系确定指针的移动。
public class Solution {
public List<List<Integer>> fourSum(int[] nums, int target) {
List<List<Integer>> result = new LinkedList<List<Integer>>();
if (nums == null || nums.length < 4) {
return result;
}
Arrays.sort(nums);
for (int i = 0; i < nums.length - 3; i++) {
if (i > 0 && nums[i] == nums[i - 1]) {
continue;
}
for (int j = i + 1; j < nums.length - 2; j++) {
if (j > i + 1 && nums[j] == nums[j - 1]) {
continue;
}
int left = j + 1;
int right = nums.length - 1;
while (left < right) {
int temp = nums[i] + nums[j] + nums[left] + nums[right];
if (temp == target) {
List<Integer> ele = new LinkedList<Integer>();
ele.add(nums[i]);
ele.add(nums[j]);
ele.add(nums[left]);
ele.add(nums[right]);
result.add(ele);
left++;
right--;
while (left < right && nums[left] == nums[left - 1]) {
left++;
}
while (left < right && nums[right] == nums[right + 1]) {
right--;
}
} else if (temp < target) {
left++;
} else {
right--;
}
}
}
}
return result;
}
}
值得注意的是,本题中的数据结构采用的是LinkedList而不是ArrayList,原因是插入操作比较多,用LinkedList效率更高。前者运行时间击败63%,后者54%。
ksum问题的更多相关文章
- 2016 一中培训 day 5 ksum
又是一天的爆零!!!!! 原本第一题 很容易做 竟然优化过度 丢了答案 1693: ksum Time Limit 1000 ms Memory Limit 524288 KBytes Judge S ...
- 2Sum,3Sum,4Sum,kSum,3Sum Closest系列
1).2sum 1.题意:找出数组中和为target的所有数对 2.思路:排序数组,然后用两个指针i.j,一前一后,计算两个指针所指内容的和与target的关系,如果小于target,i右移,如果大于 ...
- kSum问题总结
1.2Sum 题目: 方法一:两次迭代 public class TwoSum { public static int[] twoSum(int[] nums, int target) { int[] ...
- 2sum,3sum,4sum,ksum
1. 2sum 题目:给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标.你可以假设每种输入只会对应一个答案.但是,你不能重复利 ...
- 【数组】kSum问题
一.2Sum 思路1: 首先对数组排序.不过由于最后返回两个数字的索引,所以需要事先对数据进行备份.然后采用2个指针l和r,分别从左端和右端向中间运动:当l和r位置的两个数字之和小于目标数字targe ...
- k-sum 问题
问题描述 给定一个数组及数字 k ,从数组中找出所有相加结果为 k 的组合. 示例: 给定数组 [1,1,1] 令 k=2,输出: [[1,1]] 给定数组 [10, 1, 2, 7, 6, 1, 5 ...
- [算法]K-SUM problem
一.Two Sum Given an array of integers, find two numbers such that they add up to a specific target nu ...
- 【JZOJ4815】【NOIP2016提高A组五校联考4】ksum
题目描述 输入 输出 样例输入 3 4 1 3 4 样例输出 8 7 4 4 数据范围 样例解释 解法 二分做法 考虑到可以二分第k大的值mid,如果比mid大的区间和数小于或等于mid,那么mid就 ...
- k-sum问题
给定一个数组,里面的是任意整数,可能有重复,再给定一个目标T,从数组中找出所有和为T的K个数,要求结果中没有重复. Note: Elements in a quadruplet (a,b,c,d) m ...
随机推荐
- win8 wifi开关显示关闭,且设置里面wifi开关显示灰色的解决办法
只要从华硕官网下载驱动,电源管理驱动,安装下面显示的几个软件即可,然后重启电脑,即可看见wifi热点,另外设置里面的wifi开关也将显示正常(刚开始安装了个驱动人生根本没用,最后在华硕官网下载了个电源 ...
- java 计算源码的行数
import java.io.BufferedReader;import java.io.File;import java.io.FileReader;import java.io.IOExcepti ...
- 使用jquery的load方法设计动态加载,并解决被加载页面JavaScript失效问题
一.问题分析 对于后台系统,相比大家都有所印象,知道其中的布局结构,如图: 在这种布局中我们需要将header,sidebar,footer分开,而且对于中间部分的content内容需要动态变化,即根 ...
- 了解 : angular controller link ng-init 顺序
controller 会先跑,接着是view 里的ng-init,最后是link (指令里的). 所有在指令里如果用link去拿$attr,会有拿不到ng-init想setup的值
- Github创建分支
一.clone Repository clone Github 上的Repository,如下: git clone git@github.com:FBing/design-patterns.git ...
- 每天一个Linux命令(18)--locate命令
locate让使用者可以很快速的搜寻档案系统内是否有指定的档案.器方法是先建立一个包括系统内所有档案名称及路径的数据库,之后当寻找时就需查询这个数据库,而不必实际深入档案系统之中了.在一般的 ditr ...
- Javascript原型链和原型继承
哇好久都没有写随笔啦,整个人都慵懒啦. 为了不让大家忘记我,把以前写过的一些慢慢发出来. 在JS 中, 有两条链子,作用域链 和 原型链. 作用域链相对容易理解,两点 - 函数限定变量作用域,就是说, ...
- Robot Framework中经常用的第三方库的安装方法
pip升级:python -m pip install --upgrade pip 一.安装robotframework-selenium2library,相当于python中的selenium ...
- Memcached 内存管理详解
Memcached是一个高效的分布式内存cache,了解memcached的内存管理机制,便于我们理解memcached,让我们可以针对我们数据特点进行调优,让其更好的为我所用. 首先需要我们先了解两 ...
- Struts2框架(8)---Struts2的输入校验
Struts2的输入校验 在我们项目实际开发中在数据校验时,分为两种,一种是前端校验,一种是服务器校验: 客户端校验:主要是通过jsp写js脚本,它的优点很明显,就是输入错误的话提醒比较及时,能够减轻 ...