字符串中最多数目的子序列
难度:
标签:
题目描述
代码结果
运行时间: 82 ms, 内存: 16.6 MB
/*
题目思路:
1. 使用流的方式,计算当前字符串中 pattern[0] 和 pattern[1] 出现的次数。
2. 通过流的 map 和 reduce 操作,计算插入后 pattern 出现的次数。
*/
import java.util.stream.IntStream;
public class Solution {
public int maxPatternSubsequence(String text, String pattern) {
char p1 = pattern.charAt(0), p2 = pattern.charAt(1);
int count1 = 0, count2 = 0;
count2 = (int) text.chars().filter(c -> c == p2).count();
// 使用流计算最大 pattern 出现次数
int maxCount = IntStream.range(0, text.length())
.map(i -> {
if (text.charAt(i) == p1) {
count1++;
} else if (text.charAt(i) == p2) {
count2--;
}
return count1 + count2;
})
.max()
.orElse(count1 + count2);
// 考虑插入到字符串末尾的情况
maxCount = Math.max(maxCount, count1 + count2);
return maxCount;
}
}
解释
方法:
该题解通过遍历字符串text,统计模式pattern中第一个字符x和第二个字符y的出现次数以及可以形成的子序列数量。特别注意的是,若x和y相同,即pattern由两个相同的字符组成,其处理逻辑不同:直接计算所有可能位置插入新字符后的子序列数量。主要步骤为:1. 如果x和y相同,计算插入后的字符数量,利用组合公式计算可形成的子序列数。2. 如果x和y不同,遍历text,每次遇到x,增加cntx;遇到y时,将cntx累加到结果ret中,并增加cnty。最后,考虑插入一个字符后,取cntx和cnty中的最大值加到ret中,这反映了通过插入一个字符(x或y)可以额外增加的子序列数量。
时间复杂度:
O(n)
空间复杂度:
O(1)
代码细节讲解
🦆
在算法中,如何确保在遍历text时统计的子序列不会重复计数?
▷🦆
算法对于插入字符的位置是如何考虑的,是否有特定的最优位置或是随意插入就可以?
▷🦆
当pattern由两个相同字符组成时,为什么使用组合数公式`(cnt - 1) * cnt // 2`来计算子序列总数?
▷🦆
在处理x和y不同的情况时,为什么最后选择`max(cntx, cnty)`来计算通过插入一个字符可能增加的子序列数?
▷