LeetCode1717.删除子字符串的最大得分(Java)

题目

给你一个字符串 s 和两个整数 x 和 y 。你可以执行下面两种操作任意次。

  • 删除子字符串 "ab" 并得到 x 分。
    • 比方说,从 "cabxbae" 删除 ab ,得到 "cxbae" 。
  • 删除子字符串"ba" 并得到 y 分。
    • 比方说,从 "cabxbae" 删除 ba ,得到 "cabxe" 。

请返回对 s 字符串执行上面操作若干次能得到的最大得分。

跳转链接:LeetCode1717

解析

假设 x > y,所以在删除的过程中会出现以下情况:

    1.当出现 "aabb" 时,我们可以删除两个 “ab”,得分为 2x。

    2.当出现 “bbaa” 时,我们可以删除两个 “ba”,得分为 2y。

    3.当出现 “abab” 时,我们可以删除两个 “ab”,得分为 2x;或者删除一个 “ba” 和一个 “ab”,得分为 x + y。由于 x > y,所以我们优先删除两个 “ab”,这样得分最大。

    4.当出现 “baba” 时,我们可以删除两个 “ba”,得分为 2y;或者删除一个 “ba”和一个 “ab”,得分为x+y。由于 x > y,所以我们优先删除一个 “ba” 和一个 “ab”,这样得分最大。

    5.当出现 “caba” 等包含非 “a” 或 “b” 的字母时,我们会发现优先删除 “ab” 得分会更高。

综上,无论在什么情况下优先删除“ab”(当x > y时)总会得到更高的分数,因此我们可以考虑贪心来解题。

继续假设 x > y,因此我们优先删除“ab”。遍历字符串:

    情况1:当出现“a”时,我们用 count1 进行计数,表示当前可用于组合 “ab” 的 “a” 的个数; 

    情况2:当出现 “b” 时,如果有可用的 “a” 则得 x 分,同时 count1 减一;

    情况3:当出现 “b” 时,如果没有可用的 “a”则 count2 加一,表示可用于组合 “ba” 的 “b” 的个数;

    情况4:当出现其他字母时,我们可以将其看作一个分割线,因为出现其他字母时,前字符串与后字符串被分割成俩部分,两者之间不会出现 “ab” 或者 “ba” 的组合,所以这时我们可以将前面的字符串进行结算。由于前面的字符串中 “ab” 的情况在情况2中我们已考虑完,所以我们可以只考虑 “ba” 的情况。使用 ans += y * Math.min(count1, count2); 来计算得分,并将计数器归零。

public class Solution {

    public static int maximumGain(String s, int x, int y) {
        char a = 'a', b = 'b';
        //如果x < y,那么需要优先删除“ba”,这时我们只需要将x和y,a和b的值互换即可
        if(x < y){
            int t = x;
            x = y;
            y = t;
            a = 'b';
            b = 'a';
        }
        //count1用于记录当前可用的变量a的个数
        //count2用于记录当前可用的变量b的个数
        int count1 = 0, count2 = 0, n = s.length(), ans = 0;
        for (int i = 0; i < n; i++) {
            char ch = s.charAt(i);
            //当当前的字母与变量a相等时,直接计数,因为我们要优先删除得分大的组合
            if(ch == a){
                count1++;
            }
            else if(ch == b){
                //如果变量ch前面存在可用的变量a,则删除
                if(count1 > 0){
                    count1--;
                    ans += x;
                }
                //如果变量ch前面不存在可用的变量a,则count2累加
                else{
                    count2++;
                }
            }
            /*
            当出现“a”或“b”之外的字母时,前面已经不存在得分高的组合了,
            同时由于有其他字母分割,变量ch前面的字母与后面的字母不可能
            再组合了,所以此时应该将变量ch前的得分低的组合的得分计算出
            来并将两个计数器归零
            * */
            else{
                ans += y * Math.min(count1, count2);
                count1 = 0;
                count2 = 0;
            }
        }
        //遍历完字符串后还需要计算一次得分低的组合的得分
        ans += y * Math.min(count1, count2);
        return ans;
    }

}

### 2022年蓝桥杯Java C组比赛题目及解析 #### 比赛概述 蓝桥杯大赛是一项面向全国高校学生的科技竞赛活动,旨在推动软件开发技术的发展并培养创新型人才。其中,Java C组的比赛主要针对具有一定编程基础的学生设计,考察其算法思维能力、程序设计能力和实际解决问题的能力。 #### 题目分析与解答 以下是基于已有资料整理的部分题目及其解析: --- #### **第一题:排序字母** 该题要求对给定的一串字符按照字典序重新排列[^2]。 具体实现可以通过字符串操作和内置函数完成。 ```java import java.util.*; public class Main { public static void main(String[] args) { Scanner sc = new Scanner(System.in); String input = sc.nextLine(); char[] chars = input.toCharArray(); // 将输入转换为字符数组 Arrays.sort(chars); // 使用Arrays类的sort方法进行排序 System.out.println(new String(chars)); // 输出结果 } } ``` 上述代码通过`Arrays.sort()`实现了字符数组的升序排列,并最终输出重排后的字符串。 --- #### **第二题:最大子序列和** 此题属于经典的动态规划问题之一,目标是从一个整数数组中找到连续子序列的最大和。 解决方案如下所示: ```java import java.util.Scanner; public class MaxSubsequenceSum { public static int maxSubArray(int[] nums) { if (nums.length == 0) return 0; int currentMax = nums[0]; int globalMax = nums[0]; for (int i = 1; i < nums.length; ++i) { currentMax = Math.max(nums[i], currentMax + nums[i]); globalMax = Math.max(globalMax, currentMax); } return globalMax; } public static void main(String[] args) { Scanner scanner = new Scanner(System.in); // 输入处理逻辑省略... int n = scanner.nextInt(); int[] array = new int[n]; for (int i = 0; i < n; ++i) { array[i] = scanner.nextInt(); } System.out.println(maxSubArray(array)); } } ``` 这段代码利用了Kadane's Algorithm来高效求解最大子序列和问题。 --- #### **第三题:路径计数** 这是一道涉及组合数学的应用型题目,通常可以用递推或者记忆化搜索解决。假设棋盘大小固定,则可以定义状态转移方程计算不同位置到达终点的可能性数量。 伪代码描述如下: ```plaintext dp[x][y] 表示从起点到(x,y)处的不同走法数目; 初始条件 dp[0][0]=1;边界外均为0。 递推关系 dp[x][y] += dp[x-1][y]+dp[x][y-1]. ``` 完整版需注意越界情况以及数据范围优化等问题。 --- #### 参加此类赛事的经验分享 准备阶段建议多刷LeetCode、牛客网等相关平台上的经典算法习题集,重点掌握贪心策略、分治思想、图论基础知识等内容。另外,在正式比赛中保持冷静心态尤为重要,合理分配时间至每一道小问上,优先攻克简单得分项[^1]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值