前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >LeetCode(Weekly Contest 188)题解

LeetCode(Weekly Contest 188)题解

作者头像
西凉风雷
发布2022-11-23 19:44:31
1720
发布2022-11-23 19:44:31
举报

0. 前言

1. 题解

1.1 5404. 用栈操作构建数组(1441. Build an Array With Stack Operations)

代码语言:javascript
复制
class Solution {
public:
    vector<string> buildArray(vector<int>& target, int n) {
        int cur = 0, cnt = target.size();
        vector<string> ans;
        for (int i = 1 ; i <= n ; i++) {
            if (cur == cnt)   break;
            if (target[cur] == i) {
                ans.push_back("Push");
                cur++;
            } else {
                ans.push_back("Push");
                ans.push_back("Pop");
            }
        }
        return ans;
    }
};

1.2 5405. 形成两个异或相等数组的三元组数目(1442. Count Triplets That Can Form Two Arrays of Equal XOR)

代码语言:javascript
复制
class Solution {
public:
    int countTriplets(vector<int>& arr) {
        int n = arr.size();
        vector<int> xors = vector<int>(n+1, 0);
        xors[1] = arr[0];
        for (int i = 2 ; i <= n ; i++) {
            xors[i] = arr[i-1] ^ xors[i-1];
        }
        int ans = 0;
        for (int i = 0 ; i < n ; i++) {
            for (int j = i+1 ; j < n ; j++) {
                for (int k = j ; k < n ; k++) {
                    if (xors[j] ^ xors[i] == xors[k+1] ^ xors[j]) {
                        ans++;
                    }
                }
            }
        }
        return ans;
    }
};
  • 哈希代码如下:
代码语言:javascript
复制
class Solution {
public:
    int countTriplets(vector<int>& arr) {
        int n = arr.size();
        unordered_map<int, vector<int>> cnt;
        int x = 0, ans = 0;
        cnt[0] = vector<int>();
        cnt[0].push_back(0);
        for (int i = 1 ; i <= n ; i++) {
            x ^= arr[i-1];
            if (cnt.find(x) == cnt.end()) {
                cnt[x] = vector<int>();
            }
            for (auto j : cnt[x]) {
                // cout << j+1 << "->" << i << endl;
                ans += (i - j - 1);
            }
            cnt[x].push_back(i);
        }
        return ans;
    }
};

1.3 5406. 收集树上所有苹果的最少时间(1443. Minimum Time to Collect All Apples in a Tree)

代码语言:javascript
复制
class Solution {
public:
    bool dfs1(int cur, vector<vector<int>>& adj, vector<bool>& hasApple, vector<bool>& need) {
        need[cur] = hasApple[cur];
        if (0 == (int)adj[cur].size()) {
            return need[cur];
        }
        for (auto next : adj[cur]) {
            if (dfs1(next, adj, hasApple, need)) {
                need[cur] = true;
            }
        }
        return need[cur];
    }
    int dfs2(int cur, vector<vector<int>>& adj, vector<bool>& need, vector<int>& dp) {
        if (0 == (int)adj[cur].size()) {
            return 0;
        }
        cout << cur << endl;
        if (dp[cur])    return dp[cur];
        for (auto next : adj[cur]) {
            if (!need[next])    continue;
            // cout << cur << "->" << next << endl;
            dp[cur] += 2 + dfs2(next, adj, need, dp);
            // cout << "dp[" << cur << "] = " << dp[cur] << endl;
        }
        return dp[cur];
    }
    int minTime(int n, vector<vector<int>>& edges, vector<bool>& hasApple) {
        vector<int> dp = vector<int>(n, 0);
        vector<bool> need = vector<bool>(n, false);
        vector<vector<int>> adj = vector<vector<int>>(n, vector<int>());
        for (auto v : edges) {
            adj[v[0]].push_back(v[1]); 
        }
        dfs1(0, adj, hasApple, need);
        dfs2(0, adj, need, dp);
        return dp[0];
    }
};
  • 七行代码方法如下:
代码语言:javascript
复制
class Solution {
public:
    int minTime(int n, vector<vector<int>>& edges, vector<bool>& hasApple) {
        for (int i = (int)edges.size()-1 ; i >= 0 ; i--) {
            if (hasApple[edges[i][1]] == true) {
                hasApple[edges[i][0]] = true;
            }
        }
        int ans = 0;
        for (int i = (int)edges.size()-1 ; i >= 0 ; i--) {
            if (hasApple[edges[i][1]]) ans += 2;
        }
        return ans;
    }
};

