image.png
最后一题明明挺简单的,脑子没转过来。。。
一个O(n^2)能过的题被我弄成了O(n^3)

5963. 反转两次的数字

显示英文描述
反转 一个整数意味着倒置它的所有位。

  • 例如,反转 2021 得到 1202 。反转 12300 得到 321 ,不保留前导零

给你一个整数 num ,反转 num 得到 reversed1 ,接着反转 reversed1 得到 reversed2 。如果 reversed2 等于 num ,返回 true ;否则,返回 false 。

示例 1:
输入:num = 526 输出:true 解释:反转 num 得到 625 ,接着反转 625 得到 526 ,等于 num 。
示例 2:
输入:num = 1800 输出:false 解释:反转 num 得到 81 ,接着反转 81 得到 18 ,不等于 num 。
示例 3:
输入:num = 0 输出:true 解释:反转 num 得到 0 ,接着反转 0 得到 0 ,等于 num 。

提示:

  • 0 <= num <= 106

思路:
反转再转回去,只需要看最后一位是不是0即可,0特判一下

  1. class Solution {
  2. public boolean isSameAfterReversals(int num) {
  3. if (num % 10 == 0 && num != 0)
  4. return false;
  5. return true;
  6. }
  7. }

5964. 执行所有后缀指令

现有一个 n x n 大小的网格,左上角单元格坐标 (0, 0) ,右下角单元格坐标 (n - 1, n - 1) 。给你整数 n 和一个整数数组 startPos ,其中 startPos = [startrow, startcol] 表示机器人最开始在坐标为 (startrow, startcol) 的单元格上。
另给你一个长度为 m 、下标从 0 开始的字符串 s ,其中 s[i] 是对机器人的第 i 条指令:’L’(向左移动),’R’(向右移动),’U’(向上移动)和 ‘D’(向下移动)。
机器人可以从 s 中的任一第 i 条指令开始执行。它将会逐条执行指令直到 s 的末尾,但在满足下述条件之一时,机器人将会停止:

  • 下一条指令将会导致机器人移动到网格外。
  • 没有指令可以执行。

返回一个长度为 m 的数组 answer ,其中 answer[i] 是机器人从第 i 条指令 开始 ,可以执行的 指令数目

示例 1:
image.png
输入:n = 3, startPos = [0,1], s = “RRDDLU” 输出:[1,5,4,3,1,0] 解释:机器人从 startPos 出发,并从第 i 条指令开始执行: - 0: “R_RDDLU” 在移动到网格外之前,只能执行一条 “R” 指令。 - 1: “RDDLU“ 可以执行全部五条指令,机器人仍在网格内,最终到达 (0, 0) 。 - 2: “DDLU“ 可以执行全部四条指令,机器人仍在网格内,最终到达 (0, 0) 。 - 3: “DLU“ 可以执行全部三条指令,机器人仍在网格内,最终到达 (0, 0) 。 - 4: “LU” 在移动到网格外之前,只能执行一条 “L” 指令。 - 5: “U” 如果向上移动,将会移动到网格外。
示例 2:
image.png
输入:n = 2, startPos = [1,1], s = “LURD” 输出:[4,1,0,0] 解释: - 0: “
LURD“ - 1: “U_RD” - 2: “RD” - 3: “D”
示例 3:
image.png
输入:n = 1, startPos = [0,0], s = “LRUD” 输出:[0,0,0,0] 解释:无论机器人从哪条指令开始执行,都会移动到网格外。

提示:

  • m == s.length
  • 1 <= n, m <= 500
  • startPos.length == 2
  • 0 <= startrow, startcol < n
  • s 由 ‘L’、’R’、’U’ 和 ‘D’ 组成

