- 代码随想录 (programmercarl.com)
-
第一印象
- 暴力方法来遍历四个数组的话,时间复杂度会达到O(n^4)。也许可以使用哈希法存储两层或三层的方法来记录值。
-
讲解观后感
- 本题是分开的四个数组。可以分为个每两个一组,用O(n^2)存储前两组的和以及出现的次数。构建出返回值
count,再遍历后两组的和,能够使a+b+c+d=0满足时遍增加count。
-
解题代码
-
func fourSumCount(nums1 []int, nums2 []int, nums3 []int, nums4 []int) int {
AB := make(map[int]int)
for _,m:=range nums1 {
for _,n:=range nums2 {
AB[m+n] += 1
}
}
count := 0
for _,o:=range nums3 {
for _,p:=range nums4 {
if _,ok:=AB[0-o-p];ok {
count += AB[0-o-p]
}
}
}
return count
}
-
383赎金信
- 代码随想录 (programmercarl.com)
-
第一印象
- 这道题方法类似与《242字母异位词》,只需要存储
magzine的字母及出现次数,再减去信件中的字母,不为-1即视为true。
-
解题代码
-
func canConstruct(ransomNote string, magazine string) bool {
set := [26]int{}
for _,i:= range magazine {
set[i-'a']++
}
for _,s:= range ransomNote {
set[s-'a']--
if set[s-'a'] <0 {
return false
}
}
return true
}
-
15三数之和
- 代码随想录 (programmercarl.com)
-
第一印象
- 暴力的方法貌似是可以用三次遍历找出符合条件的组合,然后再进行去重,然而在思考去重逻辑的过程中发现很难实现。
-
讲解观后感
- 这道题目使用哈希法并不十分合适,因为在去重的操作中有很多细节需要注意,在面试中很难直接写出没有bug的代码。而且使用哈希法 在使用两层for循环的时候,能做的剪枝操作很有限,虽然时间复杂度是O(n^2),也是可以在leetcode上通过,但是程序的执行时间依然比较长 。双指针法的方式更合适
-
遇到问题
- 忘记第一个数字去重代码,结果出现重复
- 补充以下代码段后解决
-
if i > 0 && n1 == nums[i-1] {
continue
}
- 第二三个字母去重时,指针越界:
-
l, r := i+1,len(nums)-1
for l < r {
n2, n3 := nums[l], nums[r]
if n1 + n2 + n3 == 0 {
for l < r && nums[l] == nums[l+1] {
l++
}
for l < r && nums[r] == nums[r-1] {
r--
}
ans = append(ans,[]int{n1,n2,n3})
} else if n1 + n2 + n3 < 0 {
l++
} else {
r--
}
}
- 解决方法:将
nums[l+1]及 nums[r-1]替换为n2及n3
-
解题代码
-
func threeSum(nums []int) [][]int {
ans := [][]int{}
sort.Ints(nums)
for i:=0;i<len(nums)-2;i++ {
n1 := nums[i]
if n1>0 {
break
}
if i > 0 && n1 == nums[i-1] {
continue
}
l, r := i+1,len(nums)-1
for l < r {
n2, n3 := nums[l], nums[r]
if n1 + n2 + n3 == 0 {
for l < r && nums[l] == n2 {
l++
}
for l < r && nums[r] == n3 {
r--
}
ans = append(ans,[]int{n1,n2,n3})
} else if n1 + n2 + n3 < 0 {
l++
} else {
r--
}
}
}
return ans
}
-
18四数之和
- 代码随想录 (programmercarl.com)
-
第一印象
- 方法类似于《三数之和》的方法,只不过是多套一层循环,三数之和的复杂度是O(n^2),四数之和的复杂度为O(n^3)
- 第二层的剪枝操作可以优化为
-
if (nums[k] + nums[i] > target && nums[i] >= 0) {
break
}
-
解题代码
-
func fourSum(nums []int, target int) [][]int {
if len(nums) < 4 {
return nil
}
sort.Ints(nums)
var res [][]int
for i := 0; i < len(nums)-3; i++ {
n1 := nums[i]
if n1 > target && (n1>=0 || target>=0) {
break
}
if i > 0 && n1 == nums[i-1] {
continue
}
for j := i + 1; j < len(nums)-2; j++ {
n2 := nums[j]
if j > i+1 && n2 == nums[j-1] {
continue
}
if (nums[i] + nums[j] > target && nums[j] >= 0) {
break
}
l := j + 1
r := len(nums) - 1
for l < r {
n3 := nums[l]
n4 := nums[r]
sum := n1 + n2 + n3 + n4
if sum < target {
l++
} else if sum > target {
r--
} else {
res = append(res, []int{n1, n2, n3, n4})
for l < r && n3 == nums[l+1] {
l++
}
for l < r && n4 == nums[r-1] {
r--
}
r--
l++
}
}
}
}
return res
}