S2 icon indicating copy to clipboard operation
S2 copied to clipboard

0015.3 Sum | LeetCode Cookbook

Open halfrost opened this issue 4 years ago • 14 comments

https://books.halfrost.com/leetcode/ChapterFour/0001~0099/0015.3Sum/

halfrost avatar Aug 21 '20 05:08 halfrost

看了半天上面大部分是考虑重复数字的,只有下面一点才是普通情况的计算,看来题目稍微改动一点,复杂度大大增加

			c := 0 - uniqNums[i] - uniqNums[j]
			if c > uniqNums[j] && counter[c] > 0 {
				res = append(res, []int{uniqNums[i], uniqNums[j], c})
			}

fakeyanss avatar Sep 09 '20 03:09 fakeyanss

看了半天上面大部分是考虑重复数字的,只有下面一点才是普通情况的计算,看来题目稍微改动一点,复杂度大大增加

			c := 0 - uniqNums[i] - uniqNums[j]
			if c > uniqNums[j] && counter[c] > 0 {
				res = append(res, []int{uniqNums[i], uniqNums[j], c})
			}

@fakeYanss 是的~你可以顺着 Two-sum 开始做,一直做到 Four-sum,会有这种感受。four-sum 感觉没有这一题难。

halfrost avatar Sep 09 '20 13:09 halfrost

都做了,感觉最终还得走递归的路子,不然到kSum,k变大起来,枚举可就不好写了

fakeyanss avatar Sep 14 '20 12:09 fakeyanss

都做了,感觉最终还得走递归的路子,不然到kSum,k变大起来,枚举可就不好写了

@fakeYanss 是的,K 大了以后还是要 DFS 搞。

halfrost avatar Sep 14 '20 14:09 halfrost

居然用了sort包!!!

hujun2020 avatar Jul 21 '21 09:07 hujun2020

居然用了sort包!!!

@hujun2020 好像没说不能用 😅

halfrost avatar Jul 21 '21 11:07 halfrost

这道题的时间最优解应该是哈希集合,我用Python编程 hash有800ms, 而双指针加排序只有1900ms

fjljlzy avatar Sep 01 '21 05:09 fjljlzy

if index > 1 && nums[index] == nums[index-1] { start = index - 1 } 第一个解法 里为什么是start = index - 1,而不是index--呢?

wang-dahua avatar Oct 15 '21 09:10 wang-dahua

@wang-dahua 外层的 index 遍历的是大循环,在这个循环里面 start 和 end 是滑动窗口的 2 个指针。在窗口滑动过程中,不能改变外层 index 的值。如果改变了 index,就导致当前滑动窗口基于的初始状态发生变化了,答案就不对了。

halfrost avatar Oct 22 '21 05:10 halfrost

nums已经排序过了,所以当nums[start] > 0时,后面都不需要判断了,可以直接break,进入下一个index

Kimentanm avatar Dec 16 '21 03:12 Kimentanm

我很愚蠢,下面这一步不是很理解:

        // 这一步还不是很了解
        if index > 1 && nums[index] == nums[index-1] {
            start = index - 1
        }

guowei-gong avatar Feb 05 '22 12:02 guowei-gong

@guowei-gong 我很愚蠢,下面这一步不是很理解:

        // 这一步还不是很了解
        if index > 1 && nums[index] == nums[index-1] {
            start = index - 1
        }

这里是结合下面 for start < index && end > index 循环发挥作用的。此时 index 和 index -1 的元素相等,需要直接跳过,就把 start 重置成 index -1,这样在下面的循环里就会直接命中 start > 0 && nums[start] == nums[start-1] 这个条件跳出循环了

chidaobanjiu avatar Jul 05 '22 04:07 chidaobanjiu

我很愚蠢,下面这一步不是很理解:

        // 这一步还不是很了解
        if index > 1 && nums[index] == nums[index-1] {
            start = index - 1
        }

@guowei-gong 你不愚蠢。大家都是这样过来的。很抱歉回复你的消息回复慢了。你这个问题的答案,在你下面一楼那个同学回复了。

halfrost avatar Jul 05 '22 18:07 halfrost

解法一会不会有点繁琐,有几处看不太懂。换成这样会不会直观点?(速度内存结果貌似都差不多,刷题新人若有误见谅)

func threeSum(nums []int) [][]int {
	//nums排序
	sort.Ints(nums)
	ans := make([][]int, 0)

	for i, v := range nums {
		//若是重复数字,跳过此次过程判断下一个数字
		if i > 0 && v == nums[i-1] {
			continue
		}

		//t_sum是剩下两个数字和的值
		t_sum := 0 - v

		//左右指针开始地点
		left := i + 1
		right := len(nums) - 1

		for left < right {
			if nums[left]+nums[right] < t_sum {
				left++
			} else if nums[left]+nums[right] > t_sum {
				right--
			} else {
				//找到一组,装进答案继续,移动左指针往右一次
				ans = append(ans, []int{v, nums[left], nums[right]})
				left++

				//再次循环判断移动左指针来跳过重复数字的地方;不会增加复杂度因为父循环同样检查left<right
				for nums[left] == nums[left-1] && left < right {
					left++
				}
			}
		}
	}
	return ans
}

unclefined avatar Jul 29 '22 03:07 unclefined