思路:
暴力计算即可

  1. class Solution {
  2. Map<Character, Integer> map = new HashMap<>();
  3. public int[] executeInstructions(int n, int[] startPos, String s) {
  4. map.put('U', 0);
  5. map.put('R', 1);
  6. map.put('D', 2);
  7. map.put('L', 3);
  8. int m = s.length();
  9. int[] res = new int[m];
  10. char[] ch = s.toCharArray();
  11. for (int i = 0; i < m; i++) {
  12. res[i] = check(n, startPos, ch, i);
  13. }
  14. return res;
  15. }
  16. int[] dx = {-1, 0, 1, 0}, dy = {0, 1, 0, -1};
  17. int check(int n, int[] s, char[] ch, int S) {
  18. int cnt = 0;
  19. int x = s[0], y = s[1];
  20. for (int i = S; i < ch.length; i++) {
  21. char c = ch[i];
  22. int idx = map.get(c);
  23. int a = x + dx[idx], b = y + dy[idx];
  24. if (a < 0 || a >= n || b < 0 || b >= n)
  25. break;
  26. cnt++;
  27. x = a;
  28. y = b;
  29. }
  30. return cnt;
  31. }
  32. }

5965. 相同元素的间隔之和

给你一个下标从 0 开始、由 n 个整数组成的数组 arr 。
arr 中两个元素的 间隔 定义为它们下标之间的 绝对差 。更正式地,arr[i] 和 arr[j] 之间的间隔是 |i - j| 。
返回一个长度为 n 的数组 intervals ,其中 intervals[i] 是 _arr[i] arr 中每个相同元素(与 arr[i] 的值相同)的 间隔之和 。_
注意:|x| 是 x 的绝对值。

示例 1:
输入:arr = [2,1,3,1,2,3,3] 输出:[4,2,7,2,4,4,5] 解释: - 下标 0 :另一个 2 在下标 4 ,|0 - 4| = 4 - 下标 1 :另一个 1 在下标 3 ,|1 - 3| = 2 - 下标 2 :另两个 3 在下标 5 和 6 ,|2 - 5| + |2 - 6| = 7 - 下标 3 :另一个 1 在下标 1 ,|3 - 1| = 2 - 下标 4 :另一个 2 在下标 0 ,|4 - 0| = 4 - 下标 5 :另两个 3 在下标 2 和 6 ,|5 - 2| + |5 - 6| = 4 - 下标 6 :另两个 3 在下标 2 和 5 ,|6 - 2| + |6 - 5| = 5
示例 2:
输入:arr = [10,5,10,10] 输出:[5,0,3,4] 解释: - 下标 0 :另两个 10 在下标 2 和 3 ,|0 - 2| + |0 - 3| = 5 - 下标 1 :只有这一个 5 在数组中,所以到相同元素的间隔之和是 0 - 下标 2 :另两个 10 在下标 0 和 3 ,|2 - 0| + |2 - 3| = 3 - 下标 3 :另两个 10 在下标 0 和 2 ,|3 - 0| + |3 - 2| = 4

提示:

  • n == arr.length
  • 1 <= n <= 105
  • 1 <= arr[i] <= 105

思路:
一个数学题

  1. class Solution {
  2. public long[] getDistances(int[] arr) {
  3. int n = arr.length;
  4. int[] cl = new int[n];
  5. long[] left = new long[n];
  6. Map<Integer, Long> map = new HashMap<>();
  7. int[] cnt = new int[100010];
  8. for (int i = 0; i < n; i++) {
  9. cl[i] = cnt[arr[i]];
  10. cnt[arr[i]]++;
  11. left[i] = map.getOrDefault(arr[i], 0L);
  12. map.merge(arr[i], 1L * i, Long::sum);
  13. }
  14. long[] res = new long[n];
  15. for (int i = 0; i < n; i++) {
  16. long x = 1L * cl[i] * i - left[i];
  17. long sum = map.get(arr[i]);
  18. x += sum - left[i] - i - 1L * (cnt[arr[i]] - cl[i] - 1) * i * 1L;
  19. res[i] = x;
  20. }
  21. return res;
  22. }
  23. }

5966. 还原原数组

