Add solution 1668、1669、1670、1672、1673

This commit is contained in:
YDZ
2020-12-16 03:08:19 +08:00
parent 2e796fe70e
commit e85f3236f4
30 changed files with 1266 additions and 428 deletions

View File

@@ -56,7 +56,7 @@ Explanation: It is impossible to distribute nums into 3 subsets where no two ele
- 读完题最直白的思路就是 DFS。做法类似第 77 题。这里就不赘述了。可以见第 77 题题解。
- 这一题还需要用到贪心的思想。每次取数都取最小的数。这样可以不会让最大数和最小数在一个集合中。由于每次取数都是取最小的,那么能保证不兼容性每次都尽量最小。于是在 order 数组中定义取数的顺序。然后再把数组从小到大排列。这样每次按照 order 顺序取数,都是取的最小值。
- 正常的 DFS 写完提交,耗时是很长的。大概是 1532ms。如何优化到极致呢这里需要加上 2 个剪枝条件。第一个剪枝条件比较简单,如果累计 sum 比之前存储的 res 大,那么直接 return不需要继续递归了。第二个剪枝条件就非常重要了可以一下子减少很多次递归。每次取数产生新的集合的时候要从第一个最小数开始取一旦取了后面就不需要再循环递归了。举个例子[1,2,3,4],第一个数如果取 2集合可以是 [[2,3],[1,4]] 或 [[2,4], [1,3]], 这个集合和[[1,3],[2,4]]、[[1,4], [2,3]] 情况一样。可以看到如果取出第一个最小值以后,后面的循环是不必要的了。所以在取下标为 0 的数的时候,递归到底层以后,返回就可以直接 break不用接下去的循环了接下去的循环和递归是不必要的。加了这 2 个剪枝条件以后,耗时就变成了 0ms 了。beats 100%
- 正常的 DFS 写完提交,耗时是很长的。大概是 1532ms。如何优化到极致呢这里需要加上 2 个剪枝条件。第一个剪枝条件比较简单,如果累计 sum 比之前存储的 res 大,那么直接 return不需要继续递归了。第二个剪枝条件就非常重要了可以一下子减少很多次递归。每次取数产生新的集合的时候要从第一个最小数开始取一旦取了后面就不需要再循环递归了。举个例子[1,2,3,4],第一个数如果取 2集合可以是 [[2,3],[1,4]] 或 [[2,4], [1,3]], 这个集合和[[1,3],[2,4]]、[[1,4], [2,3]] 情况一样。可以看到如果取出第一个最小值以后,后面的循环是不必要的了。所以在取下标为 0 的数的时候,递归到底层以后,返回就可以直接 break不用接下去的循环了接下去的循环和递归是不必要的。每组组内的顺序我们并不关心,只要最大值和最小值在分组内即可。另外组间顺序我们也不关心。所以可以把排列问题 O(n!) 时间复杂度降低到组合问题 O(2^n)。加了这 2 个剪枝条件以后,耗时就变成了 0ms 了。beats 100%
## 代码