image.png
迟到的一场,,倒着开的,没想到T3这么难,心态炸了

2432. 处理用时最长的那个任务的员工

共有 n 位员工,每位员工都有一个从 0 到 n - 1 的唯一 id 。
给你一个二维整数数组 logs ,其中 logs[i] = [idi, leaveTimei] :

  • idi 是处理第 i 个任务的员工的 id ,且
  • leaveTimei 是员工完成第 i 个任务的时刻。所有 leaveTimei 的值都是 唯一 的。

注意,第 i 个任务在第 (i - 1) 个任务结束后立即开始,且第 0 个任务从时刻 0 开始。
返回处理用时最长的那个任务的员工的 id 。如果存在两个或多个员工同时满足,则返回几人中 最小 的 id 。

示例 1:
输入:n = 10, logs = [[0,3],[2,5],[0,9],[1,15]] 输出:1 解释: 任务 0 于时刻 0 开始,且在时刻 3 结束,共计 3 个单位时间。 任务 1 于时刻 3 开始,且在时刻 5 结束,共计 2 个单位时间。 任务 2 于时刻 5 开始,且在时刻 9 结束,共计 4 个单位时间。 任务 3 于时刻 9 开始,且在时刻 15 结束,共计 6 个单位时间。 时间最长的任务是任务 3 ,而 id 为 1 的员工是处理此任务的员工,所以返回 1 。
示例 2:
输入:n = 26, logs = [[1,1],[3,7],[2,12],[7,17]] 输出:3 解释: 任务 0 于时刻 0 开始,且在时刻 1 结束,共计 1 个单位时间。 任务 1 于时刻 1 开始,且在时刻 7 结束,共计 6 个单位时间。 任务 2 于时刻 7 开始,且在时刻 12 结束,共计 5 个单位时间。 任务 3 于时刻 12 开始,且在时刻 17 结束,共计 5 个单位时间。 时间最长的任务是任务 1 ,而 id 为 3 的员工是处理此任务的员工,所以返回 3 。
示例 3:
输入:n = 2, logs = [[0,10],[1,20]] 输出:0 解释: 任务 0 于时刻 0 开始,且在时刻 10 结束,共计 10 个单位时间。 任务 1 于时刻 10 开始,且在时刻 20 结束,共计 10 个单位时间。 时间最长的任务是任务 0 和 1 ,处理这两个任务的员工的 id 分别是 0 和 1 ,所以返回最小的 0 。

提示:

  • 2 <= n <= 500
  • 1 <= logs.length <= 500
  • logs[i].length == 2
  • 0 <= idi <= n - 1
  • 1 <= leaveTimei <= 500
  • idi != idi + 1
  • leaveTimei 按严格递增顺序排列

思路:模拟

  1. class Solution {
  2. public int hardestWorker(int n, int[][] logs) {
  3. int max = logs[0][1];
  4. int res = logs[0][0];
  5. for (int i = 1; i < logs.length; i++) {
  6. int x = logs[i][1] - logs[i - 1][1];
  7. if (x > max) {
  8. max = x;
  9. res = logs[i][0];
  10. } else if (x == max) {
  11. res = Math.min(res, logs[i][0]);
  12. }
  13. }
  14. return res;
  15. }
  16. }

2433. 找出前缀异或的原始数组

给你一个长度为 n 的 整数 数组 pref 。找出并返回满足下述条件且长度为 n 的数组_ _arr :

  • pref[i] = arr[0] ^ arr[1] ^ … ^ arr[i].

注意 ^ 表示 按位异或(bitwise-xor)运算。
可以证明答案是 唯一 的。

示例 1:
输入:pref = [5,2,0,3,1] 输出:[5,7,2,3,2] 解释:从数组 [5,7,2,3,2] 可以得到如下结果: - pref[0] = 5 - pref[1] = 5 ^ 7 = 2 - pref[2] = 5 ^ 7 ^ 2 = 0 - pref[3] = 5 ^ 7 ^ 2 ^ 3 = 3 - pref[4] = 5 ^ 7 ^ 2 ^ 3 ^ 2 = 1
示例 2:
输入:pref = [13] 输出:[13] 解释:pref[0] = arr[0] = 13

提示:

  • 1 <= pref.length <= 105
  • 0 <= pref[i] <= 106

思路:异或前缀

  1. class Solution {
  2. public int[] findArray(int[] pref) {
  3. int n = pref.length;
  4. int[] res = new int[n];
  5. res[0] = pref[0];
  6. int x = res[0];
  7. for (int i = 1; i < n; i++) {
  8. res[i] = x ^ pref[i];
  9. x ^= res[i];
  10. }
  11. return res;
  12. }
  13. }

2434. 使用机器人打印字典序最小的字符串

给你一个字符串 s 和一个机器人,机器人当前有一个空字符串 t 。执行以下操作之一,直到 s 和 t 都变成空字符串:

  • 删除字符串 s 的 第一个 字符,并将该字符给机器人。机器人把这个字符添加到 t 的尾部。
  • 删除字符串 t 的 最后一个 字符,并将该字符给机器人。机器人将该字符写到纸上。

