1

题目描述:

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

分类:简单题

1A:false

坑点:

  • 一看题目,没保证数组已排序,也没保证数组内数字一定是正数。觉得只能暴搜了。时间复杂度O(n^2),超时。
  • 在没有编译器帮助下,根据题意说“You may assume that each input would have exactly one solution” ,于是便只在if语句中写了return,因为根据输入,它至少有一次为真。但提交后编译器报错说,没有Return语句,所以一定要在最后加上一个return,哪怕意思意思也好。

最开始的代码(超时):

public class Solution {
    public int[] twoSum(int[] numbers, int target) {
        //since each input would have exactly one solution, it doesn't matter how I init the array
        int[] indices = {0, 0}; 
        int temp = 0;
        for (int i = 0, len = numbers.length; i < len; i++) {
            temp = numbers[i];
            for (int j = i + 1; j < len; j++) {
                if (numbers[j] + temp == target) {
                    indices[0] = i + 1; //answers are not zero-based
                    indices[1] = j + 1;
                    return indices;
                }
            }
        }
        return indices;
    }
}

想了想,既然原数组没排序,那何不弄个排好序的,然后二分查找之?

改进版(Accepted):

public class Solution {
    public int[] twoSum(int[] numbers, int target) {
        //since each input would have exactly one solution, it doesn't matter how I init the array
        int[] indices = {0, 0}; 
        int[] cloned = numbers.clone();//O(n) space

        Arrays.sort(cloned); // sort in ascending order, O(nlogn)
        int temp = 0;
        for (int i = 0, len = numbers.length; i < len; i++) {
            temp = numbers[i];
            // only if i can binary search it from the cloned array
            // would I traverse the original array to see if any element
            // meets the requirement.
            // [Note] The only condition that we may not find the element 
            // is temp equals target/2
            // guess why?
            if (Arrays.binarySearch(cloned, target - temp) > 0) {
                for (int j = i + 1; j < len; j++) {
                    if (numbers[j] + temp == target) {
                        indices[0] = i + 1; //answers are not zero-based
                        indices[1] = j + 1;
                        return indices;
                    }
                }
            }
        }
        return indices;
    }
}

虽然能通过了,但感觉结构上还是有点搓,clone/sort/binSearch,略繁琐。于是HashMap闪亮登场了,遍历数组,把每个元素做为Map的key标记下,这样在查找时就巨方便了。

最终版:

public class Solution {
    public int[] twoSum(int[] numbers, int target) {
        //since each input would have exactly one solution, it doesn't matter how I init the array
        int[] indices = {0, 0};
        int len = numbers.length;
        Map<Integer, Boolean> map = new HashMap<Integer, Boolean>();

        for (int i = 0; i < len; i++) map.put(numbers[i], true);

        for (int i = 0; i < len; i++) {
            if (map.containsKey(target - numbers[i])) {
                for (int j = i + 1; j < len; j++) {
                    if (numbers[j] + numbers[i]== target) {
                        indices[0] = i + 1; //answers are not zero-based
                        indices[1] = j + 1;
                        return indices;
                    }
                }
            }
        }
        return indices;
    }
}

注意Java中Map中的Key和Value都必须是Object类型,Primitive是不行的。虽然在赋上去的时候会进行隐式转换,但在声明时可不能写成Map<int, boolean>.


ssnau
1.5k 声望98 粉丝

负能量职业打码师