反转每对括号间的子串 c语言,5190. 反转每对括号间的子串 && 5191.K次串联后最大子数组之和...

66b52468c121889b900d4956032f1009.png

8种机械键盘轴体对比

本人程序员,要买一个写代码的键盘,请问红轴和茶轴怎么选?

前言

这次的周赛做的太菜了,不忍直视,我想图书馆对面那对情侣老是在那里叽叽喳喳,但是本质还是我太菜了。不过还是花了快一个下午时间+找参考资料把B和C过了。所以我再一次认为,多看下优秀的代码真的对自己很有帮助。

先看下题目B

题目B

题意

题意的话我还是直接贴图了。

a0139bbb047e2cfdb096ec16ea922950.png

当然对于这一类字符串去括号或者字符串压缩得题目还是使用stack比较有效。但是我当时就想着用一种新的办法做一下,没有考虑括号可能有没有嵌套得情况,直接就崩了。 所以遇到这类题目还是多注意下隐藏得测试用例好点。关键多思考。

分析

既然明确了思路,就直接使用一个栈来完成,思考入栈和退栈,当需要退栈时都是在遇到”)”时,因为此时我们需要将”()”内得字符串反转。那就很明显了。 遍历一遍字符串,遇到 “)”时退栈,遇到”(“时停止退栈。将得到的字符串反转在压栈。重复这个过程就可以得到结果了。

note:这里需要注意一点string tmp=""+'i';//这个代码在mingw环境下输出一个空串。

string tmp="";

tmp=tmp+'i';// 可以输出 i

这个我觉得比较奇怪,但是还没有找到原因。 之后再来填吧。 note:2019.9.16 填坑关于昨天这个问题,和班上一个大佬讨论了下,然后查了下资料,这应该是一个关于capacity的问题,string就好比vetcor,当我使用上述第一种方式进行初试化时,我是用的tmp并没有被初始化,或者说他没有这样类型的构造函数,所以经过 tmp=””+’i’;后tmp的capacity还是0,所以就会打印不出任何东西。而它刚好有一个拷贝构造函数,这个构造函数底层还是深拷贝(毕竟stl),初始化后capacity不为0,就可以继续往下了。

ac代码

思路大概清楚,就直接代码了class Solution {

public:

string reverseParentheses(string s) {

stack str;

s= '('+s+')';

int size=s.size();

// cout<

for(int i=0;i

string now="";

now=now+s[i];

str.push(now);

if(s[i]==')'){

string tmp;

str.pop();

while(str.empty()==false && str.top()!="("){

tmp=str.top()+tmp;

str.pop();

}

reverse(tmp.begin(),tmp.end()); //o(n)

if(str.empty()==false)

str.pop(); //pop (

str.push(tmp);

}

}

reverse(str.top().begin(),str.top().end());

return str.top();

}

};

//这种方法我觉得应该算是比较快的了。就不贴ac图了。

题目C

题意

还是先贴题目吧

87303fa3d20948c54894b9ee45aebda2.png

这道题是真的难(对于我来说)。自从之前做了一道叫 求数组的最大自序和之后,我的思路感觉就固化了,就是喜欢直接求整个数组的最大值去了,所以当然就是直接超时了。这道题我参考一些资料后,思路大概是这样的:

解析

如果k为1 直接取最大值。 如果k>1,需要计算出一个数组的和,一个数组左边开始的最大值,一个数组右边开始的最大值。然后分以下几种情况讨论:如果一个数组的和小于等于0,那么最大值应该为一个数组计算所得的最大值和 左边的最大值加右边的最大值进行比较

否则的话,需要进行判断比较下列几种情况的最大值 A. k个数组的和 B.左边k-1个数组的和加上最后一个数组的左最大值。 C右边k-1个数组的和加上第一个数组的右最大值。C.中间k-2个数组的和+左右两边的数组的最大值。 比较他们的结果,最终得出最值。

代码

根据上面的思路,就有了整体的代码:class Solution {

const int BIG=1e9+7;

public:

int kConcatenationMaxSum(vector& arr, int k) {

int size=arr.size();

long max=0,sum=0;

for(int i=0;i

sum=sum+arr[i];

if(max

max=sum;

if(sum<0)

sum=0;

} //一个子数组最大和

//k==1 直接取最大

if(k==1) return max%BIG;

//k>=2

long lmax=0,rmax=0;

long cntleft=0;

for(int i=0;i

cntleft=cntleft+arr[i];

lmax=std::max(lmax,cntleft);

}//左边最大和

long cntright=0;

for(int i=size-1;i>=0;i--){

cntright=cntright+arr[i];

rmax=std::max(rmax,cntright);

}//右边最大和

//分类讨论

long sumofone=0;

for(auto c: arr)

sumofone+=c;

// cout<

if(sumofone<0){ //数组的和小于0,则比较max和左最大值加右最大值的和

max=std::max(max,(lmax+rmax));

}else{ //一个的和大于0,则比较第一个右最大值+k-1个数组的和,中间k-2个数组的和+左右两个的左右最大值,左边k-1个数组的和+最后一个数组左最大值。 k个数组的和。

max=std::max(sumofone*k,std::max(sumofone*(k-1)+lmax,sumofone*(k-1)+rmax));

//还有一种情况 中间k-2个的和 加上左右lmax和rmax的最大值在比交

max=std::max(sumofone*(k-2)+lmax+rmax,max);

}

return max%BIG;

}

};

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值