【力扣刷题】第一题:两数之和


力扣第1题:两数之和

首先想到一种解法:
下标组合作为key,对应两数之和作为value,遍历求和后存到hashmap,最后查询value对应的key;但是题目中有说:“可以假设每种输入只会对应一个答案”,即该数组任意两元素求和结果都唯一,则可以调整将两数之和作为key,下标组合作为对应的value,以减少查询时间。
--执行结果超出时间限制
后修改为在循环中直接判断是否匹配,匹配则返回,正确通过,但实际性能并不理想,时间复杂度为O(n^2)。
最终结果:

class Solution {
    public int[] twoSum(int[] nums, int target) {
        for(int index1 = 0; index1 < nums.length; index1++) {
            for(int index2 = index1 + 1; index2 < nums.length; index2++) {
                if(nums[index1] + nums[index2] == target) {
                    return new int[]{index1, index2};
                }
            }
        }
        return null;
    }
}

降低时间复杂度的思考:
O(n^2)的来源就是遍历数组带来的,需要减少遍历数组的消耗。遍历就是n,所以要把遍历变成查询,利用查询增强性能。

第二种解法思路:
构建新数组ms,值为target与num的差(时间复杂度O(n)),因为target为两数之和,故ms中元素自身下标与在nums中的下标(如果存在的话)组合即为所需要的答案。将双层循环遍历转化为查询。
--新思路,因为target与num的差值必定存在于nums且唯一,可以将第一种解法的优化思路放进来,将差值作为key,下标作为value省去匹配的时间,直接用hashmap提高查询效率O(n * logn)
最终结果:

class Solution {
    public int[] twoSum(int[] nums, int target) {
        Map answerMap = new HashMap<>();
        for (int i = 0; i < nums.length; i++) {
            answerMap.put(target - nums[i], i);
        }
        for (int j = 0; j < nums.length; j++) {
            Integer index = answerMap.get(nums[j]);
            if(index != null && index != j) {
                return new int[]{j, index};
            }
        }
        return null;
    }
}

更进一步提高效率:
看了大佬的代码,优化点在于能够在一次遍历中完成所有任务,待后续学习补充

相关