请你返回纸上能写出的字典序最小的字符串。

示例 1:
输入:s = “zza” 输出:“azz” 解释:用 p 表示写出来的字符串。 一开始,p=”” ,s=”zza” ,t=”” 。 执行第一个操作三次,得到 p=”” ,s=”” ,t=”zza” 。 执行第二个操作三次,得到 p=”azz” ,s=”” ,t=”” 。
示例 2:
输入:s = “bac” 输出:“abc” 解释:用 p 表示写出来的字符串。 执行第一个操作两次,得到 p=”” ,s=”c” ,t=”ba” 。 执行第二个操作两次,得到 p=”ab” ,s=”c” ,t=”” 。 执行第一个操作,得到 p=”ab” ,s=”” ,t=”c” 。 执行第二个操作,得到 p=”abc” ,s=”” ,t=”” 。
示例 3:
输入:s = “bdda” 输出:“addb” 解释:用 p 表示写出来的字符串。 一开始,p=”” ,s=”bdda” ,t=”” 。 执行第一个操作四次,得到 p=”” ,s=”” ,t=”bdda” 。 执行第二个操作四次,得到 p=”addb” ,s=”” ,t=”” 。

提示:

  • 1 <= s.length <= 105
  • s 只包含小写英文字母。

思路:贪心

  1. class Solution {
  2. public String robotWithString(String s) {
  3. int n = s.length();
  4. char c = 'z';
  5. char[] r = new char[n];
  6. for (int i = n - 1; i >= 0; i--) {
  7. r[i] = (char) Math.min(s.charAt(i), c);
  8. c = r[i];
  9. }
  10. StringBuilder sb = new StringBuilder();
  11. Deque<Character> stk = new ArrayDeque<>();
  12. for (int i = 0; i < n; i++) {
  13. char cur = s.charAt(i);
  14. while (!stk.isEmpty() && stk.peek() <= r[i]) {
  15. sb.append(stk.pop());
  16. }
  17. if (cur == r[i])
  18. sb.append(cur);
  19. else stk.push(cur);
  20. }
  21. while (!stk.isEmpty())
  22. sb.append(stk.pop());
  23. return sb.toString();
  24. }
  25. }

2435. 矩阵中和能被 K 整除的路径

给你一个下标从 0 开始的 m x n 整数矩阵 grid 和一个整数 k 。你从起点 (0, 0) 出发,每一步只能往 或者往 ,你想要到达终点 (m - 1, n - 1) 。
请你返回路径和能被 k 整除的路径数目,由于答案可能很大,返回答案对 109 + 7 取余 的结果。

示例 1:
🏆 第 314 场力扣周赛 - 图2
输入:grid = [[5,2,4],[3,0,5],[0,7,2]], k = 3 输出:2 解释:有两条路径满足路径上元素的和能被 k 整除。 第一条路径为上图中用红色标注的路径,和为 5 + 2 + 4 + 5 + 2 = 18 ,能被 3 整除。 第二条路径为上图中用蓝色标注的路径,和为 5 + 3 + 0 + 5 + 2 = 15 ,能被 3 整除。
示例 2:
输入:grid = [[0,0]], k = 5 输出:1 解释:红色标注的路径和为 0 + 0 = 0 ,能被 5 整除。
示例 3:
输入:grid = [[7,3,4,9],[2,3,6,2],[2,3,7,0]], k = 1 输出:10 解释:每个数字都能被 1 整除,所以每一条路径的和都能被 k 整除。

提示:

  • m == grid.length
  • n == grid[i].length
  • 1 <= m, n <= 5 * 104
  • 1 <= m n <= 5 104
  • 0 <= grid[i][j] <= 100
  • 1 <= k <= 50

思路:经典DP问题,注意取模

  1. class Solution {
  2. public int numberOfPaths(int[][] grid, int k) {
  3. int n = grid.length, m = grid[0].length;
  4. int[][] f = new int[m][k];
  5. int[][] g = new int[m][k];
  6. int mod = (int)(1e9 + 7);
  7. for (int i = 0, s = 0; i < m; i++) {
  8. s += grid[0][i];
  9. f[i][s % k] = 1;
  10. }
  11. for (int i = 1; i < n; i++) {
  12. for (int j = 0; j < m; j++) {
  13. for (int x = 0; x < k; x++) {
  14. g[j][(x + grid[i][j]) % k] = (g[j][(x + grid[i][j]) % k] + f[j][x]) % mod;
  15. if (j > 0)
  16. g[j][(x + grid[i][j]) % k] = (g[j][(x + grid[i][j]) % k] + g[j - 1][x]) % mod;
  17. }
  18. }
  19. for (int j = 0; j < m; j++) {
  20. for (int x = 0; x < k; x++) {
  21. f[j][x] = g[j][x];
  22. g[j][x] = 0;
  23. }
  24. }
  25. }
  26. return f[m - 1][0];
  27. }
  28. }