Link: https://oj.leetcode.com/problems/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.
You may assume that each input would have exactly one solution.
Input: numbers={2, 7, 11, 15}, target=9
Output: index1=1, index2=2
Approach I: Usehashset
Time: O(n), Space: O(n)
这是我写的代码。有问题。不能这样循环两遍,否则会有问题:
Input: | [3,2,4], 6 |
Output: | 1, 1 |
Expected: | 2, 3 |
public class Solution {
public int[] twoSum(int[] numbers, int target) {
int[] result = new int[2];
HashMap<Integer, Integer> table = new HashMap<Integer, Integer>();
for(int i = 0; i < numbers.length; i++){
table.put(target - numbers[i], i);
}
for(int i = 0; i < numbers.length; i++){
if(table.containsKey(numbers[i])){
result[0] = table.get(numbers[i])+1;
result[1] = i+1;
return result;
}
}
return result;
}
}
正确解法:一遍for loop
public class Solution {
public int[] twoSum(int[] numbers, int target) {
int[] result = new int[2];
if(numbers == null || numbers.length < 2) return result;
HashMap<Integer, Integer> map = new HashMap<Integer, Integer>();
for(int i = 0; i < numbers.length; i++){
if(map.containsKey(numbers[i])){
result[0] = map.get(numbers[i])+1;
result[1] = i+1;
return result;
}
else{
map.put(target - numbers[i], i);
}
}
return result;
}
}
Approach II: 先排序,然后左右夹逼。
Time: O(nlogn)+O(n) = O(nlogn).
public class Solution {
public class Element{
int index;
int val;
public Element(int index, int val){
this.index = index;
this.val = val;
}
}
public int[] twoSum(int[] numbers, int target) {
int[] result = new int[2];
if(numbers == null || numbers.length < 2) return result;
Element[] e = new Element[numbers.length];
for(int i = 0; i < numbers.length; i++){
e[i] = new Element(i, numbers[i]);
}
Comparator<Element> comparator = new Comparator<Element>(Element a, Element b){
if(a.val > b.val) return 1;
else if(a.val == b.val) return 0;
else return -1;
}
int i = 0;
int j = numbers.length - 1;
while(i < j){
int sum = e[i].val + e[j].val;
if(sum == target){
result[0] = Math.min(e[i].index, e[j].index)+1;
result[1] = Math.max(e[i].index, e[j].index)+1;
return result;
}
else if(sum < target){
i++;
}
else{
j--;
}
}
return result;
}
}
Arrays.sort(numbers,
new Comparator<Element>(){
public int compare(Element a, Element b){
if(a.val > b.val) return 1;
else if(a.val == b.val) return 0;
else return -1;
}});
or
class ValComparator implements Comparator<Element> {
public int compare(Element a, Element b) {
if(a.val == b.val) return 0;
else if(a.val > b.val) return 1;
else return -1;
}
}
Arrays.sort(elementArr, new ValComparator());
2014.11.3
HashMap的解法没问题。todo:Comparator解法
2016.1.23
Below is wrong. 排序以后,原来的index就改变了,所以不能用left,right作为返回的index. 因此如果要用排序,必须先把index,val都存起来。
public int[] twoSum(int[] nums, int target) {
//sort?
Collections.sort(nums, new Comparator());
//one from left, one from right
int[] result = new int[2];
int left = 0;
int right = nums.length-1;
while(left < right) {
if(nums[left] + nums[right] == target) {
result[0] = left;
result[1] = right;
return result;
}
else if(nums[left] + nums[right] < target) {
left++;
}
else{
right--;
}
}
return result;
}