**
使括号有效的最少添加
**
** 问题描述 😗*
给定一个由 ‘(’ 和 ‘)’ 括号组成的字符串 S,我们需要添加最少的括号( ‘(’ 或是 ‘)’,可以在任何位置),以使得到的括号字符串有效。
从形式上讲,只有满足下面几点之一,括号字符串才是有效的:
它是一个空字符串,或者
它可以被写成 AB (A 与 B 连接), 其中 A 和 B 都是有效字符串,或者
它可以被写作 (A),其中 A 是有效字符串。
给定一个括号字符串,返回为使结果字符串有效而必须添加的最少括号数。
示例 1:
输入:"())"
输出:1
示例 2:
输入:"((("
输出:3
示例 3:
输入:"()"
输出:0
示例 4:
输入:"()))(("
输出:4
输入说明 :
输入一个由 ‘(’ 和 ‘)’ 括号组成的字符串 S
输出说明 :
输出一个整数,表示为使结果字符串有效而必须添加的最少括号数
#include<iostream>
#include<stack>
#include<string>
using namespace std;
int num(string str){
stack <char> s;
int len=str.length();
for(int i=0;i<len;i++){
if(s.size()==0)//如果栈为空,直接入栈
s.push(str[i]);
else{
if(s.top()=='('&&str[i]==')')//如果栈顶是'(',此时字符为' )',凑成一个括号,将栈顶弹出
s.pop();
else
s.push(str[i]);
}
}
return s.size();//此时栈的大小就是无法配成括号的字符数,也就需要添加栈大小个括号
}
int main(){
string s;
getline(cin,s);
cout<<num(s)<<endl;
return 0;
}
**
反转每对括号间的子串
**
问题描述 :
给出一个字符串 s(仅含有小写英文字母和括号)。
请你按照从括号内到外的顺序,逐层反转每对匹配括号中的字符串,并返回最终的结果。
注意,您的结果中不应 包含任何括号。
示例 1:
输入:s = “(abcd)”
输出:“dcba”
示例 2:
输入:s = “(u(love)i)”
输出:“iloveu”
示例 3:
输入:s = “(ed(et(oc))el)”
输出:“leetcode”
示例 4:
输入:s = “a(bcdefghijkl(mno)p)q”
输出:“apmnolkjihgfedcbq”
说明:
0 <= s.length <= 2000
s 中只有小写英文字母和括号
我们确保所有括号都是成对出现的
输入说明 :
输入仅含有小写英文字母和括号的字符串
输出说明 :
输出一行,表示结果
输入范例 :
(u(love)i)
iloveu
//思路:不需要栈,根本在于记录( 出现的下标,当出现 ) 时,利用reverse 将这期间的字符串进行反转,一次遍历字符串的过程中,边遍历边反转,最后再处理字符串中()的问题
#include<iostream>
#include<stack>
#include<vector>
#include<string>
#include<algorithm>
using namespace std;
string reverseParentheses(string str) {
vector <int> index;
int len=str.length();
int i;
for( i=0;i<len;i++){
if(str[i]=='('){
index.push_back(i);//记录( 出现的位置
}
if(!index.empty()&&str[i]==')'){ //出现)之后,将( 到 ) 期间的字符串进行反转
reverse(str.begin()+index.back()+1,str.begin()+i);
index.pop_back();
}
}
//反转结束,处理括号问题
for(i=0;i<len;i++){
if(str[i]=='(' || str[i]==')'){
str.erase(str.begin()+i);
i--;
}
}
return str;
}
int main(){
string s;
getline(cin,s);
s=trans(s);
cout<<s<<endl;
return 0;
}
字符串解码
问题描述 :
给定一个经过编码的字符串,返回它解码后的字符串。
编码规则为: k[encoded_string],表示其中方括号内部的 encoded_string 正好重复 k 次。注意 k 保证为正整数。
你可以认为输入字符串总是有效的;输入字符串中没有额外的空格,且输入的方括号总是符合格式要求的。
此外,你可以认为原始数据不包含数字,所有的数字只表示重复的次数 k ,例如不会出现像 3a 或 2[4] 的输入。
示例 1:
输入:s = “3[a]2[bc]”
输出:“aaabcbc”
示例 2:
输入:s = “3[a2[c]]”
输出:“accaccacc”
示例 3:
输入:s = “2[abc]3[cd]ef”
输出:“abcabccdcdcdef”
示例 4:
输入:s = “abc3[cd]xyz”
输出:“abccdcdcdxyz”
输入说明 :
输入一行,表示经过编码的字符串
输出说明 :
输出一行,表示解码后的字符串
输入范例 :
//这个一开始偶觉得和上题有点大同小异,记录[ 出现的下标,将[ 到 ] 之间的字符串赋值某次,在插入字符串中,可是这时候还要处理此时遍历的下标问题,就另辟一个结果string来存储
//小窍门,我觉得利用vector来模拟栈简直太爽,少记一个容器的方法使用真好,queue虽然也可利用vector,但是优先队列(大根堆、小根堆)就没法用vector了
#include<iostream>
#include<string>
#include<stack>
#include<vector>
using namespace std;
string decodeString(string str){
int len=str.length();
string res="";
stack <string> s;
stack <int> k;
int i,num=0;
for(i=0;i<len;i++){
if(isdigit(str[i])){
num+=num*10+str[i]-'0';
}
else if(isalpha(str[i])){
res+=str[i];
}
else if(str[i]=='['){
k.push(num);
num=0;
s.push(res);
res="";
}
else if(str[i]==']'){
int j=k.top();
k.pop();
while(j--){
s.top()+=res;
}
res=s.top();
s.pop();
}
}
return res;
}
int main()
{
string str;
getline(cin,str);
string result=decodeString(str);
cout<<result<<endl;
return 0;
}
和至少为 K 的最短子数组
问题描述 :
返回 A 的最短的非空连续子数组的长度,该子数组的和至少为 K 。
如果没有和至少为 K 的非空子数组,返回 -1 。
示例 1:
输入:A = [1], K = 1
输出:1
示例 2:
输入:A = [1,2], K = 4
输出:-1
示例 3:
输入:A = [2,-1,2], K = 3
输出:3
说明:
1 <= A.length <= 50000
-10 ^ 5 <= A[i] <= 10 ^ 5
1 <= K <= 10 ^ 9
输入说明 :
首先输入A数组元素的数目n
然后输入n个整数
最后输入k
输出说明 :
输出一个整数,表示结果
输入范例 :
//利用双端队列
#include<iostream>
#include<string>
#include<deque>
#include<vector>
using namespace std;
int shortestSubarray(vector <int> &A,int k){
int n=A.size(),i;
int res=n+1;
vector<int> sum(n+1,0);
for(i=0;i<n;i++){
sum[i+1]=sum[i]+A[i];
}
i=0;
deque<int> d;
while(i<=n){
while(!d.empty()&& sum[i] <= sum[d.back()]){
d.pop_back();
}
while(!d.empty() && sum[i] - sum[d.front()]>=k){
//res=i-d.front()>res ? i-d.front():res;
res = min( res, i - d.front());
d.pop_front();
}
d.push_back(i);
i++;
}
if(res==n+1)
return -1;
else
return res;
}
int main()
{
vector<int> A;
int n,data,k;
cin>>n;
for(int i=0; i<n; i++)
{
cin>>data;
A.push_back(data);
}
cin>>k;
int result=shortestSubarray(A,k);
cout<<result<<endl;
return 0;
}
任务调度器
问题描述 :
给定一个用字符数组表示的 CPU 需要执行的任务列表。其中包含使用大写的 A - Z 字母表示的26 种不同种类的任务。任务可以以任意顺序执行,并且每个任务都可以在 1 个单位时间内执行完。CPU 在任何一个单位时间内都可以执行一个任务,或者在待命状态。
然而,两个相同种类的任务之间必须有长度为 n 的冷却时间,因此至少有连续 n 个单位时间内 CPU 在执行不同的任务,或者在待命状态。
你需要计算完成所有任务所需要的最短时间。
示例 :
输入:tasks = [“A”,“A”,“A”,“B”,“B”,“B”], n = 2
输出:8
解释:A -> B -> (待命) -> A -> B -> (待命) -> A -> B.
在本示例中,两个相同类型任务之间必须间隔长度为 n = 2 的冷却时间,而执行一个任务只需要一个单位时间,所以中间出现了(待命)状态。
说明:
任务的总个数为 [1, 10000]。
n 的取值范围为 [0, 100]。
输入说明 :
首先输入任务的数目len
然后输入len个大写的 A - Z 字母,无空格、无引号
最后输入n
输出说明 :
输出一个整数,表示结果
输入范例 :
桶思想解答https://leetcode-cn.com/problems/task-scheduler/solution/tong-zi-by-popopop/
#include<iostream>
#include<vector>
using namespace std;
int leastInterval(vector<char>& tasks, int m) {
vector<int> num(26,0);
int i,n;
//统计各个字母出现的次数
for(i=0;i<tasks.size();i++){
num[tasks[i]-'A']++;
}
int max_count=0,sum=0;
for(i=0;i<26;i++){
sum+=num[i];
//找到出现次数最多的
if(num[i]>max_count){
max_count=num[i];
n=0;
}
//计算最大次数的个数
if(num[i]==max_count){
n++;
}
}
return max((max_count-1)*(m+1)+n,sum);
}
int main()
{
vector<char> v;
int len,m;
char data;
cin>>len;
for(int i=0; i<len; i++)
{
cin>>data;
v.push_back(data);
}
cin>>m;
int result=leastInterval(v,m);
cout<<result<<endl;
return 0;
}