引言
题目链接:https://leetcode.com/problems/4sum/description/
题目大意
给出一个包含n个整数的数组nums以及一个目标值target,这个数组是否存在有元素a,b,c,d使得 a + b + c + d = target,找出所有满足条件的a,b,c,d的组合
- Example
1 2 3 4 5 6 7 8 |
Given array nums = [1, 0, -1, 0, -2, 2], and target = 0. A solution set is: [ [-1, 0, 0, 1], [-2, -1, 1, 2], [-2, 0, 0, 2] ] |
题解
这题其实是第15题的变种,相信看了这篇题解举一反三很容易能拿下这题,LeetCode:15.3Sum题解,Click Here!
这道题由于是求4个数的目标值,所以需要滚动查询的数字由15题的两个变成了3个,很暴力的一个方法,在原来的循环上再加一层循环,内部继续再剩余数组上枚举两个数求和即可
Hint:
如何优雅的避免重复也是一个坑,外层两个循环都需要判断下当前选取的数字和上一次是不是相同的,相同的直接跳过,内层俩数字枚举时2也注意判断即可(千万别忘了某一层少写了这个条件,不然美滋滋~)
复杂度
时间复杂度 O(n^3)
空间复杂度 O(1)
AC代码
c++版本
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 |
class Solution { public: vector<vector<int>> fourSum(vector<int> &nums, int target) { vector<vector<int>> ans; std::sort(nums.begin(), nums.end()); const int len = nums.size(); for (int i = 0; i < len - 3; ++i) { if (target > 0 && nums[i] > target) { break; } if (i > 0 && nums[i] == nums[i - 1]) { continue; } for (int j = i + 1; j < len - 2; ++j) { if (target > 0 && nums[i] + nums[j] > target) { break; } if (j > i + 1 && nums[j] == nums[j - 1]) { continue; } int midIndex = j + 1; int lastIndex = len - 1; while (midIndex < lastIndex) { int curSum = nums[i] + nums[j] + nums[midIndex] + nums[lastIndex]; if (curSum == target) { ans.push_back({nums[i], nums[j], nums[midIndex++], nums[lastIndex--]}); while (midIndex < lastIndex && nums[midIndex] == nums[midIndex - 1]) { ++midIndex; } while (midIndex < lastIndex && nums[lastIndex] == nums[lastIndex + 1]) { --lastIndex; } } else if (curSum > target) { --lastIndex; } else { ++midIndex; } } } } return ans; } }; |
go版本
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
func fourSum(nums []int, target int) [][]int { var ans [][]int lens := len(nums) sort.Sort(sort.IntSlice(nums)) for i := 0; i < lens-3; i++ { if i > 0 && nums[i] == nums[i-1] { continue } for j := i + 1; j < lens-2; j++ { if j > i+1 && nums[j] == nums[j-1] { continue } midIndex, lastIndex := j+1, lens-1 for midIndex < lastIndex { curSum := nums[i] + nums[j] + nums[midIndex] + nums[lastIndex] if curSum == target { ans = append(ans, []int{nums[i], nums[j], nums[midIndex], nums[lastIndex]}) midIndex++ for midIndex < lastIndex && nums[midIndex] == nums[midIndex-1] { midIndex++ } lastIndex-- for midIndex < lastIndex && nums[lastIndex] == nums[lastIndex+1] { lastIndex-- } } else if curSum > target { lastIndex-- } else { midIndex++ } } } } return ans } |