两数之和
可以排序,然后双指针;
也可以用hashmap,记录数字和序号。遍历。
三数之和
升序排列,然后用三指针。第一个指针遍历。第二个指针遍历。第三个指针从后往前走。
四数之和
升序排列,用四指针。其实就是四层遍历。
/**
* @Auther: Mason
* @Date: 2020/09/15/7:56
* @Description:
*/
class Solution {
public static void main(String[] args) {
Solution s = new Solution();
System.out.println(s.fourSum(new int[]{
-2,-1, 0, 0, 1, 2}, 0));
}
public List<List<Integer>> fourSum(int[] nums, int target) {
List<List<Integer>> res = new LinkedList<>();
Arrays.sort(nums); // 先排序
int a, b, c, d, sum,min,max;
int len = nums.length;
for (a = 0; a <= len - 4; a++) {
// 第一层遍历,第一个指针。
if (a >= 1 && nums[a] == nums[a - 1]) continue; // 第一个位置去重。
min = nums[a] + nums[a + 1] + nums[a + 2] + nums[a + 3];
if (min > target) {
break;
}
max = nums[a] + nums[len - 3] + nums[len - 2] + nums[len - 1];
if (max < target) {
continue;
}
OUT:
for (b = a + 1; b <= len - 3; b++) {
// 第二个指针
if (b > a + 1 && nums[b] == nums[b - 1]) continue;
min = nums[a] + nums[b] + nums[b + 1] + nums[b + 2];
if (min > target) {
break;
}
max = nums[a] + nums[b] + nums[len - 2] + nums[len - 1];
if (max < target) {
continue;
}
for (c = b + 1; c <= len - 2; c++) {
// 第三个指针
if (c > b + 1 && nums[c] == nums[c - 1]) continue;
min = nums[a]+nums[b]+nums[c]+nums[c+1];
if(min>target) break;
max = nums[a]+nums[b]+nums[c]+nums[len-1];
if(max<target) continue;
sum = nums[a] + nums[b] + nums[c];
d = len - 1;
while (d > c && sum + nums[d] > target) d--;
if (d == c) continue OUT;
if (sum + nums[d] == target) {
LinkedList<Integer> tmp = new LinkedList<>();
tmp.add(nums[a]);
tmp.add(nums[b]);
tmp.add(nums[c]);
tmp.add(nums[d]);
res.add(tmp);
}
}
}
}
return res;
}
}