405周赛记录
- #1.leetcode100339_找出加密后的字符串
- 2.leetcode100328_生成不含相邻零的二进制字符串
- 3.leetcode100359_统计X和Y频数相等的子矩阵数量
- 4.leetcode100350_最小代价构造字符串
刷了一段时间算法了,打打周赛看看什么水平了
#1.leetcode100339_找出加密后的字符串
思路:感觉还是挺简单的,第一次还以为是字典序的后k位,审题不认真。。。
偷了个懒,忘记怎么原地修改数组了,感觉要用辅助空间,还是直接库函数吧
用后k位字符替换,其实就是把后k位提前嘛
1,2,... ,k-1,k,k+1,...,size
1+k,k,... ,size,1,2,...,k
cpp
string getEncryptedString(string s, int k) {
k = k % s.size();
return s.substr(k, s.size()) + s.substr(0, k);
}
2.leetcode100328_生成不含相邻零的二进制字符串
思路:回溯,如果当前是0,下一个就不是0,除此之外,下一个都可以是1
cpp
class Solution {
vector<string> res;
string path;
public:
void backtracking(int n) {
if(path.size() == n) {
res.push_back(path);
return;
}
if(path == "" || path.back() != '0') {
path += '0';
backtracking(n);
path.pop_back();
}
path += '1';
backtracking(n);
path.pop_back();
return;
}
vector<string> validStrings(int n) {
res.clear();
path.clear();
backtracking(n);
return res;
}
};
3.leetcode100359_统计X和Y频数相等的子矩阵数量
思路:动态规划吧,dp[i] = dp[i-1][j-1] + (dp[i-1][j] - dp[i-1][j-1]) + (dp[i][j-1] - dp[i-1][j-1])
大概思路就是以示例1为例
dp[i][j]初始化为1; 更新为2
cpp
// dp[i][j] 表示 从左上角开始长为i宽为j的矩形所含有的 x和 y的数量
class Solution {
public:
int numberOfSubmatrices(vector<vector<char>>& grid) {
int m = grid.size();
int n = grid[0].size();
vector<vector<pair<int, int>>> dp(m, vector<pair<int, int>>(n, {0, 0}));
if(grid[0][0] == 'X'){
dp[0][0].first = 1;
} else if(grid[0][0] == 'Y') {
dp[0][0].second = 1;
}
for(int i = 1; i < m; i++){
dp[i][0] = dp[i-1][0];
if(grid[i][0] == 'X'){
dp[i][0].first++;
} else if(grid[i][0] == 'Y') {
dp[i][0].second++;
}
}
for(int j = 1; j < n; j++){
dp[0][j] = dp[0][j-1];
if(grid[0][j] == 'X'){
dp[0][j].first++;
} else if(grid[0][j] == 'Y') {
dp[0][j].second++;
}
}
// cout << "1. === \n";
// for(int i = 0; i < m; i++) {
// for(int j = 0; j < n; j++){
// cout << "(" << dp[i][j].first << "," << dp[i][j].second << "), ";
// }
// cout << endl;
// }
for(int i = 1; i < m; i++)
for(int j = 1; j < n; j++) {
dp[i][j].first = dp[i][j-1].first + dp[i-1][j].first - dp[i-1][j-1].first;
dp[i][j].second = dp[i][j-1].second + dp[i-1][j].second - dp[i-1][j-1].second;
if(grid[i][j] == 'X'){
dp[i][j].first++;
}
else if(grid[i][j] == 'Y'){
dp[i][j].second++;
}
}
int res = 0;
// cout << "2. === \n";
// for(int i = 0; i < m; i++) {
// for(int j = 0; j < n; j++){
// cout << "(" << dp[i][j].first << "," << dp[i][j].second << "), ";
// }
// cout << endl;
// }
for(int i = 0; i < m; i++)
for(int j = 0; j < n; j++){
if(dp[i][j].first != 0 && dp[i][j].first == dp[i][j].second)
res++;
}
return res;
}
};
还行,差不多一个半小时做了三道题,比以前能强点,比最近一年强很多😀
4.leetcode100350_最小代价构造字符串
思路:困难题,看到就想放弃了,但是想一想吧。。
我的理解是像是一个完全背包问题,但又不完全是,
分两步,第一步看能不能组成字符串,这里想不到,感觉回溯了
第二部算最少花费,这里属于完全背包了
cost[i]花费,
-
有感觉有点像模式串匹配呀,是不是next数组能用上呢
-
没思路。。。