class Solution {
public:
vector<vector<int>> fourSum(vector<int>& nums, int target) {
}
};
18. 四数之和
给你一个由 n
个整数组成的数组 nums
,和一个目标值 target
。请你找出并返回满足下述全部条件且不重复的四元组 [nums[a], nums[b], nums[c], nums[d]]
(若两个四元组元素一一对应,则认为两个四元组重复):
0 <= a, b, c, d < n
a
、b
、c
和 d
互不相同nums[a] + nums[b] + nums[c] + nums[d] == target
你可以按 任意顺序 返回答案 。
示例 1:
输入:nums = [1,0,-1,0,-2,2], target = 0 输出:[[-2,-1,1,2],[-2,0,0,2],[-1,0,0,1]]
示例 2:
输入:nums = [2,2,2,2,2], target = 8 输出:[[2,2,2,2]]
提示:
1 <= nums.length <= 200
-109 <= nums[i] <= 109
-109 <= target <= 109
原站题解
javascript 解法, 执行用时: 60 ms, 内存消耗: 43.2 MB, 提交时间: 2023-07-15 09:10:22
/** * @param {number[]} nums * @param {number} target * @return {number[][]} */ var fourSum = function (nums, target) { nums.sort((a, b) => a - b); const n = nums.length; let ans = []; for (let a = 0; a < n - 3; a++) { // 枚举第一个数 const x = nums[a]; // 使用 long long 避免溢出 if (a > 0 && x === nums[a - 1]) continue; // 跳过重复数字 if (x + nums[a + 1] + nums[a + 2] + nums[a + 3] > target) break; // 优化一 if (x + nums[n - 3] + nums[n - 2] + nums[n - 1] < target) continue; // 优化二 for (let b = a + 1; b < n - 2; b++) { // 枚举第二个数 const y = nums[b]; if (b > a + 1 && y === nums[b - 1]) continue; // 跳过重复数字 if (x + y + nums[b + 1] + nums[b + 2] > target) break; // 优化一 if (x + y + nums[n - 2] + nums[n - 1] < target) continue; // 优化二 let c = b + 1, d = n - 1; while (c < d) { // 双指针枚举第三个数和第四个数 const s = x + y + nums[c] + nums[d]; // 四数之和 if (s > target) d--; else if (s < target) c++; else { // s == target ans.push([x, y, nums[c], nums[d]]); for (c++; c < d && nums[c] === nums[c - 1]; c++); // 跳过重复数字 for (d--; d > c && nums[d] === nums[d + 1]; d--); // 跳过重复数字 } } } } return ans; };
golang 解法, 执行用时: 4 ms, 内存消耗: 2.6 MB, 提交时间: 2023-07-15 09:10:08
func fourSum(nums []int, target int) (ans [][]int) { sort.Ints(nums) n := len(nums) for a := 0; a < n-3; a++ { // 枚举第一个数 x := nums[a] if a > 0 && x == nums[a-1] { // 跳过重复数字 continue } if x+nums[a+1]+nums[a+2]+nums[a+3] > target { // 优化一 break } if x+nums[n-3]+nums[n-2]+nums[n-1] < target { // 优化二 continue } for b := a + 1; b < n-2; b++ { // 枚举第二个数 y := nums[b] if b > a+1 && y == nums[b-1] { // 跳过重复数字 continue } if x+y+nums[b+1]+nums[b+2] > target { // 优化一 break } if x+y+nums[n-2]+nums[n-1] < target { // 优化二 continue } c, d := b+1, n-1 for c < d { // 双指针枚举第三个数和第四个数 s := x + y + nums[c] + nums[d] // 四数之和 if s > target { d-- } else if s < target { c++ } else { ans = append(ans, []int{x, y, nums[c], nums[d]}) for c++; c < d && nums[c] == nums[c-1]; c++ {} // 跳过重复数字 for d--; d > c && nums[d] == nums[d+1]; d-- {} // 跳过重复数字 } } } } return }
java 解法, 执行用时: 2 ms, 内存消耗: 42.8 MB, 提交时间: 2023-07-15 09:09:54
class Solution { public List<List<Integer>> fourSum(int[] nums, int target) { Arrays.sort(nums); List<List<Integer>> ans = new ArrayList<>(); int n = nums.length; for (int a = 0; a < n - 3; a++) { // 枚举第一个数 long x = nums[a]; // 使用 long 避免溢出 if (a > 0 && x == nums[a - 1]) continue; // 跳过重复数字 if (x + nums[a + 1] + nums[a + 2] + nums[a + 3] > target) break; // 优化一 if (x + nums[n - 3] + nums[n - 2] + nums[n - 1] < target) continue; // 优化二 for (int b = a + 1; b < n - 2; b++) { // 枚举第二个数 long y = nums[b]; if (b > a + 1 && y == nums[b - 1]) continue; // 跳过重复数字 if (x + y + nums[b + 1] + nums[b + 2] > target) break; // 优化一 if (x + y + nums[n - 2] + nums[n - 1] < target) continue; // 优化二 int c = b + 1, d = n - 1; while (c < d) { // 双指针枚举第三个数和第四个数 long s = x + y + nums[c] + nums[d]; // 四数之和 if (s > target) d--; else if (s < target) c++; else { // s == target ans.add(List.of((int) x, (int) y, nums[c], nums[d])); for (c++; c < d && nums[c] == nums[c - 1]; c++) ; // 跳过重复数字 for (d--; d > c && nums[d] == nums[d + 1]; d--) ; // 跳过重复数字 } } } } return ans; } }
python3 解法, 执行用时: 64 ms, 内存消耗: 16 MB, 提交时间: 2023-07-15 09:09:34
class Solution: def fourSum(self, nums: List[int], target: int) -> List[List[int]]: nums.sort() ans = [] n = len(nums) for a in range(n - 3): # 枚举第一个数 x = nums[a] if a and x == nums[a - 1]: # 跳过重复数字 continue if x + nums[a + 1] + nums[a + 2] + nums[a + 3] > target: # 优化一 break if x + nums[-3] + nums[-2] + nums[-1] < target: # 优化二 continue for b in range(a + 1, n - 2): # 枚举第二个数 y = nums[b] if b > a + 1 and y == nums[b - 1]: # 跳过重复数字 continue if x + y + nums[b + 1] + nums[b + 2] > target: # 优化一 break if x + y + nums[-2] + nums[-1] < target: # 优化二 continue # 双指针枚举第三个数和第四个数 c = b + 1 d = n - 1 while c < d: s = x + y + nums[c] + nums[d] # 四数之和 if s > target: d -= 1 elif s < target: c += 1 else: # s == target ans.append([x, y, nums[c], nums[d]]) c += 1 while c < d and nums[c] == nums[c - 1]: # 跳过重复数字 c += 1 d -= 1 while d > c and nums[d] == nums[d + 1]: # 跳过重复数字 d -= 1 return ans
python3 解法, 执行用时: 84 ms, 内存消耗: 14.7 MB, 提交时间: 2022-07-28 15:28:12
class Solution: def fourSum(self, nums: List[int], target: int) -> List[List[int]]: quadruplets = list() if not nums or len(nums) < 4: return quadruplets nums.sort() length = len(nums) for i in range(length - 3): if i > 0 and nums[i] == nums[i - 1]: continue if nums[i] + nums[i + 1] + nums[i + 2] + nums[i + 3] > target: break if nums[i] + nums[length - 3] + nums[length - 2] + nums[length - 1] < target: continue for j in range(i + 1, length - 2): if j > i + 1 and nums[j] == nums[j - 1]: continue if nums[i] + nums[j] + nums[j + 1] + nums[j + 2] > target: break if nums[i] + nums[j] + nums[length - 2] + nums[length - 1] < target: continue left, right = j + 1, length - 1 while left < right: total = nums[i] + nums[j] + nums[left] + nums[right] if total == target: quadruplets.append([nums[i], nums[j], nums[left], nums[right]]) while left < right and nums[left] == nums[left + 1]: left += 1 left += 1 while left < right and nums[right] == nums[right - 1]: right -= 1 right -= 1 elif total < target: left += 1 else: right -= 1 return quadruplets