18. 4Sum
Problem
Given an array nums of n integers, return an array of
all the unique quadruplets [nums[a], nums[b], nums[c], nums[d]] such that:
- 0 <= a, b, c, d < n
- a, b, c, and d are distinct.
- nums[a] + nums[b] + nums[c] + nums[d] == target
You may return the answer in any order.
Example 1:
Input: nums = [1,0,-1,0,-2,2], target = 0
Output: [[-2,-1,1,2],[-2,0,0,2],[-1,0,0,1]]
Example 2:
Input: nums = [2,2,2,2,2], target = 8
Output: [[2,2,2,2]]
Constraints:
1 <= nums.length <= 200
-109 <= nums[i] <= 109
-109 <= target <= 109
Intuition
- Tương tự bài 3sum, 2sum.
- Cần tìm một
quadruplets
, cố định 1 phần tử => có được bài toán3sum
Approach
- Dùng 2 pointer duyệt đầu mảng và cuối mảng
- Độ phức tạp O(n3)
- Lưu ý có test case số lớn, nên lúc cộng trừ thì chuyển sang
long
Implementation
class Solution {
public List<List<Integer>> fourSum(int[] nums, int target) {
List<List<Integer>> result = new ArrayList<>();
Arrays.sort(nums);
for (int i = 0; i < nums.length; i++) {
if (i > 0 && nums[i] == nums[i-1]) continue;
// 3sum problem
for (int j = i+1; j < nums.length; j++) {
if (j > (i+1) && nums[j] == nums[j-1]) continue;
long newTarget = (long)target - nums[i] - nums[j]; // use long datatype to avoid overflow number
int pLeft = j+1; int pRight = nums.length-1;
if (pLeft >= nums.length || pRight < j+1) continue;
// 2sum problem
while (pLeft < pRight) {
long sum = nums[pLeft] + nums[pRight]; // use long datatype to avoid overflow number
if (sum == newTarget) {
result.add(new ArrayList<>(Arrays.asList(nums[i], nums[j], nums[pLeft], nums[pRight])));
do {
pRight--;
} while (pRight >= j+1 && nums[pRight] == nums[pRight+1]);
do {
pLeft++;
} while (pLeft < nums.length && nums[pLeft] == nums[pLeft-1]);
} else if (sum > newTarget) {
do {
pRight--;
} while (pRight >= j+1 && nums[pRight] == nums[pRight+1]);
} else {
do {
pLeft++;
} while (pLeft < nums.length && nums[pLeft] == nums[pLeft-1]);
}
}
}
}
return result;
}
}