Alice 有一个下标从 0 开始的数组 arr ,由 n 个正整数组成。她会选择一个任意的 正整数 k 并按下述方式创建两个下标从 0 开始的新整数数组 lower 和 higher :

  1. 对每个满足 0 <= i < n 的下标 i ,lower[i] = arr[i] - k
  2. 对每个满足 0 <= i < n 的下标 i ,higher[i] = arr[i] + k

不幸地是,Alice 丢失了全部三个数组。但是,她记住了在数组 lower 和 higher 中出现的整数,但不知道每个整数属于哪个数组。请你帮助 Alice 还原原数组。
给你一个由 2n 个整数组成的整数数组 nums ,其中 恰好 n 个整数出现在 lower ,剩下的出现在 higher ,还原并返回 原数组 arr 。如果出现答案不唯一的情况,返回 任一 有效数组。
注意:生成的测试用例保证存在 至少一个 有效数组 arr 。

示例 1:
输入:nums = [2,10,6,4,8,12] 输出:[3,7,11] 解释: 如果 arr = [3,7,11] 且 k = 1 ,那么 lower = [2,6,10] 且 higher = [4,8,12] 。 组合 lower 和 higher 得到 [2,6,10,4,8,12] ,这是 nums 的一个排列。 另一个有效的数组是 arr = [5,7,9] 且 k = 3 。在这种情况下,lower = [2,4,6] 且 higher = [8,10,12] 。
示例 2:
输入:nums = [1,1,3,3] 输出:[2,2] 解释: 如果 arr = [2,2] 且 k = 1 ,那么 lower = [1,1] 且 higher = [3,3] 。 组合 lower 和 higher 得到 [1,1,3,3] ,这是 nums 的一个排列。 注意,数组不能是 [1,3] ,因为在这种情况下,获得 [1,1,3,3] 唯一可行的方案是 k = 0 。 这种方案是无效的,k 必须是一个正整数。
示例 3:
输入:nums = [5,435] 输出:[220] 解释: 唯一可行的组合是 arr = [220] 且 k = 215 。在这种情况下,lower = [5] 且 higher = [435] 。

提示:

  • 2 * n == nums.length
  • 1 <= n <= 1000
  • 1 <= nums[i] <= 109
  • 生成的测试用例保证存在 至少一个 有效数组 arr

思路:
排序,用每个数和最小的数作差就是所有可能的k的取值
比赛时我愣生生写了个双重循环去找,真是脑子秀逗了啊!虽然过了也是侥幸!
判断该k是否合法,若合法则输出最终结果。
时间复杂度:O(n2),空间复杂度:O(n)

  1. class Solution {
  2. public int[] recoverArray(int[] nums) {
  3. Map<Integer, Integer> map = new HashMap<>();
  4. List<Integer> res = new ArrayList<>();
  5. int n = nums.length / 2;
  6. Arrays.sort(nums);
  7. for (int j = 1; j < 2 * n; j++) {
  8. int delta = nums[j] - nums[0];
  9. if (delta == 0 || delta % 2 != 0)
  10. continue;
  11. boolean flag = true;
  12. map.clear();
  13. for (int x : nums) {
  14. map.merge(x, 1, Integer::sum);
  15. }
  16. delta /= 2;
  17. res.clear();
  18. for (int i = 0; i < 2 * n && flag; i++) {
  19. if (map.get(nums[i]) > 0) {
  20. if (map.getOrDefault(nums[i] + 2 * delta, 0) == 0) {
  21. flag = false;
  22. break;
  23. } else {
  24. map.merge(nums[i], -1, Integer::sum);
  25. map.merge(nums[i] + 2 * delta, -1, Integer::sum);
  26. res.add(nums[i] + delta);
  27. }
  28. }
  29. }
  30. if (flag) {
  31. int[] ans = new int[n];
  32. for (int i = 0; i < n; i++)
  33. ans[i] = res.get(i);
  34. return ans;
  35. }
  36. }
  37. return null;
  38. }
  39. }