代码改变世界

LeetCode刷题之Two Sum

2015-01-06 17:17  雪夜&流星  阅读(158)  评论(0)    收藏  举报

Problem:

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

由于水平原因,我第一反应是用两个for循环,第一个for全部,第二个for从前一个for的迭代加1开始寻找相等记录下标,提交之后直接Time Limit Exceeded

后来想了一下,觉得可以将其排序一下,分别从开头和结尾开始遍历,看两者相加是否符合target。如下代码参考了网上的解法,考虑的比较周到:

 

public class Solution {
    public static int[] twoSum(int[] numbers, int target) {
        int length = numbers.length;
        assert(length >= 2);
        int[] ret = new int[2];
        int[] sorted = new int[length];
        System.arraycopy(numbers, 0,sorted, 0, length);
        Arrays.sort(sorted);
        int low = 0;
        int high = length - 1;
        while (low < high) {
            if (sorted[low] + sorted[high] < target) {
                low ++;
                continue;
            } else if (sorted[low] + sorted[high] > target) {
                high --;
                continue;
            } else {
                break;
            }
        }

        int value1 = sorted[low];
        int value2 = sorted[high];
        int index1 = -1, index2 = -1;
        for (int i = 0; i < length; i++) {
            if ((numbers[i] == value1) || (numbers[i] == value2)) {
                if (index1 == -1) {
                    index1 = i + 1;
                } else {
                    index2 = i + 1;
                }
            }
        }

        ret[0] = index1;
        ret[1] = index2;
        Arrays.sort(ret);
        return ret;
    }
}

 

但是这种解决的办法效率还是挺低的,唉,只怪水平太low了。

网上给出的最优解法:

public class Solution {
    public static int[] twoSum(int[] numbers, int target) {
        HashMap<Integer, Integer> map = new HashMap<Integer, Integer>();
        int[] result = new int[2];

        for (int i = 0; i < numbers.length; i++) {
            if (map.containsKey(numbers[i])) {
                int index = map.get(numbers[i]);
                result[0] = index+1 ;
                result[1] = i+1;
                break;
            } else {
                map.put(target - numbers[i], i);
            }
        }

        return result;
    }
}

还有另外一种解法,开始将所有元素添加到HashSet中,然后再遍历整个数组,判断余下的数是否在set中,如果在,则从i+1继续遍历得到第二个数的索引:

public class Solution {
    public static int[] twoSum(int[] numbers, int target) {
        int[] indexs = new int[2];
        Set<Integer> set = new HashSet<Integer>();
        for (int i : numbers) {
            set.add(i);
        }

        for (int i = 0; i < numbers.length; i++) {
            if (set.contains(target - numbers[i])) {
                for (int j = i + 1; j < numbers.length; j++) {
                    if (numbers[i] + numbers[j] == target) {
                        indexs[0] = i + 1;
                        indexs[1] = j + 1;
                        return indexs;
                    }
                }
            }
        }
        return indexs;
    }
}