leetcode周赛154总结

相关链接
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;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值