小 D 字符串变换问题
一、题目分析
本题要求对仅由 "abc" 三种字母组成的字符串进行特定变换操作,并重复 k 次后得到最终字符串。关键在于理解每次变换的规则,即 'a' 变为 'bc','b' 变为 'ca','c' 变为 'ab',并且要高效地处理重复 k 次的变换过程。需要考虑如何在每次变换时准确地更新字符串内容,以及如何避免不必要的字符串操作开销。
二、题解思路
- 首先创建两个
StringBuilder对象sb和sb1,sb初始化为输入字符串s,sb1用于临时存储每次变换后的结果。 - 通过外层循环
k次来控制变换的重复次数。 - 在内层循环中,遍历当前
sb中的每个字符。根据字符是 'a'、'b' 还是 'c',将其对应的变换结果追加到sb1中。这里没有直接使用sb.replace方法,是因为其在字符串较长且多次替换时性能较差,而使用StringBuilder追加的方式效率更高。 - 当内层循环结束,即一次变换完成后,将
sb清空,并把sb1的内容赋值给sb,然后清空sb1,为下一次变换做准备。 - 最后返回经过
k次变换后的sb所表示的字符串。
public static String solution(String s, int k) {
// write code here
StringBuilder sb = new StringBuilder(s);
StringBuilder sb1 = new StringBuilder();
for (int i = 0; i < k; i++) {
int size = sb.length();
for (int j = 0; j < size; j++) {
if (sb.charAt(j) == 'a') {
// sb.replace(j, j+1, "bc");
sb1.append("bc");
} else if (sb.charAt(j) == 'b') {
sb1.append("ca");
} else if (sb.charAt(j) == 'c') {
sb1.append("ab");
}
}
// System.out.print(sb1.toString());
sb.delete(0, sb.length());
sb.append(sb1.toString());
sb1.delete(0, sb1.length());
}
return sb.toString();
}
小 M 目标分数确定问题
一、题目分析
本题给定一个分数数组,要求根据特定规则确定小 M 的目标分数。规则是如果分数中有三个或以上不同的分数,返回其中第三大的分数;如果不同的分数只有两个或更少,则选择最大的分数作为目标。需要对分数数组进行去重处理,并能方便地获取到不同分数的排序信息。
二、题解思路
- 创建一个
HashSet对象set用于对分数数组进行去重,同时创建一个大顶堆PriorityQueue对象pq,通过自定义比较器(a,b)->b - a实现大顶堆功能,用于存储去重后的分数并方便获取最大分数。 - 遍历分数数组
nums,如果当前分数不在set中,则将其加入pq并添加到set中,这样就实现了去重并将分数加入大顶堆的操作。 - 然后判断
pq的大小,如果pq中不同分数的数量小于等于 2,则直接返回堆顶元素,即最大分数。 - 如果
pq中不同分数数量大于 2,则先从堆顶弹出两个最大分数,此时堆顶元素即为第三大分数,将其弹出并返回作为目标分数。
public static int solution(int n, int[] nums) {
Set<Integer> set = new HashSet<>();
PriorityQueue<Integer> pq = new PriorityQueue<>((a,b)->b-a);
for(int i = 0;i<n;i++){
if(!set.contains(nums[i])){
pq.add(nums[i]);
set.add(nums[i]);
}
}
if(pq.size()<=2)return pq.poll();
else{
for(int i = 0;i<2;i++){
pq.poll();
}
return pq.poll();
}
}