一、Two Sum

Given an array of integers, find two numbers such that they add up to a specific target number.

The function twoSum should return indices of the two numbers such that they add up to the target, where index1 must be less than index2. Please note that your returned answers (both index1 and index2) are not zero-based.

For example:

Input: numbers={2, 7, 11, 15}, target=9
Output: index1=1, index2=2

Naive Approach

This problem is pretty straightforward. We can simply examine every possible pair of numbers in this integer array.

Time complexity in worst case: O(n^2).

  1: public static int[] twoSum(int[] numbers, int target) {
  2:   int[] ret = new int[2];
  3:   for (int i = 0; i < numbers.length; i++) {
  4:     for (int j = i + 1; j < numbers.length; j++) {
  5:       if (numbers[i] + numbers[j] == target) {
  6:         ret[0] = i + 1;
  7:         ret[1] = j + 1;
  8:       }
  9:     }
 10:   }
 11:   return ret;
 12: }
 

Better Solution

Use HashMap to store the target value.

  1: public class Solution {
  2:     public int[] twoSum(int[] numbers, int target) {
  3: 	HashMap<Integer, Integer> map = new HashMap<Integer, Integer>();
  4: 	int[] result = new int[2];
  5: 	for (int i = 0; i < numbers.length; i++) {
  6: 		if (map.containsKey(numbers[i])) {
  7: 			int index = map.get(numbers[i]);
  8: 			result[0] = index+1 ;
  9: 			result[1] = i+1;
 10: 			break;
 11: 		} else {
 12: 			map.put(target - numbers[i], i);
 13: 		}
 14: 	}
 15: 	return result;
 16:     }
 17: }

Time complexity depends on the put and get operations of HashMap which is normally O(1).

Time complexity of this solution is O(n).


二、Two Sum  II– Input array is sorted

This problem is similar to Two Sum.But the input array is sorted.
To solve this problem, we can use two points to scan the array from both sides. See
Java solution below:

  1: public int[] twoSum(int[] numbers, int target) {
  2: 	if (numbers == null || numbers.length == 0)
  3: 		return null;
  4:
  5: 	int i = 0;
  6: 	int j = numbers.length - 1;
  7:
  8: 	while (i < j) {
  9: 		int x = numbers[i] + numbers[j];
 10: 		if (x < target) {
 11: 			++i;
 12: 		} else if (x > target) {
 13: 			j--;
 14: 		} else {
 15: 			return new int[] { i + 1, j + 1 };
 16: 		}
 17: 	}
 18:
 19: 	return null;
 20: }

三、Two Sum III - Data structure design

Design and implement a TwoSum class. It should support the following operations: add and find.

add - Add the number to an internal data structure.
find - Find if there exists any pair of numbers which sum is equal to the value.

For example,

add(1);
add(3);
add(5);
find(4) -> true
find(7) –> false
 

Java Solution

Since the desired class need add and get operations, HashMap is a good option for this purpose.

  1: public class TwoSum {
  2: 	private HashMap<Integer, Integer> elements = new HashMap<Integer, Integer>();
  3:
  4: 	public void add(int number) {
  5: 		if (elements.containsKey(number)) {
  6: 			elements.put(number, elements.get(number) + 1);
  7: 		} else {
  8: 			elements.put(number, 1);
  9: 		}
 10: 	}
 11:
 12: 	public boolean find(int value) {
 13: 		for (Integer i : elements.keySet()) {
 14: 			int target = value - i;
 15: 			if (elements.containsKey(target)) {
 16: 				if (i == target && elements.get(target) < 2) {
 17: 					continue;
 18: 				}
 19: 				return true;
 20: 			}
 21: 		}
 22: 		return false;
 23: 	}
 24: }
 

四、3Sum

Problem:

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)

1. Naive Solution

Naive solution is 3 loops, and this gives time complexity O(n^3). Apparently this is not an acceptable solution, but a discussion can start from here.

  1: public class Solution {
  2:     public ArrayList<ArrayList<Integer>> threeSum(int[] num) {
  3:         //sort array
  4:         Arrays.sort(num);
  5:
  6:         ArrayList<ArrayList<Integer>> result = new ArrayList<ArrayList<Integer>>();
  7:         ArrayList<Integer> each = new ArrayList<Integer>();
  8:         for(int i=0; i<num.length; i++){
  9:             if(num[i] > 0) break;
 10:
 11:             for(int j=i+1; j<num.length; j++){
 12:                 if(num[i] + num[j] > 0 && num[j] > 0) break;
 13:
 14:                 for(int k=j+1; k<num.length; k++){
 15:                   if(num[i] + num[j] + num[k] == 0) {
 16:
 17:                       each.add(num[i]);
 18:                       each.add(num[j]);
 19:                       each.add(num[k]);
 20:                       result.add(each);
 21:                       each.clear();
 22:                   }
 23:                 }
 24:             }
 25:         }
 26:
 27:         return result;
 28:     }
 29: }

