开始之前
放任自己了一段时间后,决定还是把之前的学习成果整理出来,尝试了多个博客网站之后,觉得还是csdn用起来比较顺手.
问题
Given an array of integers nums and an integer target, return indices of the two numbers such that they add up to target.
You may assume that each input would have exactly one solution, and you may not use the same element twice.
You can return the answer in any order.
Example 1:
Input: nums = [2,7,11,15], target = 9
Output: [0,1]
Output: Because nums[0] + nums[1] == 9, we return [0, 1].
Example 2:
Input: nums = [3,2,4], target = 6
Output: [1,2]
Example 3:
Input: nums = [3,3], target = 6
Output: [0,1]
Constraints:
2 <= nums.length <= 105
-109 <= nums[i] <= 109
-109 <= target <= 109
思考
这是leetcode上的第一题,难度是easy.
方法1
最直观的方法当然就是双重遍历.
从第一个元素开始,每次指定一个元素a ,然后遍历后面的元素,如果找不到符合条件的元素b,那么把元素a向后移一位,继续寻找元素b.
时间复杂度O(n2).
空间复杂度O(1).
public int[] twoSum(int[] nums, int target) {
for(int i = 0; i < nums.length; i++){
int a = nums[i];
for(int j = i + 1; j < nums.length; j++){
if(a + nums[j] == target)
return new int[]{i, j};
}
}
return null;
}
方法2
有没有比上面更快的方法呢?
给定的数组是无序的.可以先对数进行组排序,再进行计算.就可以一定程度上排除无效计算.
比如当输入是升序排列的时候,如果两个数之后大于target, 那么就可以结束当前循环进入下一个循环了.
但是, 题目中要求返回的不是值,而是值的下标.所以不能使用排序,因为会打乱顺序.
所以我们可以用map来做,空间换时间.
有一点需要注意就是数组中允许重复的数字,所以不能简单的把所有数字都放入map然后来遍历.
时间复杂度O(n).
空间复杂度O(n).
public int[] twoSum(int[] nums, int target) {
Map<Integer, Integer> map = new HashMap<Integer, Integer>();
for(int i = 0, len = nums.length; i < len; i++){
int j = map.getOrDefault(target - nums[i], -1);
if(j >= 0)
return new int[]{i, j};
else
map.put(nums[i], i);
}
return null;
}