1717 删除子字符串的最大得分

题目描述:
给你一个字符串 s 和两个整数 x 和 y 。你可以执行下面两种操作任意次。
删除子字符串 “ab” 并得到 x 分。
比方说,从 “cabxbae” 删除 ab ,得到 “cxbae” 。
删除子字符串"ba" 并得到 y 分。
比方说,从 “cabxbae” 删除 ba ,得到 “cabxe” 。
请返回对 s 字符串执行上面操作若干次能得到的最大得分。

示例 1:
输入:s = “cdbcbbaaabab”, x = 4, y = 5
输出:19
解释:

  • 删除 “cdbcbbaaabab” 中加粗的 “ba” ,得到 s = “cdbcbbaaab” ,加 5 分。
  • 删除 “cdbcbbaaab” 中加粗的 “ab” ,得到 s = “cdbcbbaa” ,加 4 分。
  • 删除 “cdbcbbaa” 中加粗的 “ba” ,得到 s = “cdbcba” ,加 5 分。
  • 删除 “cdbcba” 中加粗的 “ba” ,得到 s = “cdbc” ,加 5 分。
    总得分为 5 + 4 + 5 + 5 = 19 。

示例 2:
输入:s = “aabbaaxybbaabb”, x = 5, y = 4
输出:20

提示:
1 <= s.length <= 105
1 <= x, y <= 104
s 只包含小写英文字母。

方法1:
主要思路:解题汇总链接
(1)使用单调栈实现贪心;
(2)贪心的策略是每次尽量的先将权重大的子字符串删除,若删除完了,再从剩余的字符中删除一个权重较小的子字符串,
(3)然后判断是否能够删除可能存在的权重较大的子字符串,若能,则接着删除,若不能,则接着再去找一个权重较小的字符串;
(4)直到判断完所有的字符;

class Solution {
public:
	//获得删除两个两个子字符串的数量
  void get_count(string& s, char first_ch, char second_ch, int& count_ch_first, int& count_ch_second) {
		stack<char> st;
		//先将原字符串使用栈进行存储,存储过程中删除所有的权重较大的子字符串
		for (char ch : s) {
			if (!st.empty() && ch == second_ch && st.top() == first_ch) {//删除子字符串
				st.pop();
				++count_ch_first;//统计删除子字符串的数量
			}
			else {
				st.push(ch);//压入字符
			}
		}
		stack<char> st_tmp;//辅助栈, 存储字符
		while (!st.empty()) {//判断完所有的字符
			if (!st.empty() && !st_tmp.empty() && st.top() == second_ch && st_tmp.top() == first_ch) {//说明可以删除一个权重较小的子字符串
				++count_ch_second;//统计权重较小的子字符串的数量
				//删除子字符串
				st.pop();
				st_tmp.pop();
				//判断是否可能进一步删除权重较大的字符串
				while (!st.empty() &&!st_tmp.empty() && st.top() == first_ch && st_tmp.top() == second_ch) {
					++count_ch_first;//统计删除权重较大的子字符串的数量
					//删除子字符串
					st.pop();
					st_tmp.pop();
				}
			}
			else {//压入到辅助栈中
				st_tmp.push(st.top());
				st.pop();
			}
		}
		return;
	}

	int maximumGain(string s, int x, int y) {
		int first = 0, second = 0;
		int res = 0;
		//根据权重的大小,决定先删除那个子字符串
		if (x > y) {
			get_count(s, 'a', 'b', first, second);
			res = x * first + y * second;
		}
		else {
			get_count(s, 'b', 'a', first, second);
			res = y * first + x * second;
		}
		return res;
	}
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值