相关链接
https://leetcode-cn.com/contest/weekly-contest-154/ranking
5189. “气球” 的最大数量
题目难度Easy
给你一个字符串 text,你需要使用 text 中的字母来拼凑尽可能多的单词 “balloon”(气球)。
字符串 text 中的每个字母最多只能被使用一次。请你返回最多可以拼凑出多少个单词 “balloon”。
示例 1:
输入:text = "nlaebolko"
输出:1
示例 2:
输入:text = "loonbalxballpoon"
输出:2
示例 3:
输入:text = "leetcode"
输出:0
class Solution {
public:
int maxNumberOfBalloons(string text) {
char word[]="balloon";
int bucket[5]={0,0,0,0,0};
for(int i=0;i<text.size();i++){
if(text[i]=='b')bucket[0]++;
else if(text[i]=='a')bucket[1]++;
else if(text[i]=='l')bucket[2]++;
else if(text[i]=='o')bucket[3]++;
else if(text[i]=='n')bucket[4]++;
}
int count=0;
while(bucket[0]>=1&&bucket[1]>=1&&bucket[2]>=2&&bucket[3]>=2&&bucket[4]>=1){
count++;
bucket[0]--;
bucket[1]--;
bucket[2]=bucket[2]-2;
bucket[3]=bucket[3]-2;
bucket[4]--;
}
return count;
}
};
总结:
这里我使用的是基于桶排的统计,总体来说显得有些笨拙,一开始也考虑使用map,但是脑子太乱了,而且对map还不够熟悉,没想好怎么建map,下面这个答案我觉得非常简洁!
1. map<char,int>与map [ ]的搜索返回second
关于map<char,int>里面的int为什么默认值为0,原因是因为调用了int的默认构造函数,而int的默认构造函数为0,因此就是0;下面这几个程序其实都使用了这个特性,包括vector < int> 具体可以看下面这个链接,讲得不错。
https://zhidao.baidu.com/question/688551295624750924.html
2. min的使用
const T& min(const T&a ,const T&b)。const 引用可以绑定右值,而普通引用不可以。下面有一个特殊的调用min({F[‘b’], F[‘a’], F[‘l’]/2, F[‘o’]/2, F[‘n’]}),提取了一个集合中的最小值。
本题的其他漂亮的解答:
//By liouzhou_101
class Solution {
public:
int maxNumberOfBalloons(string text) {
map<char, int> F;
for (auto c : text) F[c] ++;
return min({F['b'], F['a'], F['l']/2, F['o']/2, F['n']});
}
};
//by gracious
class Solution {
public:
int maxNumberOfBalloons(string text) {
unordered_map<char, int> cnt;
for ( auto c:text ){
if ( c=='b' || c=='a' || c=='l' || c=='o' || c=='n' )
++cnt[c];
}
int x = min( min( cnt['b'], cnt['a'] ), cnt['n'] );
int y = min( cnt['o']/2, cnt['l']/2 ) ;
return min( x,y );
}
};
class Solution {
public:
int maxNumberOfBalloons(string text) {
vector<int> mp(26);
for(auto i:text){
mp[i-'a']++;
}
int result = 1e9;
//balloon
result = min(result,mp['a'-'a']);
result = min(result,mp['b'-'a']);
result = min(result,mp['l'-'a']/2);
result = min(result,mp['o'-'a']/2);
result = min(result,mp['n'-'a']);
return result;
}
};
5190. 反转每对括号间的子串
题目难度Medium
给出一个字符串 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"
#include<iostream>
#include<iterator>
#include<string>
#include<stack>
#include<algorithm>
using namespace std;
int main() {
string text;
cin >> text;
stack<string::iterator> s;
string::iterator temp;
for (auto iter = text.begin(); iter != text.end(); ) {
if (*iter == '(') {
s.push(iter);
text.erase(iter);
}
else if (*iter == ')') {
temp = s.top();
s.pop();
reverse(temp, iter);
text.erase(iter);
}
else iter++;
}
cout << text;
return 0;
}
总结:
这里主要是用了STL里的reverse(iter1,iter2)//[iter1,iter2)。
另外就是关于string类里面的erase函数,erase函数在擦去iter1位置的元素后,之后iter1会指向擦去元素的下一个元素,或者说有点像后面的元素会往前移动。
或者说,在擦去之前将iter1入栈,此时指向的是a;擦去a后,弹出iter1,此时的iter1指向b;也就是说地址的位置没有变,但是地址的元素改变了。
这个特性导致我在调试程序的时候一开始一直越界。
本题的其他漂亮的解答:
1.下面这个vector使用得非常娴熟,模拟得非常漂亮,对string的特性也十分了解,其实本质也是使用vector来模拟了一个栈的操作;每次遇到"("都将当前的cur存到vector中,清空cur。
下面两个代码思路都是相同的,可以欣赏一下。
class Solution {
public:
string reverseParentheses(string s) {
vector<string> st;
vector<char> c;
string cur="";
for ( auto c:s ){
if ( c!='(' && c!=')' )
cur += c;
else if ( c=='(' ){
st.push_back( cur );
cur = "";
}else if ( c==')' ){
reverse( cur.begin() , cur.end() );
cur = st.back() + cur; st.pop_back();
}
}
return cur;
}
};
class Solution {
public:
string reverseParentheses(string s) {
vector<string> v(1);//这里建立1的空间相当于“”,就不需要上面的cur了
for (auto c : s)
{
if (c == '(')
{
v.push_back("");
}
else if (c == ')')
{
auto t = v.back();
reverse(t.begin(), t.end());
v.pop_back();
v.back() += t;
}
else
v.back() += c;
}
return v[0];
}
};
1191. K 次串联后最大子数组之和
总结:
这个题目是最大子序列和的变种,但是由于重复了k次,因此要分类讨论,另外还要计算头尾。对于这种计算头尾,中间简化计算的方法要了解。另外在计算过程中出现了乘法溢出的情况,因此以后对于比较大的数据要考虑long long 的情况。
另外在看他人的解答过程中,发现max({1,2,3,4 });这种方法可以极大的简化各种多位数字的比较,应该了解这种技巧!
用户通过次数203
用户尝试次数444
通过次数211
提交次数1604
题目难度Medium
给你一个整数数组 arr 和一个整数 k。
首先,我们要对该数组进行修改,即把原数组 arr 重复 k 次。
举个例子,如果 arr = [1, 2] 且 k = 3,那么修改后的数组就是 [1, 2, 1, 2, 1, 2]。
然后,请你返回修改后的数组中的最大的子数组之和。
注意,子数组长度可以是 0,在这种情况下它的总和也是 0。
由于 结果可能会很大,所以需要 模(mod) 10^9 + 7 后再返回。
示例 1:
输入:arr = [1,2], k = 3
输出:9
示例 2:
输入:arr = [1,-2,1], k = 5
输出:2
示例 3:
输入:arr = [-1,-2], k = 7
输出:0
提示:
1 <= arr.length <= 10^5
1 <= k <= 10^5
-10^4 <= arr[i] <= 10^4
#include<iostream>
#include<algorithm>
#include<vector>
#include<cstring>
using namespace std;
int kConcatenationMaxSum(vector<int>& arr, int k) {
if (arr.size() == 0)return 0;
int N = k*arr.size() - 1;
int sum = 0;
int index=0;
int max = 0;
for (int i = 0; i <= N; i++,index++) {
if (index > arr.size() - 1) {
index = 0;
}
sum += arr[index];
if (sum < 0) {
sum = 0;
}
max = max > sum ? max : sum;
}
return max;
}
int kConcatenationMaxSum2(vector<int>& arr, int k) {
int n = arr.size();
int* ForwardSum = new int[n];
int* BackwardSum = new int[n];
memset(ForwardSum, 0, sizeof(ForwardSum));
memset(BackwardSum, 0, sizeof(BackwardSum));
int Maxf, Maxb;
Maxf = Maxb = 0;
int Arrsum = arr[0];//序列全部和
ForwardSum[0] = arr[0];
Maxf = Maxf > ForwardSum[0] ? Maxf : ForwardSum[0];
for (int i = 1; i < arr.size(); i++) {
Arrsum += arr[i];
ForwardSum[i] = ForwardSum[i - 1] + arr[i];
Maxf = Maxf > ForwardSum[i] ? Maxf : ForwardSum[i];
}
BackwardSum[n - 1] = arr[n - 1];
Maxb = Maxb > BackwardSum[n-1] ? Maxb : BackwardSum[n-1];
for (int i = n-2; i >=0; i--) {
BackwardSum[i] = BackwardSum[i + 1] + arr[i];
Maxb = Maxb > BackwardSum[i] ? Maxb : BackwardSum[i];
}
int sum = 0;//临时存放
int maxsum = 0;//最大子列和
for (int i = 0; i < n; i++) {
if (sum + arr[i] > 0) {
sum += arr[i];
}
else {
sum = 0;
}
maxsum = maxsum > sum ? maxsum : sum;
}
int TwoPart;
TwoPart = Maxf > Maxb ? Maxf : Maxb;
TwoPart = TwoPart > (Maxf + Maxb) ? TwoPart : (Maxf + Maxb);
int maxval=maxsum > TwoPart ? maxsum : TwoPart;
if (k == 1)return maxsum;
if (k == 2) {
return maxval;
}
else if (Arrsum < 0) {
return maxval;
}
else {
long long result;
result =(long long) (k - 2)*Arrsum + TwoPart;
return result;
}
}
其他人的漂亮的代码
class Solution {
public:
int a[100005],s[100005],f[100005];
int kConcatenationMaxSum(vector<int>& arr, int k) {
int n=arr.size(),i,m,x,y;
long long ans=0;
for(i=f[0]=s[0]=0;i<n;i++)
{
a[i+1]=arr[i];
s[i+1]=s[i]+a[i+1];
f[i+1]=max(0,f[i]+a[i+1]);
if(f[i+1]>ans)ans=f[i+1];
}
if(k==1)return ans;
m=max(s[n],0);
for(i=x=y=0;i<=n;i++)
{
x=max(x,s[i]);
y=max(y,s[n]-s[i]);
}
ans=max(ans,(long long)(k-2)*m+x+y);
return ans%1000000007;
}
};