二数之和
题目: 给定一个整形数组和一个整数target,返回2个元素的下标,它们满足相加的和为target。你可以假定每个输入,都会恰好有一个满足条件的返回结果。
思路: 一次遍历即可,借助一个Map用于存储value-index,每次去map中get差值,如果为null,则将当前值存入,否则,即找到对应的匹配。注,遍历到两者中的后一个元素时才会找到匹配。
class Solution {
public int[] twoSum(int[] nums, int target) {
int[] result = new int[2];
Map<Integer, Integer> tempMap = new HashMap<>();
for (int i = 0; i < nums.length; i++) {
int temp = target - nums[i];
if (tempMap.containsKey(temp)) {
result[0] = tempMap.get(temp);
result[1] = i;
return result;
} else {
tempMap.put(nums[i], i);
}
}
result[0] = 0;
result[1] = 0;
return result;
}
}
三数之和
题目: 给定一个数组S,它包含n个整数,它是否存在3个元素a,b,c,满足a+b+c=0?找出所有满足条件的元素数组。提示:a,b,c三个元素必须是升序排列(也就是满足a ≤ b ≤ c),最终的结果不能包含重复的元素数组。例如给定S为{-1 0 1 2 -1 -4},返回结果是(-1, 0, 1)和(-1, -1, 2)。
思路: 遍历数组建立Map(value-indexList),排序数组,三层循环变为二层,最内层根据差值查询Map即可,以下点可以加快搜索进度
- 如果第一层循环获得的起始值已经大于0,则直接break。
- 如果待查找的第三个数的值已经小于第二个数,则直接break。
- 第一层、第二层从第二次循环开始,如果当前值和前一个值相等,则continue。
public List<List<Integer>> threeSum(int[] nums) {
List<List<Integer>> res = new ArrayList<>();
// nums先进行排序
Arrays.sort(nums);
Map<Integer, List<Integer>> map = new HashMap<>();
for (int i = 0; i < nums.length; i++) {
int num = nums[i];
if (map.get(num) == null) {
List<Integer> subscripts = new ArrayList<>();
subscripts.add(i);
map.put(num, subscripts);
} else {
map.get(num).add(i);
}
}
for (int i = 0; i <= nums.length - 3; i++) {
if (nums[i] > 0) {
break;
}
if (i > 0 && nums[i] == nums[i - 1]) {
continue;
}
for (int j = i + 1; j <= nums.length - 2; j++) {
if (j > i + 1 && nums[j] == nums[j - 1]) {
continue;
}
int finalNum = -nums[i] - nums[j];
if (finalNum < nums[j]) {
break;
}
List<Integer> subscripts = map.get(finalNum);
if (subscripts == null) {
continue;
}
for (Integer subscript : subscripts) {
if (subscript != j && subscript != i) {
List<Integer> list = new ArrayList<>();
list.add(nums[i]);
list.add(nums[j]);
list.add(nums[subscript]);
res.add(list);
break;
}
}
}
}
return res;
}