“Offer 驾到,掘友接招!我正在参与2022春招打卡活动,点击查看活动详情。”
一、题目描述
给你一个下标从 0 开始的字符串 text 和另一个下标从 0 开始且长度为 2 的字符串 pattern ,两者都只包含小写英文字母。
你可以在 text 中任意位置插入 一个 字符,这个插入的字符必须是 pattern[0] 或者 pattern[1] 。注意,这个字符可以插入在 text 开头或者结尾的位置。
请你返回插入一个字符后,text 中最多包含多少个等于 pattern 的 子序列 。
子序列 指的是将一个字符串删除若干个字符后(也可以不删除),剩余字符保持原本顺序得到的字符串。
示例 1:
输入: text = "abdcdbc", pattern = "ac"
输出: 4
解释:
如果我们在 text[1] 和 text[2] 之间添加 pattern[0] = 'a' ,那么我们得到 "abadcdbc" 。那么 "ac" 作为子序列出现 4 次。
其他得到 4 个 "ac" 子序列的方案还有 "aabdcdbc" 和 "abdacdbc" 。
但是,"abdcadbc" ,"abdccdbc" 和 "abdcdbcc" 这些字符串虽然是可行的插入方案,但是只出现了 3 次 "ac" 子序列,所以不是最优解。
可以证明插入一个字符后,无法得到超过 4 个 "ac" 子序列。
示例 2:
输入: text = "aabb", pattern = "ab"
输出: 6
解释:
可以得到 6 个 "ab" 子序列的部分方案为 "aaabb" ,"aaabb" 和 "aabbb" 。
提示:
1 <= text.length <= 105pattern.length == 2text和pattern都只包含小写英文字母。
二、思路分析
读懂题目后不难发现,这道题是要考察贪心:求在 text 中插入 pattern 其中一个元素后, text 中包含了 pattern 且 pattern 的元素在 text 保持原本顺序的最大数量。
因为要保持顺序,那么很明显,pattern[0] 要在 pattern[1] 之前;又因为题意要求数量最大,因此可以得出贪心最优解:要么 pattern[0] 插在 text 最前面,要么 pattern[1] 插在 text 最后面。
这样一来问题就解决了大半,但还需要注意的是,pattern 的两个字符可能都是相同的,因此插在 text 中的哪个位置都无所谓。
还剩最后一个问题,这个所谓的最大数量应该怎么计算。题目告诉我们,可以删除 text 若干个字符(也可以不删除),也就是说 text 中每个 pattern[0] 可以与其后面的每个 pattern[1] 匹配成子序列,因此只要记录 pattern[0] 的数量为 cnt,当遇到 pattern[0] 的时候 cnt++ ,当遇到 pattern[1] 的时候最大数量加上 cnt 即可满足题意。
那么在动手敲代码之前,我们再整理一下思路:
- 当
pattern两个字符都不相同的时候,分别将pattern的第一和第二个字符插在text的前面和后面,并定义count和cnt分别标识 值等于插入字符的数量和题目要返回的最大数量。然后开始遍历新的text,如果当前元素等于插入的字符,count++,如果等于另一个字符,则cnt += count。直到遍历结束,return cnt即可。 - 当
pattern两个字符都相同的时候:取一个字符出来插在text后面,遍历时如果当前元素等于插入的字符,直接将最大数量加上遍历到的插入字符的数量,同时插入字符的数量也加1,直到遍历结束即可。
三、AC 代码
function getCnt (text, a, b) {
let count = 0;
let cnt = 0;
for (let i = 0; i < text.length; i ++) {
if (text[i] === b) {
cnt += count;
} else if (text[i] === a) {
count++;
}
}
return cnt;
}
var maximumSubsequenceCount = function(text, pattern) {
const [a, b] = pattern.split('');
if (a === b) {
let cnt = 0;
let sum = 0;
text += b;
for (let i = 0; i < text.length; i ++) {
if (text[i] === a) {
sum += cnt;
cnt++;
}
}
return sum;
}
const text1 = `${a}${text}`;
const text2 = `${text}${b}`;
return Math.max(getCnt(text1, a, b), getCnt(text2, a, b));
};