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

    5605.检查两个字符串数组是否相等

    题目链接:5605.检查两个字符串数组是否相等

    给你两个字符串数组 word1word2 。如果两个数组表示的字符串相同,返回 __true __ ;否则,返回 false

    数组表示的字符串 是由数组中的所有元素 按顺序 连接形成的字符串。

    示例 Sample

    示例 1:

    **输入:** word1 = ["ab", "c"], word2 = ["a", "bc"]
    **输出:** true
    **解释:**
    word1 表示的字符串为 "ab" + "c" -> "abc"
    word2 表示的字符串为 "a" + "bc" -> "abc"
    两个字符串相同,返回 true
    

    示例 2:

    **输入:** word1 = ["a", "cb"], word2 = ["ab", "c"]
    **输出:** false
    

    示例 3:

    **输入:** word1  = ["abc", "d", "defg"], word2 = ["abcddefg"]
    **输出:** true
    

    提示:

    • 1 <= word1.length, word2.length <= 103
    • 1 <= word1[i].length, word2[i].length <= 103
    • 1 <= sum(word1[i].length), sum(word2[i].length) <= 103
    • word1[i]word2[i] 由小写字母组成

    我的题解

    class Solution {
     public:
      bool arrayStringsAreEqual(vector<string>& word1, vector<string>& word2) {
        string s1, s2;
        for (auto i : word1) s1 += i;
        for (auto i : word2) s2 += i;
        return s1 == s2;
      }
    };
    

    5606.具有给定数值的最小字符串

    题目链接:5606.具有给定数值的最小字符串

    小写字符数值 是它在字母表中的位置(从 1 开始),因此 a 的数值为 1b 的数值为 2c 的数值为
    3 ,以此类推。

    字符串由若干小写字符组成, 字符串的数值 为各字符的数值之和。例如,字符串 "abe" 的数值等于 1 + 2 + 5 = 8

    给你两个整数 nk 。返回 长度 等于 n数值 等于 k字典序最小 的字符串。

    注意,如果字符串 x 在字典排序中位于 y 之前,就认为 x 字典序比 y 小,有以下两种情况:

    • xy 的一个前缀;
    • 如果 ix[i] != y[i] 的第一个位置,且 x[i] 在字母表中的位置比 y[i] 靠前。

    示例 Sample

    示例 1:

    **输入:** n = 3, k = 27
    **输出:** "aay"
    **解释:** 字符串的数值为 1 + 1 + 25 = 27,它是数值满足要求且长度等于 3 字典序最小的字符串。
    

    示例 2:

    **输入:** n = 5, k = 73
    **输出:** "aaszz"
    

    提示:

    • 1 <= n <= 105
    • n <= k <= 26 * n

    我的题解

    class Solution {
     public:
      string getSmallestString(int n, int k) {
        k -= n;
        vector<int> a(n);
        for (int i = 0; i < n; i++) a[i] = 0;
        for (int i = n - 1, t; i >= 0 && k; i--) {
          t = min(25, k);
          a[i] += t, k -= t;
        }
        string s;
        for (int i = 0; i < n; ++i) s += a[i] + 'a';
        return s;
      }
    };
    

    5607.生成平衡数组的方案数

    题目链接:5607.生成平衡数组的方案数

    给你一个整数数组 nums 。你需要选择 恰好 一个下标(下标从 0
    开始)并删除对应的元素。请注意剩下元素的下标可能会因为删除操作而发生改变。

    比方说,如果 nums = [6,1,7,4,1] ,那么:

    • 选择删除下标 1 ,剩下的数组为 nums = [6,7,4,1]
    • 选择删除下标 2 ,剩下的数组为 nums = [6,1,4,1]
    • 选择删除下标 4 ,剩下的数组为 nums = [6,1,7,4]

    如果一个数组满足奇数下标元素的和与偶数下标元素的和相等,该数组就是一个 平衡数组

    请你返回删除操作后,剩下的数组 __nums __ 是 平衡数组方案数

    示例 Sample

    示例 1:

    **输入:** nums = [2,1,6,4]
    **输出:** 1
    **解释:**
    删除下标 0 :[1,6,4] -> 偶数元素下标为:1 + 4 = 5 。奇数元素下标为:6 。不平衡。
    删除下标 1 :[2,6,4] -> 偶数元素下标为:2 + 4 = 6 。奇数元素下标为:6 。平衡。
    删除下标 2 :[2,1,4] -> 偶数元素下标为:2 + 4 = 6 。奇数元素下标为:1 。不平衡。
    删除下标 3 :[2,1,6] -> 偶数元素下标为:2 + 6 = 8 。奇数元素下标为:1 。不平衡。
    只有一种让剩余数组成为平衡数组的方案。
    

    示例 2:

    **输入:** nums = [1,1,1]
    **输出:** 3
    **解释:** 你可以删除任意元素,剩余数组都是平衡数组。
    

    示例 3:

    **输入:** nums = [1,2,3]
    **输出:** 0
    **解释:** 不管删除哪个元素,剩下数组都不是平衡数组。
    

    提示:

    • 1 <= nums.length <= 105
    • 1 <= nums[i] <= 104

    我的题解

    (s_i) 表示从 i 开始的间隔为 1 的序列和,那么删掉第 k 个,有

    • k 为奇数
      • 偶数项和为 (s_0 - s_{k + 1} + s_{k + 2})
      • 奇数项和为 (s_1-s_k+s_{k+1});
    • k 为偶数
      • 偶数项和为 (s_0-s_k+s_{k+1})
      • 奇数项和为 (s_1 - s_{k+1}+s_{k+2})
    class Solution {
     public:
      bool chk(int k, const vector<int>& s) {
        int x, y;
        if (k & 1) {
          x = s[0] - s[k + 1] + s[k + 2];
          y = s[1] - s[k] + s[k + 1];
        } else {
          x = s[0] - s[k] + s[k + 1];
          y = s[1] - s[k + 1] + s[k + 2];
        }
        return x == y;
      }
    
      int waysToMakeFair(vector<int>& nums) {
        const int n = nums.size();
        vector<int> s(n + 2, 0);
        for (int i = n - 1; i >= 0; i--) {
          s[i] = (i + 2 < n ? s[i + 2] : 0) + nums[i];
        }
        int ans(0);
        for (int i = 0; i < n; ++i) {
          if (chk(i, s)) ans++;
        }
        return ans;
      }
    };
    

    5608.完成所有任务的最少初始能量

    题目链接:5608.完成所有任务的最少初始能量

    给你一个任务数组 tasks ,其中 tasks[i] = [actuali, minimumi]

    • actuali 是完成第 i 个任务 需要耗费 的实际能量。
    • minimumi 是开始第 i 个任务前需要达到的最低能量。

    比方说,如果任务为 [10, 12] 且你当前的能量为 11 ,那么你不能开始这个任务。如果你当前的能量为 13
    ,你可以完成这个任务,且完成它后剩余能量为 3

    你可以按照 任意顺序 完成任务。

    请你返回完成所有任务的 最少 初始能量。

    示例 Sample

    示例 1:

    **输入:** tasks = [[1,2],[2,4],[4,8]]
    **输出:** 8
    **解释:**
    一开始有 8 能量,我们按照如下顺序完成任务:
        - 完成第 3 个任务,剩余能量为 8 - 4 = 4 。
        - 完成第 2 个任务,剩余能量为 4 - 2 = 2 。
        - 完成第 1 个任务,剩余能量为 2 - 1 = 1 。
    注意到尽管我们有能量剩余,但是如果一开始只有 7 能量是不能完成所有任务的,因为我们无法开始第 3 个任务。
    

    示例 2:

    **输入:** tasks = [[1,3],[2,4],[10,11],[10,12],[8,9]]
    **输出:** 32
    **解释:**
    一开始有 32 能量,我们按照如下顺序完成任务:
        - 完成第 1 个任务,剩余能量为 32 - 1 = 31 。
        - 完成第 2 个任务,剩余能量为 31 - 2 = 29 。
        - 完成第 3 个任务,剩余能量为 29 - 10 = 19 。
        - 完成第 4 个任务,剩余能量为 19 - 10 = 9 。
        - 完成第 5 个任务,剩余能量为 9 - 8 = 1 。
    

    示例 3:

    **输入:** tasks = [[1,7],[2,8],[3,9],[4,10],[5,11],[6,12]]
    **输出:** 27
    **解释:**
    一开始有 27 能量,我们按照如下顺序完成任务:
        - 完成第 5 个任务,剩余能量为 27 - 5 = 22 。
        - 完成第 2 个任务,剩余能量为 22 - 2 = 20 。
        - 完成第 3 个任务,剩余能量为 20 - 3 = 17 。
        - 完成第 1 个任务,剩余能量为 17 - 1 = 16 。
        - 完成第 4 个任务,剩余能量为 16 - 4 = 12 。
        - 完成第 6 个任务,剩余能量为 12 - 6 = 6 。
    

    提示:

    • 1 <= tasks.length <= 105
    • 1 <= actual​i <= minimumi <= 104

    我的题解

    按照差值贪心即可。(大胆猜的结论,下面的内容参考的 [zerotrac的题解)ORZ

    不妨设答案为 (ans) ,完成任务顺序为 ((a_0,m_0),(a_1,m_1),...(a_{n-1},m_{n-1})),那么

    [egin{aligned} ans ge m_0 \ ans -a_0 ge m_1 \ ans -a_0-a_1 ge m_2 \ ...\ ans - sum_0^{n-1}a_i ge m_{n-1} end{aligned} ]

    移动不等式,有

    [egin{aligned} ans &ge m_0 \ ans &ge a_0 + m_1 \ ans &ge a_0+a_1+m_2 \ ...\ ans &ge m_{n-1} +sum_0^{n-1}a_i end{aligned} ]

    那么如何最小化这个最大值?假设我们交换了任务 ((a_i, m_i)) 以及 ((a_{i+1},m_{i+1})) ,那么只有交换前:

    [egin{aligned} p &geq a_0+a_1+cdots+a_{i-1}+m_i = P(i,0) \ p &geq a_0+a_1+cdots+a_{i-1}+a_i+m_{i+1} = P(i,1) end{aligned} ]

    以及交换后:

    [egin{aligned} p &geq a_0+a_1+cdots+a_{i-1}+m_{i+1} = P'(i,0) \ p &geq a_0+a_1+cdots+a_{i-1}+a_{i+1}+m_i = P'(i,1) end{aligned} ]

    那么可以通过交换来进行松弛(优化当前答案)。交换前的最大值为 (max { P(i,0),P(i,1) }) ,交换后的最大值为 (max ig{ P'(i,0),P'(i,1) ig}) 。由于 (P(i,0) < P'(i,1)) 以及 (P'(i,0) < P(i,1)) 恒成立(无论顺序如何,能量消耗都是递增的),因此交换的条件

    [egin{aligned} max { P(i,0),P(i,1) } & gt max {P'(i,0),P'(i,1)} \ a_i+m_{i+1}& gt a_{i+1}+m_i \ a_i-m_i &gt a_{i+1}-m_{i+1} end{aligned} ]

    综上,按照差值排序贪心即可。

    class Solution {
     public:
      int minimumEffort(vector<vector<int>>& tasks) {
        const int n = tasks.size();
        sort(tasks.begin(), tasks.end(), [&](vector<int>& a, vector<int>& b) {
          if (a[1] - a[0] != b[1] - b[0]) return a[1] - a[0] < b[1] - b[0];
          return a[1] < b[1];
        });
    
        int ans(0), d(0);
        for (int i = 0; i < n; ++i) {
          ans += tasks[i][0];
          if (ans + d < tasks[i][1]) d += tasks[i][1] - ans;
        }
        return ans + d;
      }
    };
    
  • 相关阅读:
    递归的初步应用
    最大公约数与最小公倍数(低效)
    进制转换
    凸多边形的面积问题
    单词替换
    DNA排序
    字符串排序
    倒三角形
    韩信点兵
    oracle
  • 原文地址:https://www.cnblogs.com/Forgenvueory/p/14019216.html
Copyright © 2011-2022 走看看