1.4 5407. 切披萨的方案数(1444. Number of Ways of Cutting a Pizza)

  • 中文版题目描述:https://leetcode-cn.com/problems/number-of-ways-of-cutting-a-pizza/
  • 英文版题目描述:https://leetcode.com/problems/number-of-ways-of-cutting-a-pizza/
  • 思路:dp,dp[i][j][k] 表示切了 k-1 刀,剩余披萨左上角第 i 行 j 列为左上角的切法数量,初始化 dp[1][1][1] = 1
    • 二层遍历剩余左上角,然后逐行判断是否可以切,在更新以切口处为左上角的披萨,切了 k 刀的切法,然后再逐列切,方法同上,复杂度为 O(N^4)
    • 判断切口两端是否 'A',可以通过容斥原理计算,nums[i][j] 表示以第 i 行 j 列为右下角,第 1 行 1 列为左上角的 'A' 大数量
  • 二分法代码如下:
代码语言:javascript
复制
class Solution {
public:
    int numA(int r, int c, vector<vector<int>>& nums, int ru, int cu) {
        // cout << "numA:" << ru << " " << cu << " " << r << " " << c << endl;
        // cout << nums[r][c] << "-" << nums[ru-1][c] << "-" << nums[r][cu-1] << "-" << nums[ru-1][cu-1] << endl;
        return nums[r][c] - (nums[ru-1][c] + nums[r][cu-1] - nums[ru-1][cu-1]);
    }
    int ways(vector<string>& pizza, int k) {
        int  r = (int)pizza.size(), c = (int)pizza[0].length(), mod = 1000000007;
        vector<vector<int>> nums = vector<vector<int>>(r+1, vector<int>(c+1, 0));
        for (int i = 1 ; i <= r ; i++) {
            for (int j = 1 ; j <= c ; j++) {
                nums[i][j] = nums[i-1][j] + nums[i][j-1] - nums[i-1][j-1] + (int)(pizza[i-1][j-1] == 'A');
            }
        }
        vector<vector<vector<int>>> dp = vector<vector<vector<int>>>(r+1, vector<vector<int>>(c+1, vector<int>(k+1)));
        dp[1][1][1] = 1;
        for (int cut = 2 ; cut <= k ; cut++) {
            for (int i = 1 ; i <= r ; i++) {
                for (int j = 1 ; j <= c ; j++) {
                    if (dp[i][j][cut-1] == 0) continue;
                    int cntIJ = numA(r, c, nums, i , j);
                    for (int l = i ; l < r ; l++) {
                        int cntLJ = numA(r, c, nums, l+1, j);
                        if (cntIJ - cntLJ > 0 && cntLJ > 0) {
                            dp[l+1][j][cut] +=  dp[i][j][cut-1];
                            dp[l+1][j][cut] %= mod;
                        }
                    }
                    for (int l = j ; l < c ; l++) {
                        int cntIL = numA(r, c, nums, i, l+1);
                        if (cntIJ - cntIL > 0 && cntIL > 0) {
                            dp[i][l+1][cut] += dp[i][j][cut-1];
                            dp[i][l+1][cut] %= mod;
                        }
                    }
                }
            }
        }

        int ans = 0;
        for (int i = 1 ; i <= r ; i++) {
            for (int j = 1 ; j <= c ; j++) {
                ans += dp[i][j][k];
                ans %= mod;
            }
        }
        return ans;
    }
};

3. 参考文献 

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2020-05-10,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 0. 前言
  • 1. 题解
    • 1.1 5404. 用栈操作构建数组(1441. Build an Array With Stack Operations)
      • 1.2 5405. 形成两个异或相等数组的三元组数目(1442. Count Triplets That Can Form Two Arrays of Equal XOR)
        • 1.3 5406. 收集树上所有苹果的最少时间(1443. Minimum Time to Collect All Apples in a Tree)
          • 1.4 5407. 切披萨的方案数(1444. Number of Ways of Cutting a Pizza)
          • 3. 参考文献 
          领券
          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档