// 454.四数相加II
package main
import "fmt"
func fourSumCount(nums1 []int, nums2 []int, nums3 []int, nums4 []int) int {
count := 0 //统计总共出现的次数
hash := make(map[int]int, 0) //key:a+b value:a+b出现的次数
for _, v1 := range nums1 { //遍历nums1 a
for _, v2 := range nums2 { //遍历nums2 b
hash[v1+v2]++ //统计a+b出现的次数
}
}
for _, v3 := range nums3 {
for _, v4 := range nums4 {
target := 0 - (v3 + v4) //查找a+b是否存在
if s, ok := hash[target]; ok {
count += s //注意这里加的是value的值
}
}
}
return count
}
func main() {
nums1 := []int{1, 2}
nums2 := []int{-2, -1}
nums3 := []int{-1, 2}
nums4 := []int{0, 2}
res := fourSumCount(nums1, nums2, nums3, nums4)
fmt.Printf("res: %v\n", res) //res: 2
}
// 383.赎金信
package main
import "fmt"
func canConstruct(ransomNote string, magazine string) bool {
hash := make([]int, 26)
for _, v := range ransomNote { //统计目标字符串各个元素出现次数
hash[v-rune('a')]++
}
for _, v := range magazine { //用字典字符串各个元素与目标字符串的相减
hash[v-rune('a')]--
}
for _, v := range hash { //若结果有正数,说明字典字符串不可构成目标字符串
if v > 0 {
return false
}
}
return true
}
func main() {
s1 := "aa"
s2 := "abb"
b := canConstruct(s1, s2)
fmt.Printf("b: %v\n", b) //b: false
}
// 5.三数之和
package main
import (
"fmt"
"sort"
)
func threeSum(nums []int) [][]int {
res := [][]int{} //初始化一个二维切片存放结果 或者 res:=make([][]int,0)
sort.Ints(nums) //对数组元素进行升序排序 注意排序函数的写法
for i, v := range nums {
if v > 0 { //如果最小的数大于0则停止遍历
break
}
//对i进行去重
if i > 0 && nums[i-1] == nums[i] {
continue
}
left := i + 1
right := len(nums) - 1
for right > left { //由于这里需要三个元素,因此left!=right
n1, n2, n3 := nums[i], nums[left], nums[right]
s := n1 + n2 + n3
if s > 0 {
right--
} else if s < 0 {
left++
} else {
res = append(res, []int{n1, n2, n3}) //先收获结果
//对nums[left]和nums[right]去重,必须放在收获结果的后面
for right > left && n2 == nums[left] {
left++
}
for right > left && n3 == nums[right] {
right--
}
}
}
}
return res
}
func main() {
nums := []int{-1, 0, 1, 2, -1, -4}
res := threeSum(nums)
fmt.Printf("res: %v\n", res) //res: [[-1 -1 2] [-1 0 1]]
}
// 18.四数之和
package main
import (
"fmt"
"sort"
)
func fourSum(nums []int, target int) [][]int {
if len(nums) < 4 { //如果数组长度小于4返回空
return nil
}
res := [][]int{} //二维切片初始化
sort.Ints(nums) //对数组升序排序
for k := 0; k < len(nums)-3; k++ {
n1 := nums[k]
//k剪枝
if n1 > 0 && target > 0 && n1 > target {
break
}
//k去重
if k > 0 && nums[k-1] == n1 {
continue
}
for i := k + 1; i < len(nums)-2; i++ {
n2 := nums[i]
//i剪枝
if n1+n2 > 0 && target > 0 && n1+n2 > target {
break
}
//i去重
if i > k+1 && nums[i-1] == n2 {
continue
}
left := i + 1
right := len(nums) - 1
for right > left {
n3, n4 := nums[left], nums[right] //注意n3,n4赋值要在for循环里面
s := n1 + n2 + n3 + n4 //求和也在for循环里面
if s > target {
right--
} else if s < target {
left++
} else {
res = append(res, []int{n1, n2, n3, n4})
//nums[left]、nums[right]去重
for right > left && nums[left] == n3 {
left++
}
for right > left && nums[right] == n4 {
right--
}
}
}
}
}
return res
}
func main() {
nums := []int{1, 0, -1, 0, -2, 2}
res := fourSum(nums, 0)
fmt.Printf("res: %v\n", res) //res: [[-2 -1 1 2] [-2 0 0 2] [-1 0 0 1]]
}