LeetCode周赛216 题解

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

传送门

题目描述

给你两个字符串数组word1word2 。如果两个数组表示的字符串相同,返回 true ;否则,返回 false
数组表示的字符串 是由数组中的所有元素 按顺序 连接形成的字符串。

示例 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] 由小写字母组成
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/check-if-two-string-arrays-are-equivalent
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

解题思路

按照题意将两个字符数组中的字符串拼接起来比较是否相等即可。

AC代码

class Solution {
    public boolean arrayStringsAreEqual(String[] word1, String[] word2) {
        StringBuilder s1 = new StringBuilder();
        StringBuilder s2 = new StringBuilder();
        int len1 = word1.length,len2 = word2.length;
        for (int i = 0; i < len1; i++) {
            s1.append(word1[i]);
        }
        for (int i = 0; i < len2; i++) {
            s2.append(word2[i]);
        }
        return s1.toString().equals(s2.toString());
    }
}

1663. 具有给定数值的最小字符串【贪心】

传送门

题目描述

小写字符数值 是它在字母表中的位置(从 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] 靠前。

示例 1:

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

示例 2:

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

提示:

1 <= n <= 105
n <= k <= 26 * n
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/smallest-string-with-a-given-numeric-value
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

解题思路

一位位的确定字符。第i位的答案是在后面全选z的情况下能选择的最小值(大于等于’a’)。

AC代码1

class Solution {
    public String getSmallestString(int n, int k) {
        char[] s = new char[n];
        int x = ('z' - 'a' + 1);
        for (int i = 0; i < n; i++) {
            if ((n - i - 1) * x >= k) {
                s[i] = 'a';
                k--;
            } else {
                int t = k - (n - i - 1) * x;
                s[i] = (char)(t + 'a' - 1);
                k -= t;
            }
        }
        return new String(s);
    }
}

AC代码2

class Solution {
    public String getSmallestString(int n, int k) {
        char[] s = new char[n];
        for (int i = 0; i < n; i++) {
            s[i] = 'a';
            k--;
        }
        int len = n - 1;
        while (k > 0) {
            if (k < 26) {
                s[len] = (char)('a' + k);
                break;
            } else {
                s[len] = 'z';
                k -= 25;
            }
            len--;
        }
        return new String(s);
    }
}

1664. 生成平衡数组的方案数【前缀和数组】

传送门

题目描述

给你一个整数数组 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平衡数组方案数

示例 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
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/ways-to-make-a-fair-array
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

解题思路

题目说只能删除一位,所以我们可以枚举删除的位置。
首先预处理奇数项前缀和,偶数项前缀和便于后续的操作。
当删除第i位后,第i位后面的奇偶状态会互换,然后根据我们预处理的前缀和计算新奇偶项的和即可。

AC代码

class Solution {
    public int waysToMakeFair(int[] nums) {
        int n = nums.length;
        int[] odd = new int[n],even = new int[n];
        even[0] = nums[0];
        for (int i = 1; i < n; i++) {
            odd[i] += odd[i - 1];
            even[i] += even[i - 1];
            if ((i & 1) == 1) {
                odd[i] += nums[i];
            } else {
                even[i] += nums[i];
            }
        }
        int ans = 0;
        for (int i = 0; i < n; i++) {
            if (i == 0) {
                if (even[n - 1] - nums[0] == odd[n - 1]) {
                    ans++;
                }
                continue;
            } 
            if (i == n - 1) {
                if (odd[i - 1] == even[i - 1]) {
                    ans++;
                }
                continue;
            } 
            if (odd[i - 1] + even[n - 1] - even[i] == even[i - 1] + odd[n - 1] - odd[i]) {
                ans++;
            }
        }
        return ans;
    }
}

1665. 完成所有任务的最少初始能量【贪心】

传送门

题目描述

给你一个任务数组 tasks ,其中 tasks[i] = [actuali, minimumi]
actuali 是完成第 i 个任务 需要耗费 的实际能量。
minimumi 是开始第i 个任务前 需要达到 的最低能量。
比方说,如果任务为[10, 12] 且你当前的能量为 11,那么你不能开始这个任务。如果你当前的能量为 13 ,你可以完成这个任务,且完成它后剩余能量为 3
你可以按照 任意顺序 完成任务。
请你返回完成所有任务的 最少 初始能量。

示例 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
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/minimum-initial-energy-to-finish-tasks
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

AC代码

class Solution {
    public int minimumEffort(int[][] tasks) {
        class Node{
            int x, y;
            int sub;
            Node(int tx, int ty, int tsub) {
                x = tx;
                y = ty;
                sub = tsub;
            }
        }
        int size = tasks.length;
        ArrayList<Node> list = new ArrayList();
        for (int i = 0; i < size; i++) {
            int x = tasks[i][0];
            int y = tasks[i][1];
            list.add(new Node(x, y, y - x));
        }
        Collections.sort(list, new Comparator<Node>() {
            @Override
            public int compare(Node o1, Node o2) {
            	// 如果差值相等,按需要耗费能量由小到大排序
                if (o1.sub == o2.sub) {
                    return o1.x - o2.x;
                }
                // 如果差值不相等,按差值由大到小排序
                return o2.sub - o1.sub;
            }
        });
        // 倒推完成所有任务的最少初始能量
        // ans是完成所有任务的最少初始能量,t是当前可用能量
        int ans = 0,t = 0;
        for (Node i : list) {
        	// 当前能量不足,就补足
            if (t < i.y) {
                ans += (i.y - t);
                // 更新当前可用能量
                t = i.y;
            }
            // 用掉需要耗费的实际能量
            t -= i.x;
        }
        return ans;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值