您的位置:首页 > 编程语言 > Java开发

LeetCode(001) Two Sum (Java)

2015-04-12 07:12 375 查看
题目如下:

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

分析如下:

1 详细见代码中的bug 注释

2 用这道题目来熟悉了java中常见的comparator ,sort, hash的用法。

我的代码:

一共写了3个版本。

第一个版本,先sort,然后头尾各来一个指针,开始搜寻。

// Solution 1 
//252 ms
public class Solution {
		
		class Element {
			private int value;
			private int index;
			Element(int v, int i) {
				this.value = v;
				this.index = i + 1;
			}
		}
		
	    public int[] twoSum(int[] numbers, int target) {
	    	Element[] e = new Element[numbers.length];
	    	int[] res = new int[2];
	    	
	    	for (int i = 0; i < numbers.length; ++i) {
	    		e[i] = new Element(numbers[i], i);
	    	}
	    	
	    	//NOTE1: compartor的写法格式
	    	Arrays.sort(e, new Comparator<Element> ()  {
	    			public int  compare(Element a, Element b) {
                                        // java使用1, 0, -1来代表大小关系的比较。
	    			        return a.value>b.value?1:(a.value==b.value?0:-1);
	    			}
	    	});
	        int i = 0, j = numbers.length - 1;
	        while (i < j) {
	        	if (e[i].value + e[j].value > target) {
	        		--j;
	        		//BUG1: 注意 j 和 j + 1 比较,不是 j 和 j -1 比较。
	        		while(i < j && j < numbers.length -1 &&  e[j].value == e[j + 1].value) {
	        		    --j;
	        		}
	        	} else if (e[i].value + e[j].value < target) {
	        		++i;
	        		//BUG2: 注意 i 和 i -1  比较,不是 i 和 i + 1 比较。
	        		while (i < j && i > 0 && e[i].value == e[i - 1].value) {
	        		    ++i;    
	        		}
	        	} else {
	        		res[0] = e[i].index;
	        		res[1] = e[j].index;
	        		break;
	        	}
	        }
                //BUG3: The final result should be sorted
	        Arrays.sort(res); 
	        return res;
	    }
	    
	}


第二个版本是使用hashmap来做的。

但是提交发现,有个很容易忽略的case

// Input: [3,2,4], 6

// Output: 1, 1

// Expected: 2, 3

这里,误以为 6 = 3 + 3。但是其实3 只出现了1次,而不是2次,所以在map里还要注意判断是否重复考虑了元素的相加。

// Solution 2
// swipe the array twice, one for bulding the map, another for searching. Then there might be a trap below
// 常见错误: map 没有考虑区别不合理的重复计算,比如下面的6 = 3 + 3,其实不对。应该被去掉。
// Input:	    [3,2,4], 6
// Output:	    1, 1
// Expected:	2, 3
// 248 ms
public class Solution {
	    public int[] twoSum(int[] numbers, int target) {
	    	int[] result = new int [2];
	    	HashMap<Integer, Integer> map = new HashMap<Integer, Integer> ();
	    	for (int i = 0; i < numbers.length; ++i) {
	    		map.put(numbers[i], i + 1);
	    	}
	    	for (int i = 0; i < numbers.length; ++i) {
	    		if( map.containsKey(target - numbers[i]) && map.get(target - numbers[i]) != i + 1) {
	    			result[0] = i + 1;
	    			result[1] = map.get(target - numbers[i]);
	    			break;
	    		} 
	    	}
	    	Arrays.sort(result);
	    	return result;
	    }
}


上面这个版本扫描了原数组两次,其实只要稍微改动一下,就可以只扫描原数组一次了。

// solution 3
// 294 ms
public class Solution {
    public int[] twoSum(int[] numbers, int target) {
        HashMap<Integer, Integer> hashmap = new HashMap<Integer, Integer> ();
        int[] result = new int[2];
        for (int i = 0; i < numbers.length; ++i) {
            if (hashmap.containsKey(target - numbers[i])) {
                result[0] = i + 1;
                result[1] = hashmap.get(target - numbers[i]);
                break;
            } else {
                hashmap.put(numbers[i], i + 1);
            }
        }
        Arrays.sort(result);
        return result;
    }
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: