11.15
402. 移掉K位数字
难度中等385
给定一个以字符串表示的非负整数 num,移除这个数中的 k 位数字,使得剩下的数字最小。
注意:
- num 的长度小于 10002 且 ≥ k。
- num 不会包含任何前导零。
示例 1 :
输入: num = "1432219", k = 3
输出: "1219"
解释: 移除掉三个数字 4, 3, 和 2 形成一个新的最小的数字 1219。
示例 2 :
输入: num = "10200", k = 1
输出: "200"
解释: 移掉首位的 1 剩下的数字为 200. 注意输出不能有任何前导零。
示例 3 :
输入: num = "10", k = 2
输出: "0"
解释: 从原数字移除所有的数字,剩余为空就是0。
解答:贪心问题。思路单调栈,从前往后扫描,遇到比前一个大的就压进栈,后一个小就出栈
class Solution {
public:
string removeKdigits(string num, int k) {
string res;
for(auto c : num){
while(k && res.size() && res.back() > c){
k--;
res.pop_back();
}
res += c;
}
while(k--)res.pop_back();
k = 0;
while(k < res.size() && res[k] == '0')k++;
if(k == res.size())res += '0';
return res.substr(k);
}
};
5550. 拆炸弹
难度简单0
你有一个炸弹需要拆除,时间紧迫!你的情报员会给你一个长度为 n 的 循环 数组 code 以及一个密钥 k 。
为了获得正确的密码,你需要替换掉每一个数字。所有数字会 同时 被替换。
- 如果
k > 0,将第i个数字用 接下来k个数字之和替换。 - 如果
k < 0,将第i个数字用 之前k个数字之和替换。 - 如果
k == 0,将第i个数字用0替换。
由于 code 是循环的, code[n-1] 下一个元素是 code[0] ,且 code[0] 前一个元素是 code[n-1] 。
给你 循环 数组 code 和整数密钥 k ,请你返回解密后的结果来拆除炸弹!
示例 1:
输入:code = [5,7,1,4], k = 3
输出:[12,10,16,13]
解释:每个数字都被接下来 3 个数字之和替换。解密后的密码为 [7+1+4, 1+4+5, 4+5+7, 5+7+1]。注意到数组是循环连接的。
示例 2:
输入:code = [1,2,3,4], k = 0
输出:[0,0,0,0]
解释:当 k 为 0 时,所有数字都被 0 替换。
示例 3:
输入:code = [2,4,9,3], k = -2
输出:[12,5,6,13]
解释:解密后的密码为 [3+9, 2+3, 4+2, 9+4] 。注意到数组是循环连接的。如果 k 是负数,那么和为 之前 的数字。
提示:
n == code.length1 <= n <= 1001 <= code[i] <= 100-(n - 1) <= k <= n - 1
解答:直接暴力枚举
class Solution {
public:
vector<int> decrypt(vector<int>& code, int k) {
int n = code.size();
vector<int>res(n);
for(int i = 0; i < n; i++){
if(k == 0){
res[i] = 0;
}else if(k > 0){
for(int j = 1; j < k + 1; j++){
res[i] += code[(i + j) % n];
}
}else{
for(int j = -1; j >= k ; j--){
res[i] += code[(i + j + n) % n];
}
}
}
return res;
}
};
5551. 使字符串平衡的最少删除次数
难度中等3
给你一个字符串 s ,它仅包含字符 'a' 和 'b' 。
你可以删除 s 中任意数目的字符,使得 s 平衡 。我们称 s 平衡的 当不存在下标对 (i,j) 满足 i < j 且 s[i] = 'b' 同时 s[j]= 'a' 。
请你返回使 s 平衡 的 最少 删除次数。
示例 1:
输入:s = "aababbab"
输出:2
解释:你可以选择以下任意一种方案:
下标从 0 开始,删除第 2 和第 6 个字符("aababbab" -> "aaabbb"),
下标从 0 开始,删除第 3 和第 6 个字符("aababbab" -> "aabbbb")。
示例 2:
输入:s = "bbaaaaabb"
输出:2
解释:唯一的最优解是删除最前面两个字符。
提示:
1 <= s.length <= 105s[i]要么是'a'要么是'b'。
解答: 考察前缀和思想
class Solution {
public:
int minimumDeletions(string s) {
int n = s.size();
vector<int>s1(n + 1), s2(n + 1);
for(int i = 1; i <= n; i++){
s1[i] = s1[i - 1];
s2[i] = s2[i - 1];
if(s[i - 1] == 'a')s1[i]++;
else s2[i]++;
}
int res = INT_MAX;
for(int i = 0; i <= n; i++)res = min(res, s2[i] + s1[n] - s1[i]);
return res;
}
};
523. 连续的子数组和
难度中等186
给定一个包含 非负数 的数组和一个目标 整数 k,编写一个函数来判断该数组是否含有连续的子数组,其大小至少为 2,且总和为 k 的倍数,即总和为 n*k,其中 n 也是一个整数。
示例 1:
输入:[23,2,4,6,7], k = 6
输出:True
解释:[2,4] 是一个大小为 2 的子数组,并且和为 6。
示例 2:
输入:[23,2,6,4,7], k = 6
输出:True
解释:[23,2,6,4,7]是大小为 5 的子数组,并且和为 42。
说明:
- 数组的长度不会超过 10,000 。
- 你可以认为所有数字总和在 32 位有符号整数范围内。
解答:前缀和,只要s[i] - s[i - 2] ... s[i] - s[0]只要有为k*n的倍数就行,于是只要满足s[i]对K取余与s[i - 2]相等即可
class Solution {
public:
bool checkSubarraySum(vector<int>& nums, int k) {
if(!k){
for(int i = 0; i < nums.size() - 1; i++){
if(!nums[i] && !nums[i + 1])return true;
}
return false;
}
int n = nums.size();
unordered_set<int>hash;
vector<int>s(n + 1);
for(int i = 1; i <= n; i++)s[i] = s[i - 1] + nums[i - 1];
for(int i = 2; i <= n; i++){
hash.insert(s[i - 2] % k);
if(hash.count(s[i] % k))return true;
}
return false;
}
};
520. 检测大写字母
难度简单115
给定一个单词,你需要判断单词的大写使用是否正确。
我们定义,在以下情况时,单词的大写用法是正确的:
- 全部字母都是大写,比如"USA"。
- 单词中所有字母都不是大写,比如"leetcode"。
- 如果单词不只含有一个字母,只有首字母大写, 比如 "Google"。
否则,我们定义这个单词没有正确使用大写字母。
示例 1:
输入: "USA"
输出: True
示例 2:
输入: "FlaG"
输出: False
注意: 输入是由大写和小写拉丁字母组成的非空单词。
解答:
class Solution {
public:
bool check(char c){
if(c >= 'A' && c <= 'Z')return true;
else return false;
}
bool detectCapitalUse(string word) {
int n = word.size();
int res = 0;
for(auto c : word){
if(check(c))res++;
}
return res == n || !res || res == 1 && check(word[0]);
}
};
521. 最长特殊序列 Ⅰ
难度简单72
给你两个字符串,请你从这两个字符串中找出最长的特殊序列。
「最长特殊序列」定义如下:该序列为某字符串独有的最长子序列(即不能是其他字符串的子序列)。
子序列 可以通过删去字符串中的某些字符实现,但不能改变剩余字符的相对顺序。空序列为所有字符串的子序列,任何字符串为其自身的子序列。
输入为两个字符串,输出最长特殊序列的长度。如果不存在,则返回 -1。
示例 1:
输入: "aba", "cdc"
输出: 3
解释: 最长特殊序列可为 "aba" (或 "cdc"),两者均为自身的子序列且不是对方的子序列。
示例 2:
输入:a = "aaa", b = "bbb"
输出:3
示例 3:
输入:a = "aaa", b = "aaa"
输出:-1
提示:
- 两个字符串长度均处于区间
[1 - 100]。 - 字符串中的字符仅含有
'a'~'z'。
解答:
class Solution {
public:
int findLUSlength(string a, string b) {
if(a == b)return -1;
return max(a.size(), b.size());
}
};

浙公网安备 33010602011771号