持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第11天,点击查看活动详情
前言
小白算法比较菜,希望能激励我每日更新,从leetcode第一题开始,2022年目标300题,记录从0到1的全过程!!
力扣第 312 场周赛
力扣第 312 场周赛-力扣
a了三题,2000以内,小上10几分。第三题有点离谱,给的例子太基础了,修改了代码之后根本试不出来对不对,错八次可真是,,,,不罚时的话能到1150名呢(当然只能想想)
这个第四题,,,当又是暴力又是咋,反正就是没做出来。后来看灵山的视频,也没太看懂,经过提醒尝试了一下dp,提交能通过,不是每次都能通过。还是有可能会超时。
2430. 对字母串可执行的最大删除数
给你一个仅由小写英文字母组成的字符串 s 。在一步操作中,你可以:
- 删除 整个字符串 s ,或者
- 对于满足 1 <= i <= s.length / 2 的任意 i ,如果 s 中的 前 i 个字母和接下来的 i 个字母 相等 ,删除 前 i 个字母。 例如,如果 s = "ababc" ,那么在一步操作中,你可以删除 s 的前两个字母得到 "abc" ,因为 s 的前两个字母和接下来的两个字母都等于 "ab" 。
返回删除 s 所需的最大操作数。
示例 1
- 输入:s = "abcabcdabc"
- 输出:2
解释:
- 删除前 3 个字母("abc"),因为它们和接下来 3 个字母相等。现在,s = "abcdabc"。
- 删除全部字母。 一共用了 2 步操作,所以返回 2 。可以证明 2 是所需的最大操作数。
注意,在第二步操作中无法再次删除 "abc" ,因为 "abc" 的下一次出现并不是位于接下来的 3 个字母。
示例 2
- 输入:s = "aaabaab"
- 输出:4
解释:
- 删除第一个字母("a"),因为它和接下来的字母相等。现在,s = "aabaab"。
- 删除前 3 个字母("aab"),因为它们和接下来 3 个字母相等。现在,s = "aab"。
- 删除第一个字母("a"),因为它和接下来的字母相等。现在,s = "ab"。
- 删除全部字母。
一共用了 4 步操作,所以返回 4 。可以证明 4 是所需的最大操作数。
示例 3
输入: s = "aaaaa"
输出: 5
解释: 在每一步操作中,都可以仅删除 s 的第一个字母。
提示
1 <= s.length <= 4000s仅由小写英文字母组成
解析
思路其实并不难,从后往前遍历
对于i来说,如果找到能删除到j,那么就更新dp[i] = Math.max(dp[i], dp[j] + 1); 然后一直遍历到数组的最后,此时如果dp[i] 还是0的话,那就一次性全部删除,更新位dp[i] = 1;
从而一直更新到dp[0],返回dp[0]就是删除全部的最大次数了。
代码
代码确实不长,主要在字符串比较太耗时了。
class Solution {
public int deleteString(String s) {
char[] chars = s.toCharArray();
int[] dp = new int[chars.length];
// Arrays.fill(dp, 1);
dp[dp.length - 1] = 1;
int max = 0;
for (int i = dp.length - 2; i >= 0; i--) {
dp[i] = 1;
for (int j = i; j < (dp.length + i >> 1); j++) {
if (check(i, j, chars)) {
dp[i] = Math.max(dp[i], 1 + dp[j + 1]);
if (dp[i]>max) break;
}
}
max = Math.max(max,dp[i]);
}
return dp[0];
}
private boolean check(int i, int j, char[] chars) {
int l = i;
int r = j + 1;
while (l <= j) {
if (chars[l] != chars[r]) {
return false;
}
r++;
l++;
}
return true;
}
}
第一、二题连接如下
[杨小白]_leetcode_力扣第 312 场周赛-第一、二题
第三题连接如下
[杨小白]_leetcode_力扣第 312 场周赛-第三题
3.结束
前两题都不难,基本200题量的同学就可以做出来了,第三题的话,最后的方法确实很巧妙,还是得多见多写。第四题虽然没办法做出来非常快和巧妙的技巧,但是要ac还是有机会的,gogogo,刷题刷题,每天一道,三年1000道!!!!