点击跳转到题目位置
给你一个仅由 大写 英文字符组成的字符串 s 。
你可以对此字符串执行一些操作,在每一步操作中,你可以从 s 中删除 任一个 “AB” 或 “CD” 子字符串。
通过执行操作,删除所有 “AB” 和 “CD” 子串,返回可获得的最终字符串的 最小 可能长度。
注意,删除子串后,重新连接出的字符串可能会产生新的 “AB” 或 “CD” 子串。
class Solution {
public:
int minLength(string s) {
stack<char> stk;
int n = s.size();
for(int i = 0; i < n; ++i){
if(stk.empty()){
stk.push(s[i]);
continue;
}
if(s[i] == 'D'){
if(stk.top() == 'C'){
stk.pop();
continue;
}
}
if(s[i] == 'B'){
if(stk.top() == 'A'){
stk.pop();
continue;
}
}
stk.push(s[i]);
}
return stk.size();
}
};
(1) 这道题目采取的是用栈来删除字符串。
(2) 如果栈为空,则将字符压入栈中,否则的话判断字符是否是‘B’,是‘B’的话如果栈顶是‘A’则出栈,如果字符是‘D’的话,如果栈顶是‘C’则出栈。其他情况一律入栈。
(3) 最后返回栈的长度即为删除子串后的字符串最小长度。
点击跳转到题目位置
给你一个由 小写英文字母 组成的字符串 s ,你可以对其执行一些操作。在一步操作中,你可以用其他小写英文字母 替换 s 中的一个字符。
请你执行 尽可能少的操作 ,使 s 变成一个 回文串 。如果执行 最少 操作次数的方案不止一种,则只需选取 字典序最小 的方案。
对于两个长度相同的字符串 a 和 b ,在 a 和 b 出现不同的第一个位置,如果该位置上 a 中对应字母比 b 中对应字母在字母表中出现顺序更早,则认为 a 的字典序比 b 的字典序要小。
返回最终的回文字符串。
class Solution {
public:
string makeSmallestPalindrome(string s) {
int left = 0;
int right = s.size() - 1;
while(left <= right){
if(s[left] != s[right]){
int num = min(s[left], s[right]);
s[left] = char(num);
s[right] = char(num);
}
left++;
right--;
}
return s;
}
};
(1) 采用双指针进行字符串遍历。left = 0, right = n - 1。 n表示字符串的长度。
(2) 如果left和right所指的字符不一样,将字符替换成字典序小的那一个字符。
(3) left++,right–一直到left > right。
点击跳转到题目位置
给你一个正整数 n ,请你返回 n 的 惩罚数 。
n 的 惩罚数 定义为所有满足以下条件 i 的数的平方和:
class Solution {
bool judge(int num, int target){
if(num == target){
return true;
}
string s = to_string(num);
string t = to_string(num);
int tmp = 0;
int n = s.size();
int yz = 1;
for(int i = n-1; i >= 0; --i){
tmp += (yz * (s[i] - '0'));
if(tmp > target){
return false;
}
t.pop_back();
if(t.size() == 0 ){
if(tmp != target){
return false;
} else{
return true;
}
}
int num1 = stoi(t);
int target1 = target - tmp;
if(judge(num1, target1) == true){
return true;
}
yz *= 10;
}
return false;
}
public:
int punishmentNumber(int n) {
int res = 0;
for(int i = 1; i <= n; ++i){
int num = i * i;
if(judge(num , i) == true){
res += num;
}
}
return res;
}
};
(1) 首先依次遍历从1 ~ n的所有整数,然后来进行判断。
(2) 距一个例子来解释算法思路。数字10,10 * 10 等于 100。 100 = 10 + 0。我们从后面往前遍历来判断分割的位置,先从第一个0开始分割,这个时候我们目标得到的数字是10 - 0,剩下的数字是10,那么我们实际上由原来的问题100 能否分割出10转移到10能否分割出10,显然10 等于 10,分割出来了,那么就返回true。那么什么时候返回false呢。如果最终已经无法通过分割来得到目标数字或者已经分割出的数字大于目标数字,那么意味着这样的分割是错误的。
(3) 按照上述的描述,我们采用的是递归的思路,通过不同的分割点,递归求出分割是否可行。
点击跳转到题目位置
给你一个 n 个节点的 无向带权连通 图,节点编号为 0 到 n - 1 ,再给你一个整数数组 edges ,其中 edges[i] = [ai, bi, wi] 表示节点 ai 和 bi 之间有一条边权为 wi 的边。
部分边的边权为 -1(wi = -1),其他边的边权都为 正 数(wi > 0)。
你需要将所有边权为 -1 的边都修改为范围 [1, 2 * 109] 中的 正整数 ,使得从节点 source 到节点 destination 的 最短距离 为整数 target 。如果有 多种 修改方案可以使 source 和 destination 之间的最短距离等于 target ,你可以返回任意一种方案。
如果存在使 source 到 destination 最短距离为 target 的方案,请你按任意顺序返回包含所有边的数组(包括未修改边权的边)。如果不存在这样的方案,请你返回一个 空数组 。
注意:你不能修改一开始边权为正数的边。
心若在,梦就在,只不过是从头再来。哪怕每次周赛一题都做不出来,都得努力去研究,因为未来的某一天一定能够进步的。