目录
一:四数相加Ⅱ
题目链接:四数相加Ⅱ
思路:这道题本来是没啥思路的,只想到了四重循环,但是有感觉不太现实,所以看了看答案,答案用hash表的方式,把四重循环转换为二重循环了,其实这是一个挺好的思路,以后就要记住这个思路。
func fourSumCount(nums1 []int, nums2 []int, nums3 []int, nums4 []int) int {
hashTable := make(map[int]int)
count := 0
for _,v1 := range nums1{
for _,v2 := range nums2{
hashTable[v1+v2]++
}
}
for _,v3 := range nums3{
for _,v4 := range nums4{
count += hashTable[-v3-v4]
}
}
return count
}
二:赎金信
题目链接:赎金信
思路:这道题思路就比较正常了,就是用hash表完成的,先将magazine里面的字符拆解出来,存到hash表中,最后遍历另一个字符串然后对hash表进行减法操作。
func canConstruct(ransomNote string, magazine string) bool {
hashTable := make(map[rune]int)
for _,v := range magazine {
hashTable[v]++
}
for _,v := range ransomNote {
hashTable[v]--
if hashTable[v] < 0 {
return false
}
}
return true
}
三:三数之和
题目链接:三数之和
思路:先进行排序,再利用双指针法查找相加数组为0的组合,这道题的难点在于怎么样去去重,去除重复的数组。
import "sort"
func threeSum(nums []int) [][]int {
sort.Ints(nums)
results := make([][]int,0)
length := len(nums)
for i:=0;i<length-2; {
left := i+1
right := length-1
for left < right {
if nums[i] + nums[left] + nums[right] == 0 {
results = append(results,[]int{nums[i] , nums[left] , nums[right]})
n1,n2 := nums[left] ,nums[right]
for left<right && n1 == nums[left]{ //在内层循环,双指针之间的进行去重,如果相等就跳过这次查找
left++
}
for left<right && n2 == nums[right]{
right--
}
continue
}
if nums[i] + nums[left] + nums[right] > 0 {
right--
continue
}
left++
}
n3 := nums[i]
i++
for i < length - 2 && nums[i] == n3 {//外层循环,如果第一层就重复了,则直接跳过
//关键点:要这个外层数据使用完之后再去重,不要直接上来就去重
i++
}
}
return results
}
这道题大家也很容易想到利用回溯法,回溯法可以剪枝操作去重,但是回溯法是超时的。代码如下:
var res [][]int
func threeSum(nums []int) [][]int {
res = make([][]int,0)
sort.Ints(nums)
traceBack(nums,[]int{},3,0)
return res
}
func traceBack(nums []int,path []int,n int,sum int) {
if n ==0 && sum == 0 {
temp := make([]int,len(path))
copy(temp,path)
res = append(res,temp)
return
}
if n < 0 {
return
}
for i:=0;i<len(nums);i++ {
//去重
if i>0 && nums[i-1] == nums[i] {
continue
}
path = append(path,nums[i])
traceBack(nums[i+1:],path,n-1,sum+nums[i])
path = path[:len(path)-1]
}
}
四:四数之和
题目链接:四数之和
思路:和三数之和一样的道理,只是多了一层循环,这里用到双指针所作的优化是把O(n4)的复杂度优化成了O(n3),三数之和同理。
import "sort"
func fourSum(nums []int, target int) [][]int {
sort.Ints(nums)
length := len(nums)
results := make([][]int,0)
for i:=0;i<length - 3; {
for j:=i+1;j<length - 2; {
left := j+1
right := length-1
for left < right {
if nums[i] + nums[j] + nums[left] + nums[right] == target {
results = append(results,[]int{nums[i],nums[j],nums[left],nums[right]})
n1,n2 := nums[left],nums[right]
for left<right && n1 == nums[left] {
left++
}
for left<right && n2 == nums[right] {
right--
}
continue
}
if nums[i] + nums[j] + nums[left] + nums[right] < target {
left++
}
if nums[i] + nums[j] + nums[left] + nums[right] > target {
right--
}
}
n3 := nums[j]
j++
for j < length-2 && n3 == nums[j] {
j++
}
}
n4 := nums[i]
i++
for i < length-3 && n4 == nums[i] {
i++
}
}
return results
}