力扣双周赛/周赛
第226场周赛
3:前缀和
class Solution {
public:
typedef long long ll;
long long sum[100005];
vector<bool> canEat(vector<int>& candiesCount, vector<vector<int>>& queries) {
vector<bool>ans;
sum[0] = candiesCount[0];
for(int i = 1; i < candiesCount.size(); i++){
sum[i] = sum[i-1]+candiesCount[i];
}
for(int i = 0; i < queries.size(); i++){
ll x = (queries[i][0] == 0 ? 0 : sum[queries[i][0]-1])+1;
ll y = sum[queries[i][0]];
ll l = 1ll*queries[i][1]+1;
ll r = (1ll*queries[i][1]+1)*1ll*queries[i][2];
bool t = true;
if(x > r || y < l) t = false;
ans.push_back(t);
}
return ans;
}
}; 4:最长回文串(dp)
class Solution {
public:
int dp[2005][2005];
bool checkPartitioning(string s) {
memset(dp,0,sizeof dp);
for(int i = 0; i < s.length(); i++) dp[i][i] =1;
for(int i = 0; i < s.length()-1; i++){
if(s[i] == s[i+1]) dp[i][i+1] = 1;
}
if(s[s.length()-1] == s.length()-2) dp[s.length()-1][s.length()-2] = 1;
for(int l = 3; l < s.length(); l++){
for(int i = 0; i < s.length() && l+i-1 < s.length(); i++){
if(dp[i+1][l+i-2]){
if(s[i] == s[l+i-1]) dp[i][l+i-1] = 1;
}
}
}
for(int i = 1; i < s.length()-1; i++){
for(int j = i; j < s.length()-1; j++){
if(dp[i][j] && dp[0][i-1] && dp[j+1][s.length()-1]) return true;
}
}
return false;
}
}; 第218场周赛
2:尺取法
class Solution {
public:
int maxOperations(vector<int>& nums, int k) {
int ans = 0,l = 0,r = nums.size()-1;
sort(nums.begin(),nums.end());
while(l < r){
if(nums[l]+nums[r] < k && l < r) l++;
if(nums[l]+nums[r] > k && l < r) r--;
if(nums[l]+nums[r] == k && l < r) {
ans++;
l++;
r--;
}
}
return ans;
}
};
3:二进制
class Solution {
public:
typedef long long ll;
int mod = 1e9+7;
int qpow(ll a,ll b){
ll res = 1;
while(b){
if(b&1) res = res*a%mod;
b >>= 1;
a = a*a%mod;
}
return res%mod;
}
int concatenatedBinary(int n) {
int num = 0,num1 = 0;
int a[100005];
long long sum = 1;
for(int i = 2; i <= n; i++){
int temp = i;
int t = 0;
while(temp){
num++;
t++;
temp >>= 1;
}
sum = (sum << t)%mod;
sum += i;
}
// cout << num << endl;
int ans = sum;
return ans;
}
}; 第217场周赛
2:单调栈
class Solution {
public:
vector<int> mostCompetitive(vector<int>& nums, int k) {
stack<int>st;
int p = nums.size()-k;
for(int i = 0; i < nums.size(); i++){
while(st.size() && p > 0 && nums[i] < st.top()){
p--;
st.pop();
}
st.push(nums[i]);
}
vector<int>ans,ans1;
while(st.size()){
ans.push_back(st.top());
st.pop();
}
reverse(ans.begin(),ans.end());
for(int i = 0; i < k; i++) ans1.push_back(ans[i]);
return ans1;
}
}; 第214场周赛
1
class Solution {
public:
int getMaximumGenerated(int n) {
int a[5005];
a[0] = 0;
a[1] = 1;
for(int i = 1; i <= n; i++){
if(2*i <= n) a[2*i] = a[i];
if(2*i+1 <= n) a[2*i+1] = a[i]+a[i+1];
}
int mmax = 0;
for(int i = 0; i <= n; i++){
mmax = max(a[i],mmax);
}
return mmax;
}
};
2
class Solution {
public:
int minDeletions(string s) {
map<int,int>mp,mp1;
int l = s.size();
int cnt = 0;
int a[55],b[55],mmax = 0;
memset(a,0,sizeof(a));
for(int i = 0; i < l; i++){
int k = s[i] - 'a'+1;
a[k]++;
mmax = max(a[k],mmax);
}
int t = 0;
for(int i = 1; i <= 26; i++){
if(a[i]){
b[t++] = a[i];
mp[a[i]]++;
};
}
sort(b,b+t);
// cout << mp[3] << endl;
for(int i = t-1; i >= 0; i--){
if(mp[b[i]] >= 2){
mp[b[i]]--;
b[i]--;
cnt++;
while(mp1[b[i]]){
b[i]--;
cnt++;
}
if(b[i] != 0) mp1[b[i]]++,mp[b[i]]++;
}
}
return cnt;
}
}; 和为奇数的子数组数目:前缀和
https://leetcode-cn.com/problems/number-of-sub-arrays-with-odd-sum/
思路:
1:奇数=奇数-偶数,奇数=偶数-奇数
2:所有可以先把前缀和算出来,判断当前前缀和是奇数还是偶数,如果是奇数的话则加上前面前缀和是偶数的个数,因为按照上面的结论我们可以利用前缀和相减去获得前面那部分所有连续子数组和为奇数的个数,即:奇数=奇数-偶数,同时我们还不能忘了+1,因为当前前缀和也是奇数。如果是偶数的话也是一样的。
class Solution {
public:
int mod = 1e9+7;
int numOfSubarrays(vector<int>& arr) {
int j_num,o_num,num;
int sum[100005] = {0};
j_num = o_num = num = 0;
sum[0] = arr[0];
if(sum[0] % 2 == 0){
o_num++;
num = (num + j_num) % mod;
}
else{
j_num++;
num = (num + o_num) % mod + 1;
}
for(int i = 1; i < arr.size(); i++){
sum[i] = sum[i - 1] + arr[i];
if(sum[i] % 2 == 0){
o_num++;
num = (num + j_num) % mod;
}
else{
j_num++;
num = (num + o_num) % mod + 1;
}
}
return num;
}
}; 字符串的好分割数目:前缀和+map
https://leetcode-cn.com/problems/number-of-good-ways-to-split-a-string/
思路:
1:首先我们冲击以每个字符结尾的子字符串中有多少个不同的字符。
2:统计方法:前缀和sum[],假设当前字符为a,首先判断mp[a]是否为零,如果为零说明之前还未出现字符a,那么就让sum[i]+1,mp[a]++,否则说明之前已经出现了字符a,sum[i]=sum[i-1]。
3:然后以字符串中的每个字符作为前一段字符串的最后一个字符,该字符的后一个字符作为后一段字符串的第一个字符,依次去判断两段不同字符数目是否相等。
4:判断方法:假设当前字符为a,前一段字符串不同字符的数目已经算出来了,就是sum[i],统计后一段之前要让mp[a]--,判断mp[a]是否为零,为零说明后一段里面已经没有了字符a,则让sum[len]-1,那为什么不是sum[len]-sum[i]呢,因为我们是从第一个字符依次判断过来的。
class Solution {
public:
int numSplits(string s) {
map<string,int>mp;
int sum[100005] = {0};
sum[0] = 1;
string t;
t += s[0];
mp[t]++;
for(int i = 1; i < s.size(); i++){
string k;
k += s[i];
if(mp[k] == 0){
sum[i] = sum[i - 1] + 1;
mp[k]++;
}
else{
sum[i] = sum[i - 1];
mp[k]++;
}
}
int ans = 0,len,temp;
len = s.size() - 1;
temp = sum[len];
for(int i = 0; i < s.size() - 1; i++){
string k;
k += s[i];
mp[k]--;
if(mp[k] <= 0) temp = sum[len] - 1;
if(sum[i] == temp) ans++;
}
return ans;
}
}; 第199场周赛:https://leetcode-cn.com/contest/weekly-contest-199/
灯泡开关IV:找规律
https://leetcode-cn.com/problems/bulb-switcher-iv/
思路:
1:看样例:10111,初始串00000,遍历target串,只要对比不同我们就翻转,比如第一个1和0不同,翻转为11111,第二个为0和1,翻转为10000,第三个为1和0,翻转为10111,三步完成。
2:而我们可以发现我们不需要真的去翻转,因为当前翻转得到的字符和后面是一样的,所有我们用一个字符a去代替后面所有的字符即可。
class Solution {
public:
int minFlips(string target) {
char a = '0';
int ans = 0;
for(int i = 0; i < target.size(); i++){
if(target[i] != a){
ans++;
a = a == '0' ? '1' : '0';
}
}
return ans;
}
}; 第34场双周赛
https://leetcode-cn.com/contest/biweekly-contest-34/
删除最短子数组使得剩余数有序
https://leetcode-cn.com/problems/shortest-subarray-to-be-removed-to-make-array-sorted/
思路:
先看图片:
剩余数的部分只可能是
1)A段,删除B和C段。
2)C段,删除A和B段。
3)A的前一部分加上C的后一部分,删掉中间部分。
class Solution {
public:
int findLengthOfShortestSubarray(vector<int>& a) {
int n = a.size(),t1,t2,ans;
t1 = t2 = ans = 0;
int i;
for(i = 0; i < n - 1; i++){
if(a[i] > a[i + 1])
{
t1 = i + 1;
break;
}
}
if(!t1 && i == n - 1) return 0;
ans = max(ans,t1);
//cout << ans << endl;
t2 = n - 1;
for(int i = n - 1; i > 0; i--){
if(a[i] < a[i - 1]){
t2 = i - 1;
break;
}
}
// cout << t2 << endl;
ans = max(ans,n - t2 - 1);
int t = t1;
//cout << ans << endl;
int j = n - 1;
for(i = t1 - 1; i >= 0; i--){
while(j > t2){
if(a[i] <= a[j]){
t++;
ans = max(ans,t);
j--;
}
else break;
}
t--;
}
return n - ans;
}
};
第205场周赛
2
class Solution {
public:
int numTriplets(vector<int>& nums1, vector<int>& nums2) {
int n1,n2;
n1 = nums1.size();
n2 = nums2.size();
map<long long,long long>mp1,mp2;
long long temp;
for(int i = 0; i < n1; i++){
for(int j = i + 1; j < n1; j++){
temp = (long long)nums1[i] * nums1[j];
mp1[temp]++;
}
}
for(int i = 0; i < n2; i++){
for(int j = i + 1; j < n2; j++){
temp = (long long)nums2[i] * nums2[j];
mp2[temp]++;
}
}
int ans = 0;
//cout << mp2.count(1) << endl;
for(int i = 0; i < n2; i++){
long long k = (long long)nums2[i] * nums2[i];
ans += (mp1.count(k) == 1 ? mp1[k] : 0);
}
for(int i = 0; i < n1; i++){
long long k = (long long)nums1[i] * nums1[i];
// cout << k << " ";
// cout << mp2.count(k) << " ";
ans += (mp2.count(k) == 1 ? mp2[k] : 0);
}
return ans;
}
}; 3
class Solution {
public:
int minCost(string s, vector<int>& cost) {
int l = s.length();
int n = cost.size();
int mmax = 0;
int c[100005];
int len[100005];
int sum[100005];
sum[0] = cost[0];
for(int i = 1; i < n; i++){
sum[i] = sum[i - 1] + cost[i];
}
s += ' ';
int cnt = 1;
for(int i = 0; i < l; i++){
if(s[i] == s[i + 1]){
cnt++;
mmax = max(mmax,cost[i]);
}
else{
mmax = max(mmax,cost[i]);
c[i] = mmax;
len[i] = cnt;
mmax = 0;
cnt = 1;
}
}
int ans = 0;
//cout << c[4] << endl;
for(int i = 0; i < l; i++){
if(s[i] != s[i + 1]){
if(len[i] > 1){
int temp = i - len[i] + 1;
if(temp == 0) ans += sum[i] - c[i];
else
ans += sum[i] - sum[temp - 1] - c[i];
}
//cout << ans << endl;
}
}
return ans;
}
}; 第206场周赛
2
class Solution {
public:
bool check(int num[1005][1005],int x,int y,int p[],int n){
for(int i = 0; i < n; i++){
if(num[x][y] < num[x][i] && num[i][x] > num[i][p[i]]) return false;
}
return true;
}
int unhappyFriends(int n, vector<vector<int>>& preferences, vector<vector<int>>& pairs) {
int num[1005][1005];
int p[1005];
for(int i = 0; i < n; i++){
for(int j = 0; j < n - 1; j++){
num[i][preferences[i][j]] = n - j;
}
}
for(int i = 0; i < n / 2; i++){
p[pairs[i][0]] = pairs[i][1];
p[pairs[i][1]] = pairs[i][0];
}
int ans = 0;
for(int i = 0; i < n; i++){
if(!check(num,i,p[i],p,n)){
ans++;
}
}
return ans;
}
}; 