* The solution also does not handle duplicates. Therefore, it is not only time inefficient, but also incorrect.

Result:

Submission Result: Output Limit Exceeded
 

2. Better Solution

A better solution is using two pointers instead of one. This makes time complexity of O(n^2).

To avoid duplicate, we can take advantage of sorted arrays, i.e., move pointers by >1 to use same element only once.

  1: public ArrayList<ArrayList<Integer>> threeSum(int[] num) {
  2: 	ArrayList<ArrayList<Integer>> result = new ArrayList<ArrayList<Integer>>();
  3:
  4: 	if (num.length < 3)
  5: 		return result;
  6:
  7: 	// sort array
  8: 	Arrays.sort(num);
  9:
 10: 	for (int i = 0; i < num.length - 2; i++) {
 11: 		 //avoid duplicate solutions
 12: 		if (i == 0 || num[i] > num[i - 1]) {
 13:
 14: 			int negate = -num[i];
 15:
 16: 			int start = i + 1;
 17: 			int end = num.length - 1;
 18:
 19: 			while (start < end) {
 20: 				//case 1
 21: 				if (num[start] + num[end] == negate) {
 22: 					ArrayList<Integer> temp = new ArrayList<Integer>();
 23: 					temp.add(num[i]);
 24: 					temp.add(num[start]);
 25: 					temp.add(num[end]);
 26:
 27: 					result.add(temp);
 28: 					start++;
 29: 					end--;
 30: 					//avoid duplicate solutions
 31: 					while (start < end && num[end] == num[end + 1])
 32: 						end--;
 33:
 34: 					while (start < end && num[start] == num[start - 1])
 35: 						start++;
 36: 				//case 2
 37: 				} else if (num[start] + num[end] < negate) {
 38: 					start++;
 39: 				//case 3
 40: 				} else {
 41: 					end--;
 42: 				}
 43: 			}
 44:
 45: 		}
 46: 	}
 47:
 48: 	return result;
 49: }
 

五、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 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)

Thoughts

A typical k-sum problem. Time is N to the power of (k-1).

Java Solution

  1: public ArrayList<ArrayList<Integer>> fourSum(int[] num, int target) {
  2: 	Arrays.sort(num);
  3:
  4: 	HashSet<ArrayList<Integer>> hashSet = new HashSet<ArrayList<Integer>>();
  5: 	ArrayList<ArrayList<Integer>> result = new ArrayList<ArrayList<Integer>>();
  6:
  7: 	for (int i = 0; i < num.length; i++) {
  8: 		for (int j = i + 1; j < num.length; j++) {
  9: 			int k = j + 1;
 10: 			int l = num.length - 1;
 11:
 12: 			while (k < l) {
 13: 				int sum = num[i] + num[j] + num[k] + num[l];
 14:
 15: 				if (sum > target) {
 16: 					l--;
 17: 				} else if (sum < target) {
 18: 					k++;
 19: 				} else if (sum == target) {
 20: 					ArrayList<Integer> temp = new ArrayList<Integer>();
 21: 					temp.add(num[i]);
 22: 					temp.add(num[j]);
 23: 					temp.add(num[k]);
 24: 					temp.add(num[l]);
 25:
 26: 					if (!hashSet.contains(temp)) {
 27: 						hashSet.add(temp);
 28: 						result.add(temp);
 29: 					}
 30:
 31: 					k++;
 32: 					l--;
 33: 				}
 34: 			}
 35: 		}
 36: 	}
 37:
 38: 	return result;
 39: }

Here is the hashCode method of ArrayList. It makes sure that if all elements of two lists are the same, then the hash code of the two lists will be the same. Since each element in the ArrayList is Integer, same integer has same hash code.

  1: int hashCode = 1;
  2: Iterator<E> i = list.iterator();
  3: while (i.hasNext()) {
  4:       E obj = i.next();
  5:       hashCode = 31*hashCode + (obj==null ? 0 : obj.hashCode());
  6: }

六、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).

Analysis

This problem is similar to 2 Sum. This kind of problem can be solved by using a similar approach, i.e., two pointers from both left and right.

Java Solution

  1: public int threeSumClosest(int[] nums, int target) {
  2:     int min = Integer.MAX_VALUE;
  3: 	int result = 0;
  4: 	Arrays.sort(nums);
  5: 	for (int i = 0; i < nums.length; i++) {
  6: 		int j = i + 1;
  7: 		int k = nums.length - 1;
  8: 		while (j < k) {
  9: 			int sum = nums[i] + nums[j] + nums[k];
 10: 			int diff = Math.abs(sum - target);
 11: 			if(diff == 0) return sum;
 12: 			if (diff < min) {
 13: 				min = diff;
 14: 				result = sum;
 15: 			}
 16: 			if (sum <= target) {
 17: 				j++;
 18: 			} else {
 19: 				k--;
 20: 			}
 21: 		}
 22: 	}
 23:
 24: 	return result;
 25: }

