zoukankan      html  css  js  c++  java
  • LeetCode 第 222 场周赛

    1710.卡车上的最大单元数

    题目链接:1710.卡车上的最大单元数

    请你将一些箱子装在 一辆卡车 上。给你一个二维数组 boxTypes ,其中 boxTypes[i] = [numberOfBoxesi, numberOfUnitsPerBoxi]

    • numberOfBoxesi 是类型 i 的箱子的数量。
    • numberOfUnitsPerBoxi 是类型 i 每个箱子可以装载的单元数量。

    整数 truckSize 表示卡车上可以装载 箱子最大数量 。只要箱子数量不超过 truckSize
    ,你就可以选择任意箱子装到卡车上。

    返回卡车可以装载 单元最大 总数

    示例 Sample

    示例 1:

    **输入:** boxTypes = [[1,3],[2,2],[3,1]], truckSize = 4
    **输出:** 8
    **解释:** 箱子的情况如下:
    - 1 个第一类的箱子,里面含 3 个单元。
    - 2 个第二类的箱子,每个里面含 2 个单元。
    - 3 个第三类的箱子,每个里面含 1 个单元。
    可以选择第一类和第二类的所有箱子,以及第三类的一个箱子。
    单元总数 = (1 * 3) + (2 * 2) + (1 * 1) = 8
    

    示例 2:

    **输入:** boxTypes = [[5,10],[2,5],[4,7],[3,9]], truckSize = 10
    **输出:** 91
    

    提示:

    • 1 <= boxTypes.length <= 1000
    • 1 <= numberOfBoxesi, numberOfUnitsPerBoxi <= 1000
    • 1 <= truckSize <= 106

    我的题解

    排序贪心即可。

    class Solution {
     public:
      int maximumUnits(vector<vector<int>>& boxTypes, int truckSize) {
        sort(boxTypes.begin(), boxTypes.end(), [&](auto a, auto b) { return a[1] > b[1]; });
        int ans(0);
        for (int i = 0; i < boxTypes.size(); i++) {
          int x = min(boxTypes[i][0], truckSize);
          ans += boxTypes[i][1] * x;
          truckSize -= x;
        }
        return ans;
      }
    };
    

    1711.大餐计数

    题目链接:1711.大餐计数

    大餐 是指 恰好包含两道不同餐品 的一餐,其美味程度之和等于 2 的幂。

    你可以搭配 任意 两道餐品做一顿大餐。

    给你一个整数数组 deliciousness ,其中 deliciousness[i] 是第 i​​​​​​​​​​​​​​
    道餐品的美味程度,返回你可以用数组中的餐品做出的不同 大餐 的数量。结果需要对 109 + 7 取余。

    注意,只要餐品下标不同,就可以认为是不同的餐品,即便它们的美味程度相同。

    示例 Sample

    示例 1:

    **输入:** deliciousness = [1,3,5,7,9]
    **输出:** 4
    **解释:** 大餐的美味程度组合为 (1,3) 、(1,7) 、(3,5) 和 (7,9) 。
    它们各自的美味程度之和分别为 4 、8 、8 和 16 ,都是 2 的幂。
    

    示例 2:

    **输入:** deliciousness = [1,1,1,3,3,3,7]
    **输出:** 15
    **解释:** 大餐的美味程度组合为 3 种 (1,1) ,9 种 (1,3) ,和 3 种 (1,7) 。
    

    提示:

    • 1 <= deliciousness.length <= 105
    • 0 <= deliciousness[i] <= 220

    我的题解

    有卡常 ……

    class Solution {
     public:
      int countPairs(vector<int>& deliciousness) {
        const int maxn = (1 << 21) + 7;
        int g[maxn] = {0};
        int ans(0);
        const int MOD = 1e9 + 7;
        const int n = deliciousness.size();
        for (int i : deliciousness) g[i]++;
        set<int> s;
        for (int i : deliciousness) s.insert(i);
        for (int i = 1; i <= (1 << 21); (i <<= 1)) {
          for (int a : s) {
            int b = i - a;
            if (a < b)
              ans = (ans + g[a] * g[b]) % MOD;
            else if (a == b)
              ans = (ans + g[a] * (g[b] - 1ll) / 2) % MOD;
          }
        }
        return ans;
      }
    };
    

    1712.将数组分成三个子数组的方案数

    题目链接:1712.将数组分成三个子数组的方案数

    我们称一个分割整数数组的方案是 好的 ,当它满足:

    • 数组被分成三个 非空 连续子数组,从左至右分别命名为 leftmidright
    • left 中元素和小于等于 mid 中元素和,mid 中元素和小于等于 right 中元素和。

    给你一个 非负 整数数组 nums ,请你返回 好的 分割 nums 方案数目。由于答案可能会很大,请你将结果对 109 + 7
    取余后返回。

    示例 Sample

    示例 1:

    **输入:** nums = [1,1,1]
    **输出:** 1
    **解释:** 唯一一种好的分割方案是将 nums 分成 [1] [1] [1] 。
    

    示例 2:

    **输入:** nums = [1,2,2,2,5,0]
    **输出:** 3
    **解释:** nums 总共有 3 种好的分割方案:
    [1] [2] [2,2,5,0]
    [1] [2,2] [2,5,0]
    [1,2] [2,2] [5,0]
    

    示例 3:

    **输入:** nums = [3,2,1]
    **输出:** 0
    **解释:** 没有好的分割方案。
    

    提示:

    • 3 <= nums.length <= 105
    • 0 <= nums[i] <= 104

    我的题解

    二分

    class Solution {
     public:
      int waysToSplit(vector<int>& nums) {
        const int n = nums.size();
        vector<int> s(n);
        for (int i = 0; i < n; ++i) {
          s[i] = nums[i] + (i ? s[i - 1] : 0);
        }
        int ans(0);
        const int MOD = 1e9 + 7;
        for (int i = 0; i < n - 2 && s[i] <= s[n - 1] / 3; i++) {
          int l, r;
          l = lower_bound(s.begin(), s.end(), s[i] * 2) - s.begin();
          l = max(i + 1, l);
          r = upper_bound(s.begin(), s.end(), s[i] + (s[n - 1] - s[i]) / 2) - s.begin();
          r = min(n - 1, max(r, i + 1));
          ans = (ans + r - l) % MOD;
        }
        return ans;
      }
    };
    

    双指针(Y总太强啦)。只考虑了 left 和 mid 的分隔,没有单调性。但是,考虑 mid 和 right 的分隔时,left 和 mid 的分隔可以双指针。

    class Solution {
     public:
      int waysToSplit(vector<int>& nums) {
        int n = nums.size();
        const int mod = 1e9 + 7;
        vector<int> s(n + 1);
        for (int i = 1; i <= n; i++) s[i] = s[i - 1] + nums[i - 1];
        int ans = 0;
        for (int i = 3, j = 2, k = 2; i <= n; i++) {
          while (s[n] - s[i - 1] < s[i - 1] - s[j - 1]) j++;
          while (k + 1 < i && s[i - 1] - s[k] >= s[k]) k++;
          if (j <= k && s[n] - s[i - 1] >= s[i - 1] - s[j - 1] && s[i - 1] - s[k - 1] >= s[k - 1])
            ans = (ans + k - j + 1) % mod;
        }
        return ans;
      }
    };
    

    1713.得到子序列的最少操作次数

    题目链接:1713.得到子序列的最少操作次数

    给你一个数组 target ,包含若干 互不相同 的整数,以及另一个整数数组 arrarr 可能 包含重复元素。

    每一次操作中,你可以在 arr 的任意位置插入任一整数。比方说,如果 arr = [1,4,1,2] ,那么你可以在中间添加 3 得到
    [1,4, **3** ,1,2] 。你可以在数组最开始或最后面添加整数。

    请你返回 最少 操作次数,使得 __target __ 成为 arr 的一个子序列。

    一个数组的 子序列 指的是删除原数组的某些元素(可能一个元素都不删除),同时不改变其余元素的相对顺序得到的数组。比方说,[2,7,4]
    [4, **2** ,3, **7** ,2,1, **4** ] 的子序列(加粗元素),但 [2,4,2] 不是子序列。

    示例 Sample

    示例 1:

    **输入:** target = [5,1,3], arr = [9,4,2,3,4]
    **输出:** 2
    **解释:** 你可以添加 5 和 1 ,使得 arr 变为 [ **5** ,9,4, **1** ,2,3,4] ,target 为 arr 的子序列。
    

    示例 2:

    **输入:** target = [6,4,8,1,3,2], arr = [4,7,6,2,3,8,6,1]
    **输出:** 3
    

    提示:

    • 1 <= target.length, arr.length <= 105
    • 1 <= target[i], arr[i] <= 109
    • target 不包含任何重复元素。

    我的题解

    满足唯一性时,LCS(最长公共子序列) 转为 LIS (最长上升子序列)。
    知识点++。

    class Solution {
     public:
      int minOperations(vector<int>& target, vector<int>& arr) {
        unordered_map<int, int> pos;
        for (int i = 0; i < target.size(); i++) pos[target[i]] = i;
        vector<int> a;
        for (int x : arr) {
          if (pos.count(x)) a.emplace_back(pos[x]);
        }
        int len = 0;
        vector<int> q(a.size() + 1);
        for (int i = 0; i < a.size(); i++) {
          int l = 0, r = len, mid;
          while (l < r) {
            mid = l + r + 1 >> 1;
            if (q[mid] < a[i])
              l = mid;
            else
              r = mid - 1;
          }
          len = max(len, r + 1);
          q[r + 1] = a[i];
        }
        return target.size() - len;
      }
    };
    
  • 相关阅读:
    ”锁“-LockSupport深入浅出
    python利器之切片
    i 是一个修饰符 (搜索不区分大小写)
    react ---- svg(绘图---桑葚图)
    react---后台管理系统推荐(ant disgin)
    vue____后台管理系统搭建(推荐,懒得自己写了)
    H5 -- 简单的 跳转下载APP(自备份留存)
    小程序UI框架推荐----自用备份---colorUI
    H5-----注册 示例
    H5 ---- 地图--周边搜索
  • 原文地址:https://www.cnblogs.com/Forgenvueory/p/14232455.html
Copyright © 2011-2022 走看看