Two Sum

Given an array of integers, return indices of the two numbers such that they add up to a specific target.

You may assume that each input would have exactly one solution.

Example:
Given nums = [2, 7, 11, 15], target = 9,

Because nums[0] + nums[1] = 2 + 7 = 9, return [0, 1].

UPDATE (2016/2/13):
The return format had been changed to zero-based indices. Please read the above updated description carefully.

难度: Easy.

就是说, 给一个整数数组(如[2, 7, 11, 15]), 给一个目标数字(如9), 从数组中找出相加为这个目标数字的两个数的下标. 2+7=9, 就返回2,7的下标[0,1]. 只需要给出满足条件的一对数字即可.

这个题想起来比较直接, 此处给出两种解法, 这之后的题目中, 还有多个数字相加的相对较难的题目.

第一种:
将数组排序, 以两个游标从两头向中间逼近

  1. 如果和偏大, 就把右游标向左挪动

  2. 如果和偏小, 就把左游标向右挪动

最终返回正确的下标. 此算法时间复杂度是 O(nlogn).

public class Solution {
    public int[] twoSum(int[] nums, int target) {

        class Pair {
            int idx;
            int val;
        }

        Pair[] pnums = new Pair[nums.length];
        for (int i = 0; i < nums.length; i++) {
            pnums[i] = new Pair();
            pnums[i].idx = i;
            pnums[i].val = nums[i];
        }

        Arrays.sort(pnums, new Comparator<Pair>() {

            @Override
            public int compare(Pair o1, Pair o2) {
                if (o1.val > o2.val) {
                    return 1;
                } else if (o1.val < o2.val) {
                    return -1;
                } else {
                    return 0;
                }
            }

        });

        int lp = 0;
        int rp = nums.length - 1;
        while (true) {
            int sum = pnums[lp].val + pnums[rp].val;
            if (sum == target) {
                break;
            } else if (sum > target) {
                rp--;
            } else {
                lp++;
            }
        }
        if (pnums[lp].idx < pnums[rp].idx) {
            return new int[] { pnums[lp].idx, pnums[rp].idx };
        } else {
            return new int[] { pnums[rp].idx, pnums[lp].idx };
        }
    }

    public static void main(String[] args) {
        int[] a1 = { 3, 2, 4 };
        Solution s = new Solution();
        int[] ret = s.twoSum(a1, 6);
        System.out.println("" + ret[0] + " " + ret[1]);
    }
}

第二种:
使用一个map, 记录值->下标的映射关系(重复的值其实覆盖了没关系).
循环看每个值, 对于值a, 从map中查找(target-a), 如果存在, 则输出这两个数值的下标即可.

由于使用HashMap, 算法的时间复杂度是O(n)

public class Solution2 {
    public int[] twoSum(int[] nums, int target) {
        Map<Integer, Integer> nmap = new HashMap<Integer, Integer>();
        for (int i = 0; i < nums.length; i++) {
            nmap.put(nums[i], i);
        }

        int i = 0;
        int j = 0;
        for (; i < nums.length; i++) {
            if (nmap.containsKey(target - nums[i])) {
                j = nmap.get(target - nums[i]);
                if (i != j) {
                    break;
                }
            }
        }
        if (i < j) {
            return new int[] { i, j };
        } else {
            return new int[] { j, i };
        }

    }

    public static void main(String[] args) {
        int[] a1 = { 3, 2, 4 };
        Solution2 s = new Solution2();
        int[] ret = s.twoSum(a1, 6);
        System.out.println("" + ret[0] + " " + ret[1]);
    }
}

EthanSun
45 声望3 粉丝