力扣周赛第255期(上)

364 阅读1分钟

这是我参与8月更文挑战的第30天,活动详情查看:8月更文挑战

1979. 找出数组的最大公约数

截屏2021-08-30 下午9.24.16.png

思路分析

一次循环让我们可以找到最小值和最大值,然后就是计算两个值的最大公约数

计算最大公约数使用辗转相除法就可以了。。实在太简单,代码略了。

1981. 最小化目标值与所选元素的差

截屏2021-08-30 下午10.42.18.png

截屏2021-08-30 下午10.42.52.png

思路分析

如果是穷举的话,使用dfs就可以计算出所有的值,通过计算的sum - target的绝对值来依次比较,得到最小的绝对差。

这样的话时间复杂度便是指数级了,我们要怎么才能剪枝呢?

首先我们并不需要计算每一种可能,比如在计算前两行的时候,理论上有2arr[0].size()2^{arr[0].size()} 种情况,但其实可能并没有那么多,我们只需要记录dp[i][j]为前i行出现和为j的可能是否存在,就可以了。

没错,这就是一道动态规划题。

状态转移方程为:

当遍历的第i行的某节点为x时

f[i][j]=f[i][j] ∨ f[i−1][j−x]

考虑一下j的范围,动态的看,j的范围是f[i- 1]时j的最大值,加上每一行的最大值。

静态的看,就是根据

m == mat.length

n == mat[i].length

1 <= m, n <= 70

1 <= mat[i][j] <= 70

1 <= target <= 800

计算出最大值为4900

考虑到由于状态转移方程只使用f[i]和f[i - 1],因此我们是可以将其数组从n行数组压缩至一个二行数组,只是每次需要将第一行移动至第0行而已。