LeetCode每日1题——2023.02

周日周一周二周三周四周五周六
1 2 34
567891011
121314 1516 17 ×18
19 20 2122 ×23 ×2425×
262728

统计每个月的每日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;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值