Time Complexity is O(n^2).

[算法]K-SUM problem的更多相关文章

  1. summary of k Sum problem and solutions in leetcode

    I found summary of k Sum problem and solutions in leetcode on the Internet. http://www.sigmainfy.com ...

  2. 求和问题总结(leetcode 2Sum, 3Sum, 4Sum, K Sum)

    转自  http://tech-wonderland.net/blog/summary-of-ksum-problems.html 前言: 做过leetcode的人都知道, 里面有2sum, 3sum ...

  3. k sum 问题系列

    转自:http://tech-wonderland.net/blog/summary-of-ksum-problems.html (中文旧版)前言: 做过leetcode的人都知道, 里面有2sum, ...

  4. LeetCode解题报告--2Sum, 3Sum, 4Sum, K Sum求和问题总结

    前言: 这几天在做LeetCode 里面有2sum, 3sum(closest), 4sum等问题, 这类问题是典型的递归思路解题.该这类问题的关键在于,在进行求和求解前,要先排序Arrays.sor ...

  5. lintcode: k Sum 解题报告

    K SUM My Submissions http://www.lintcode.com/en/problem/k-sum/ 题目来自九章算法 13% Accepted Given n distinc ...

  6. HDu 1001 Sum Problem 分类: ACM 2015-06-19 23:38 12人阅读 评论(0) 收藏

    Sum Problem Time Limit: 1000/500 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total ...

  7. HD2058The sum problem

    The sum problem Time Limit: 5000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Tot ...

  8. Maxmum subsequence sum problem

    We have a lot of ways to solve the maximum subsequence sum problem, but different ways take differen ...

  9. NYOJ--927--dfs--The partial sum problem

    /* Name: NYOJ--927--The partial sum problem Author: shen_渊 Date: 15/04/17 19:41 Description: DFS,和 N ...

  10. 动态规划法(三)子集和问题(Subset sum problem)

      继续讲故事~~   上次讲到我们的主人公丁丁,用神奇的动态规划法解决了杂货店老板的两个找零钱问题,得到了老板的肯定.之后,他就决心去大城市闯荡了,看一看外面更大的世界.   这天,丁丁刚回到家,他 ...

随机推荐

  1. idea新建项目打包 ,运行jar,并放入maven仓库

    1.新建项目(转自:http://www.cnblogs.com/wql025/p/5215570.html) 创建一个新Maven项目 new 一个project 不选择任何Maven模板 起个Gr ...

  2. 已备份数据库的磁盘结构版本号为611,server支持版本号为539,无法还原或升级数据库

    提供的是bak文件是2005备份的,还原到本地的sqlserver2000,提示:已备份数据库的磁盘上结构版本号为611.服务器支持版本号539,无法还原或升级数据库. 网上找了下,原因是611是sq ...

  3. maven-tomcat7;IOC;AOP;数据库远程连接

    [说明]真的是好烦下载插件啊,maven-tomcat7 插件试了好多次都不行,下载不成:部署不成:好不容易从github中得到的springmvc项目也是运行不起来,中间又是查了许多东西,绕着绕着都 ...

  4. 爬虫入门【1】urllib.request库用法简介

    urlopen方法 打开指定的URL urllib.request.urlopen(url, data=None, [timeout, ]*, cafile=None, capath=None, ca ...

  5. hdu_1226超级密码(BFS)

    超级密码 Problem Description Ignatius花了一个星期的时间终于找到了传说中的宝藏,宝藏被放在一个房间里,房间的门用密码锁起来了,在门旁边的墙上有一些关于密码的提示信息:密码是 ...

  6. K - Max Sum Plus Plus

    K - Max Sum Plus Plus Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I6 ...

  7. Sum of Remainders(数学题)

    F - Sum of Remainders Time Limit:2000MS     Memory Limit:262144KB     64bit IO Format:%I64d & %I ...

  8. 成功扩展live555支持ipv6,同时支持RTSPServer & RTSPClient

    live555对ipv6的扩展 从live555的官网看live555的发展历史,实在是历史悠久,保守估计已经发展了至少16年以上了,同时,这也导致了live555在很多架构和考虑上面不能满足现代化的 ...

  9. 小程序获取openId

    1.小程序获取微信openId   wx.login({ success: res => { // 发送 res.code 到后台换取 openId, sessionKey, unionId / ...

  10. Pipeline模式(netty源码死磕6)

    精进篇:netty源码死磕6  巧夺天工--Pipeline模式揭秘 1. 巧夺天工--Pipeline模式揭秘 1.1. Pipeline模式简介 管道的发名者叫,Malcolm Douglas M ...