【1.两数之和】

84 阅读1分钟

题目

给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 target  的那 两个 整数,并返回它们的数组下标。

你可以假设每种输入只会对应一个答案,并且你不能使用两次相同的元素。

你可以按任意顺序返回答案。

输入: nums = [2,7,11,15], target = 9
输出: [0,1]
解释: 因为 nums[0] + nums[1] == 9 ,返回 [0, 1] 

两数之和-leetcode

题解

方式一:暴力遍历

复杂度:O(n^2)

public int[] twoSum(int[] nums, int target) {
    int[] result = new int[2];
    // 确定基数
    for (int i = 0; i < nums.length; i++) {
        // 遍历剩下的所有数,找到符合条件的
        for (int j = i + 1; j < nums.length; j++) {
            if (nums[i] + nums[j] == target) {
                result[0] = i;
                result[1] = j;
                return result;
            }
        }
    }
    return result;
}

方式二:排序 + 双指针

复杂度:还不知道咋算 快排是O(nlogn)

public int[] twoSum(int[] nums, int target) {
    // 这里用的快排,也可以自己实现
    Arrays.sort(nums);
    int[] result = new int[2];
    int left = 0;
    int right = nums.length - 1;
    // 不能使用两次相同的元素,所以不是 <=
    while (left < right) { 
        if (nums[left] + nums[right] == target) {
            result[0] = nums[left];
            result[1] = nums[right];
            break;
        } else if (nums[left] + nums[right] < target) {
            left++;
        } else {
            right--;
        }
    }
    return result;
}

方式三:前缀和 + Map

复杂度:一次遍历O(n),map读写不会算

public int[] twoSum(int[] nums, int target) {
        // key=值 value=下标
        Map<Integer, Integer> map = new HashMap<>(); 
        for (int i = 0; i < nums.length; i++) {
            if (map.containsKey(target - nums[i])) {
                // 符合条件返回两个下标
                return new int[]{map.get(target - nums[i]), i};
            }
            // 不符合条件把当前数写入map
            map.put(nums[i], i);
        }
        return new int[]{};
    }

总结

算法:前缀和双指针快排
数据结构:Map数组