每日打卡
一、连续子数组的最大和
思路
这是一道简单线性 DP 题。
定义 f[i] 为考虑以 nums[i] 为结尾的子数组的最大值。不失一般性的考虑 f[i] 如何转移。 f[i] = max(f[i-1]+nums[i], nums[i]) f[i]表示当前下标及往前的连续子数组最大和, 等于f[i-1]+当前下标元素,与当前下标元素的较大者 也就是说,要么取从当前下标元素开始累加,要么包含前面的元素
class Solution {
public int maxSubArray(int[] nums) {
int n = nums.length;
int[] f = new int[n];
f[0] = nums[0];
int ans = f[0];
for (int i = 1; i < n; i++) {
f[i] = Math.max(nums[i], f[i - 1] + nums[i]);
ans = Math.max(ans, f[i]);
}
return ans;
}
}
题目来源
二、 最长递增子序列
思路
动态规划中,通过线性遍历来计算 dp 的复杂度无法降低;每轮计算中,需要通过线性遍历 [0,k) 区间元素来得到 dp[k] 。我们考虑:是否可以通过重新设计状态定义,使整个 dp 为一个排序列表;这样在计算每个 dp[k] 时,就可以通过二分法遍历 [0,k) 区间元素,将此部分复杂度由 O(N) 降至 O(logN)
class Solution {
public int lengthOfLIS(int[] nums) {
int[] tails = new int[nums.length];
int res = 0;
for(int num : nums) {
int i = 0, j = res;
while(i < j) {
int m = (i + j) / 2;
if(tails[m] < num) i = m + 1;
else j = m;
}
tails[i] = num;
if(res == j) res++;
}
return res;
}
}
题目来源
三、最长递增子序列
思路
每一位 i 能否放置房子的决策仅与前一位 i-1 是否有房子有关 我们定义 f[i][2] 为 第 i 位置是否有房子的方案数, f[i][0] 表示没房子, f[i][1] 表示有房子
- i 位置没有房子 不管 i-1 是否有房子都可以转移
f[i][0] = (f[i - 1][1] + f[i - 1][0]) % MOD; - i 位置放置房子 则需要 i-1 处无房子
f[i][1] = f[i - 1][0]; 由于路两边独立放置, 最后只要取个 f[n] 两个情况和 的平方即可 记得用long 和 取MOD
class Solution {
int MOD = (int) 1e9 + 7;
public int countHousePlacements(int n) {
long[][] f = new long[n + 1][2];
f[0][0] = 1;
for (int i = 1; i <= n; i++) {
f[i][0] = (f[i - 1][1] + f[i - 1][0]) % MOD;
f[i][1] = f[i - 1][0];
}
long res = 0;
res = (f[n][0] + f[n][1]) * (f[n][0] + f[n][1]) % MOD;
return (int) res;
}
}
总结
提示:这里对文章进行总结: 例如:以上就是今天要讲的内容,本文仅仅简单介绍了pandas的使用,而pandas提供了大量能使我们快速便捷地处理数据的函数和方法。
|