今天周赛就是暴力出奇迹。。。
1221. Split a String in Balanced Strings
类似于括号匹配,不用括号匹配做也行,用sum统计遇到L,++,else --,sum == 0就为一个子串。
class Solution {
public:
int balancedStringSplit(string s) {
stack<char> st;
st.push(s[0]);
int re = 0;
for (int i = 1; i < s.size(); i++) {
if (!st.empty() && s[i] != st.top())
st.pop();
else
st.push(s[i]);
if (st.empty())
re++;
}
return re;
}
};
1222. Queens That Can Attack the King
其实就是搜索king的八个方向是否有queen有且是第一次出现即合法
class Solution {
bool marked[8][8] = {false};
public:
vector<vector<int>> queensAttacktheKing(vector<vector<int>>& queens, vector<int>& king) {
vector<vector<int>> re;
for (auto queen : queens)
marked[queen[0]][queen[1]] = true;
for (int dx = -1; dx <= 1; dx++) {
for (int dy = -1; dy <= 1; dy++) {
if (dx == 0 && dy == 0)
continue;
int x = king[0] + dx;
int y = king[1] + dy;
while (x >= 0 && x < 8 && y >= 0 && y < 8) {
if (marked[x][y]) {
re.push_back({x,y});
break;
}
x += dx;
y += dy;
}
}
}
return re;
}
};
1223. Dice Roll Simulation
掷骰子,有个rollMax数组限制了每个点数连续出现次数。就是递推结果。
设
d
p
[
i
]
[
j
]
[
k
]
dp[i][j][k]
dp[i][j][k] 为第i次,投出j,并且j已经连续出现k次了。
这样的关系式可以分为两种情况讨论。
- k = 1,即第一次连续出现,那这个状态可以这样写:
d
p
[
i
]
[
j
]
[
1
]
=
c
n
t
−
d
p
[
i
−
1
]
[
j
]
[
k
]
(
k
∈
2...
r
o
l
l
M
a
x
[
j
]
)
dp[i][j][1] = cnt - dp[i - 1][j][k] (k \in 2 .. .rollMax[j])
dp[i][j][1]=cnt−dp[i−1][j][k](k∈2...rollMax[j])
其中cnt是上一个所有状态总计。排除他不能转移的状态即可 - k > 1 ,只有一种可能 d p [ i ] [ j ] [ k ] = d p [ i − 1 ] [ j ] [ k − 1 ] dp[i][j][k] = dp[i - 1][j][k - 1] dp[i][j][k]=dp[i−1][j][k−1]
int dp[5010][6][16];
int MOD = 1e9 + 7;
class Solution {
public:
int dieSimulator(int n, vector<int>& rollMax) {
memset(dp, 0, sizeof(dp));
for (int i = 0; i < 6; i++)
dp[1][i][1] = 1;
for (int i = 2; i <= n; i++) {
int cnt = 0;
for (int j = 0; j < 6; j++) {
for (int k = 1; k <= rollMax[j]; k++) {
cnt = (cnt + dp[i - 1][j][k]) % MOD;
}
}
for (int j = 0; j < 6; j++) {
dp[i][j][1] += cnt;
for (int k = 1; k <= rollMax[j]; k++) {
dp[i][j][1] = (dp[i][j][1] - dp[i - 1][j][k] + MOD) % MOD; //负值处理
}
for (int k = 2; k <= rollMax[j]; k++) {
dp[i][j][k] = dp[i - 1][j][k - 1];
}
}
}
int re = 0;
for (int i = 0; i < 6; i++) {
for (int j = 1; j <= rollMax[i]; j++) {
re = (re + dp[n][i][j]) % MOD;
}
}
return re;
}
};
注意 d p [ i ] [ j ] [ 1 ] = ( d p [ i ] [ j ] [ 1 ] − d p [ i − 1 ] [ j ] [ k ] + M O D ) dp[i][j][1] = (dp[i][j][1] - dp[i - 1][j][k] + MOD) % MOD dp[i][j][1]=(dp[i][j][1]−dp[i−1][j][k]+MOD),因为之前相加的时候模掉了大于MOD的数,也就是减的时候可能为负,需要处理一下。
1224. Maximum Equal Frequency
判断前缀是否合法,要求是删去一个数,剩下的前缀数出现频率相同。也是分情况。需要两个map记录信息,mp记录出现某个频率的次数,mpp记录哪个数出现的次数。
class Solution {
public:
int maxEqualFreq(vector<int>& nums) {
unordered_map<int, int> mp;
unordered_map<int, int> mpp;
int re = 0;
for (int i = 0; i < nums.size(); i++) {
int temp = nums[i];
if (mpp.count(temp)) {
int f = mpp[temp];
mp[f]--;
if (mp[f] == 0)
mp.erase(f);
mp[f + 1]++;
mpp[temp]++;
} else {
mpp[temp]++;
mp[1]++;
}
if (mp.size() == 1 && i < nums.size() - 1) {
re = max(re, i + 2);
}
if (mp.size() == 2) {
auto a = mp.begin();
auto b = ++mp.begin();
if (a->first == 1 && a->second == 1)
re = max(re, i + 1);
if (b->first == 1 && b->second == 1)
re = max(re, i + 1);
if (a->first == 1 + b->first && a->second == 1)
re = max(re, i + 1);
if (b->first == 1 + a->first && b->second == 1)
re = max(re, i + 1);
}
}
return re;
}
};
当出现频率种类为1,即可直接判断有效。
当出现频率种类为2,有如下情况:
- 出现了一个频率为1,且频率为1次数也为1,删去则合法
- 出现两个频率之间差值为,并且较大的频率次数为1