【力扣刷题】第一题:两数之和
力扣第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) { MapanswerMap = 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; } }
更进一步提高效率:
看了大佬的代码,优化点在于能够在一次遍历中完成所有任务,待后续学习补充