周日 | 周一 | 周二 | 周三 | 周四 | 周五 | 周六 |
---|---|---|---|---|---|---|
1 √ | 2 √ | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 √ | 15 | 16 √ | 17 × | 18 √ |
19 √ | 20 √ | 21√ | 22 × | 23 × | 24√ | 25× |
26√ | 27√ | 28√ |
统计每个月的每日1题做题情况。统计规则为:
- 若正常解题且不为暴力做法,则日期后做标记 √
- 若正常解题且为暴力做法,则日期后做标记 √
- 若无法解题,则日期后做标记 ×
1 解密消息
链接
代码
class Solution {
public:
string decodeMessage(string key, string message) {
map<char, int> mp;
for(int i = 0; i < 26; i++){
mp[key[i]] = i;
}
string ans;
for(int i = 0; i < message.length(); i++){
char ch = char(mp[message[i]] + 'a');
string s(1, ch);
cout << "mp[message[i]] = " << mp[message[i]] << " message[i] = " << message[i] << endl;
ans += s;
}
return ans;
}
};
2 颜色交替的最短路径
链接
代码
class Solution {
public:
struct point{
int node;
int last_color;
int step;
point(int n, int l, int s){node = n; last_color = l; step = s;}
};
vector<int> shortestAlternatingPaths(int n, vector<vector<int>>& redEdges, vector<vector<int>>& blueEdges) {
int G[n][n][2];
vector<int> answer(n);
for(int i = 0; i < n; i++)
for(int j = 0; j < n; j++)
for(int k = 0; k < 2; k++){
G[i][j][k] = 0;
answer[i] = 2*n;
}
for(int i = 0; i < redEdges.size(); i++)
G[redEdges[i][0]][redEdges[i][1]][0] = 1;
for(int i = 0; i < blueEdges.size(); i++)
G[blueEdges[i][0]][blueEdges[i][1]][1] = 1;
queue<point> Q;
Q.push(point(0, 0, 0));
Q.push(point(0, 1, 0));
while(!Q.empty()){
point tmp = Q.front();
Q.pop();
answer[tmp.node] = min(answer[tmp.node], tmp.step);
for(int i = 0; i < n; i++){
if(G[tmp.node][i][!tmp.last_color]){
Q.push(point(i, !tmp.last_color, tmp.step+1));
G[tmp.node][i][!tmp.last_color] = 0;
}
}
}
for(int i = 0; i < n; i++){
if(answer[i] == 2*n) answer[i] = -1;
}
return answer;
}
};
14 表现良好的最长时间段
链接
思路
代码
class Solution {
public:
int longestWPI(vector<int>& hours) {
vector<int> presum(hours.size()+1);
stack<int> stk;
stk.push(0);
presum[0] = 0;
int max_len = 0;
for(int i = 1; i < presum.size(); i++) {
if(hours[i-1] > 8)
presum[i] = presum[i-1] + 1;
else
presum[i] = presum[i-1] - 1;
if(presum[stk.top()] > presum[i]){
stk.push(i);
}
}
for(int j = hours.size(); j >= 0; j--){
while(!stk.empty()){
if(presum[j] - presum[stk.top()] > 0){
max_len = max(max_len, j - stk.top());
stk.pop();
}
else break;
}
if(stk.empty()) break;
}
return max_len;
}
};
16 数组能形成多少数对
链接
代码
class Solution {
public:
vector<int> numberOfPairs(vector<int>& nums) {
vector<int> ans;
map<int, queue<int> > mp;
bool vis[nums.size()];
for(int i = 0; i < nums.size(); i++){
mp[nums[i]].push(i);
vis[i] = false;
}
int cnt = 0;
int num = nums.size();
for(int i = 0; i < nums.size(); i++){
if(vis[i]) continue;
if(mp[nums[i]].size() >= 2){
mp[nums[i]].pop();
vis[mp[nums[i]].front()] = true;
mp[nums[i]].pop();
num -= 2;
cnt++;
}
}
ans.push_back(cnt);
ans.push_back(num);
return ans;
}
};
17 最大的以 1 为边界的正方形
链接
思路
代码
class Solution {
public:
int largest1BorderedSquare(vector<vector<int>>& grid) {
int m = grid.size();
int n = grid[0].size();
int dp[m+1][n+1][2];
for(int i = 0; i <= m; i++)
for(int j = 0; j <= n; j++)
dp[i][j][0] = dp[i][j][1] = 0;
for(int i = 1; i <= m; i++)
for(int j = 1; j <= n; j++){
if(grid[i-1][j-1] == 0) continue;
dp[i][j][0] = dp[i][j-1][0] + 1; // 行方向,从左到右
dp[i][j][1] = dp[i-1][j][1] + 1; // 列方向,从上到下
}
int max_side = 0;
for(int i = 1; i <= m; i++)
for(int j = 1; j<= n; j++){
int cur_side = min(dp[i][j][0], dp[i][j][1]);
for(int k = cur_side; k > max_side; k--){
if(i-k+1 <= 0 || j-k+1 <= 0) continue;
if(dp[i-k+1][j][0] >= k && dp[i][j-k+1][1] >= k){
max_side = max(max_side, k);
break;
}
}
}
return max_side*max_side;
}
};
18 找出给定方程的正整数解
链接
代码
class Solution {
public:
vector<vector<int>> findSolution(CustomFunction& customfunction, int z) {
vector<vector<int>> ans;
for(int i = 1; i <= 1000; i++)
for(int j = 1; j <= 1000; j++){
if(customfunction.f(i, j) == z){
vector<int> tmp;
tmp.push_back(i);
tmp.push_back(j);
ans.push_back(tmp);
}
}
return ans;
}
};
19 最大平均通过率
链接
代码
class Solution {
public:
struct tmp1{
int pass;
int total;
tmp1(int p, int t) {pass = p; total = t;}
bool operator<(const tmp1& b) const
{
double inc1 = (pass+1.0)/(total+1) - pass*1.0/total;
double inc2 = (b.pass+1.0)/(b.total+1) - b.pass*1.0/b.total;
return inc1 < inc2;
}
};
double maxAverageRatio(vector<vector<int>>& classes, int extraStudents) {
priority_queue<tmp1> q;
for(int i = 0; i < classes.size(); i++){
int pass = classes[i][0];
int total = classes[i][1];
q.push(tmp1(pass, total));
}
while(extraStudents--){
tmp1 tmp = q.top();
q.pop();
tmp.pass +=1; tmp.total += 1;
q.push(tmp);
}
double sum = 0;
while(!q.empty()){
tmp1 tmp = q.top();
sum += tmp.pass*1.0/tmp.total;
q.pop();
}
return sum/classes.size();
}
};
20 最好的扑克手牌
链接
代码
class Solution {
public:
string bestHand(vector<int>& ranks, vector<char>& suits) {
if(suits[0] == suits[1] && suits[1] == suits[2] && suits[2] == suits[3] && suits[3] == suits[4])
return "Flush";
map<int, int> mp;
int flag = 0;
for(int i = 0; i < 5; i++) mp[ranks[i]] += 1;
for(int i = 0; i < 5; i++){
if(mp[ranks[i]] >= 3) return "Three of a Kind";
if(mp[ranks[i]] == 2) flag = 1;
}
if(flag)
return "Pair";
return "High Card";
}
};
21 灌溉花园的最少水龙头数目
链接
代码
class Solution {
public:
struct Taps{
int left;
int right;
Taps(){}
Taps(int l, int r){left = l; right = r;}
};
static bool cmp(Taps p1, Taps p2){
if(p1.left != p2.left)
return p1.left < p2.left;
else
return p1.right > p2.right;
}
int minTaps(int n, vector<int>& ranges) {
struct Taps P[n+1];
int cnt = 0;
for(int i = 0; i < ranges.size(); i++){
if(ranges[i]){
int left = (i-ranges[i] >= 0)? i-ranges[i]: 0;
int right = i + ranges[i];
P[cnt++] = Taps(left, right);
}
}
sort(P, P+cnt, cmp);
if(P[0].left) return -1;
int Taps_num = 1;
int now_left = P[0].left;
int now_right = P[0].right;
int i = 1;
while(i < cnt){
if(now_right >= n) break;
int max_index = i;
int max_right = now_right;
while(P[i].left <= now_right && i < cnt){
if(P[i].right > max_right){
max_index = i;
max_right = P[i].right;
}
i++;
}
if(max_right <= now_right) return -1;
Taps_num++;
now_left = P[max_index].left;
now_right = P[max_index].right;
}
if(now_right < n) {
return -1;
}
return Taps_num;
}
};
22 石子游戏 II
链接
思路
代码
class Solution {
public:
int stoneGameII(vector<int>& piles) {
int n = piles.size();
int dp[n+1][n+1];
int sum = 0;
for(int i = n-1; i >= 0; i--){
sum += piles[i];
for(int M = 1; M <= n; M++){
if(i + 2*M >= n)
dp[i][M] = sum;
else{
dp[i][M] = 0;
for(int x = 1; x <= 2*M; x++){
dp[i][M] = max(dp[i][M], sum - dp[i+x][max(M,x)]);
}
}
}
}
return dp[0][1];
}
};
23 循环码排列
链接
思路
代码
class Solution {
public:
vector<int> circularPermutation(int n, int start) {
vector<int> p;
for(int i = 0; i < 1<<n; i++){
p.push_back(i^(i>>1)^start);
}
return p;
}
};
24 使数组中所有元素都等于零
链接
代码
class Solution {
public:
int minimumOperations(vector<int>& nums) {
int cnt = 0;
set<int> st;
for(int i = 0; i < nums.size(); i++){
if(nums[i])
st.insert(nums[i]);
}
return st.size();
}
};
25 交换字符使得字符串相同
链接
思路
代码
class Solution {
public:
int minimumSwap(string s1, string s2) {
int xy = 0;
int yx = 0;
for(int i = 0; i < s1.length(); i++){
if(s1[i] != s2[i]){
if(s1[i] == 'x') xy += 1;
else yx += 1;
}
}
int num = (xy + yx)/2;
xy %= 2; yx %= 2;
if(xy != yx) return -1;
if(xy == 1) num += 1;
return num;
}
};
26 得分最高的单词集合
链接
代码
class Solution {
public:
int maxScoreWords(vector<string>& words, vector<char>& letters, vector<int>& score) {
vector<int> count(26); // 统计letters中的所有单词分布
int n = words.size();
int sum = 0;
for(int i = 0; i < letters.size(); i++)
count[letters[i] - 'a']++;
for(int i = 0; i < (1 << n); i++){
vector<int> tmp(26); // 统计当前子集中的所有单词分布
for(int j = 0; j < n; j++){
if(i & (1 << j)){
for(int k = 0; k < words[j].size(); k++) tmp[words[j][k]- 'a']++;
}
}
int tmp_sum = 0;
int ok = 1;
for(int l = 0; l < 26; l++){
tmp_sum += tmp[l] * score[l];
ok = ok && (tmp[l] <= count[l]);
}
if(ok) sum = max(sum, tmp_sum);
}
return sum;
}
};
27 递减元素使数组呈锯齿状
链接
代码
class Solution {
public:
int sum_moves(vector<int> nums, int flag){
int len = nums.size();
int sum = 0;
for(int i = len-2; i >= 1; i--){
int min_value = min(nums[i-1], nums[i+1]);
int max_value = max(nums[i-1], nums[i+1]);
if(flag && nums[i] >= min_value) {// <
sum += nums[i] - min_value + 1;
nums[i] = min_value - 1;
}
else if(!flag && nums[i] <= max_value){
if(nums[i] <= nums[i-1]){
sum += nums[i-1] - nums[i] + 1;
nums[i-1] = nums[i] - 1;
}
if(nums[i] <= nums[i+1]){
sum += nums[i+1] - nums[i] + 1;
nums[i+1] = nums[i] - 1;
}
}
flag = !flag;
}
return sum;
}
int movesToMakeZigzag(vector<int>& nums) {
return min(sum_moves(nums, 1), sum_moves(nums, 0));
}
};
28 合并相似的物品
链接
代码
class Solution {
public:
vector<vector<int>> mergeSimilarItems(vector<vector<int>>& items1, vector<vector<int>>& items2) {
map<int, int> mp;
for(int i = 0; i < items1.size(); i++){
mp[items1[i][0]] += items1[i][1];
}
for(int i = 0; i < items2.size(); i++){
mp[items2[i][0]] += items2[i][1];
}
vector<vector<int>> ans;
for(auto p: mp){
vector<int> tmp;
tmp.push_back(p.first);
tmp.push_back(p.second);
ans.push_back(tmp);
}
return ans;
}
};