454. 四数相加 II - 力扣(LeetCode)
四数和两数之和相比还是有些变化
func fourSumCount(nums1 []int, nums2 []int, nums3 []int, nums4 []int) (ans int) {
countAB := map[int]int{}
for _, v := range nums1 {
for _, w := range nums2 {
countAB[v+w]++
}
}
for _, v := range nums3 {
for _, w := range nums4 {
ans += countAB[-v-w]
}
}
return
}
383. 赎金信 - 力扣(LeetCode)
赎金信用一个数组做哈希即可
func canConstruct(ransomNote string, magazine string) bool {
words := make([]int, 26)
for i := 0; i < len(magazine); i++ {
words[magazine[i]-'a']++
}
for i := 0; i < len(ransomNote); i++ {
words[ransomNote[i]-'a']--
}
for i := 0; i < 26; i++ {
if words[i] < 0 {
return false
}
}
return true
}
15. 三数之和 - 力扣(LeetCode)
枚举循环好复杂
func threeSum(nums []int) [][]int {
n := len(nums)
sort.Ints(nums)
ans := make([][]int, 0)
// 枚举 a
for first := 0; first < n; first++ {
// 如果和上一个数字相同,就跳过
if first > 0 && nums[first] == nums[first-1] {
continue
}
third := n-1
target := -1 * nums[first]
// 枚举 b
for second := first + 1; second < n; second++ {
// 需要和上一次枚举的数不同
if second > first +1 && nums[second] == nums[second-1] {
continue
}
for second < third && nums[second] + nums[third] > target {
third--
}
if second == third {
break
}
if nums[second] + nums[third] == target {
ans = append(ans, []int{nums[first], nums[second], nums[third]})
}
}
}
return ans
}
18. 四数之和 - 力扣(LeetCode)
不想再写这种循环了
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
}