image.png
又刷新最好成绩了!
t3wrong是因为没考虑长度问题。

5268. 找出两数组的不同

给你两个下标从 0 开始的整数数组 nums1 和 nums2 ,请你返回一个长度为 2 的列表 answer ,其中:

  • answer[0] 是 nums1 中所有存在于 nums2 中的 不同 整数组成的列表。
  • answer[1] 是 nums2 中所有存在于 nums1 中的 不同 整数组成的列表。

注意:列表中的整数可以按 任意 顺序返回。

示例 1:
输入:nums1 = [1,2,3], nums2 = [2,4,6] 输出:[[1,3],[4,6]] 解释: 对于 nums1 ,nums1[1] = 2 出现在 nums2 中下标 0 处,然而 nums1[0] = 1 和 nums1[2] = 3 没有出现在 nums2 中。因此,answer[0] = [1,3]。 对于 nums2 ,nums2[0] = 2 出现在 nums1 中下标 1 处,然而 nums2[1] = 4 和 nums2[2] = 6 没有出现在 nums2 中。因此,answer[1] = [4,6]。
示例 2:
输入:nums1 = [1,2,3,3], nums2 = [1,1,2,2] 输出:[[3],[]] 解释: 对于 nums1 ,nums1[2] 和 nums1[3] 没有出现在 nums2 中。由于 nums1[2] == nums1[3] ,二者的值只需要在 answer[0] 中出现一次,故 answer[0] = [3]。 nums2 中的每个整数都在 nums1 中出现,因此,answer[1] = [] 。

提示:

  • 1 <= nums1.length, nums2.length <= 1000
  • -1000 <= nums1[i], nums2[i] <= 1000

思路:
哈希

  1. class Solution {
  2. public List<List<Integer>> findDifference(int[] nums1, int[] nums2) {
  3. Set<Integer> s1 = new HashSet<>();
  4. Set<Integer> s2 = new HashSet<>();
  5. for (int x : nums1) {
  6. s1.add(x);
  7. }
  8. for (int x : nums2) {
  9. s2.add(x);
  10. }
  11. List<Integer> l1 = new ArrayList<>();
  12. List<Integer> l2 = new ArrayList<>();
  13. List<List<Integer>> res = new ArrayList<>();
  14. for (int x : s1) {
  15. if (!s2.contains(x))
  16. l1.add(x);
  17. }
  18. for (int x : s2) {
  19. if (!s1.contains(x))
  20. l2.add(x);
  21. }
  22. res.add(l1);
  23. res.add(l2);
  24. return res;
  25. }
  26. }

5236. 美化数组的最少删除数

给你一个下标从 0 开始的整数数组 nums ,如果满足下述条件,则认为数组 nums 是一个 美丽数组

  • nums.length 为偶数
  • 对所有满足 i % 2 == 0 的下标 i ,nums[i] != nums[i + 1] 均成立

注意,空数组同样认为是美丽数组。
你可以从 nums 中删除任意数量的元素。当你删除一个元素时,被删除元素右侧的所有元素将会向左移动一个单位以填补空缺,而左侧的元素将会保持 不变
返回使 nums 变为美丽数组所需删除的 最少 元素数目

示例 1:
输入:nums = [1,1,2,3,5] 输出:1 解释:可以删除 nums[0] 或 nums[1] ,这样得到的 nums = [1,2,3,5] 是一个美丽数组。可以证明,要想使 nums 变为美丽数组,至少需要删除 1 个元素。
示例 2:
输入:nums = [1,1,2,2,3,3] 输出:2 解释:可以删除 nums[0] 和 nums[5] ,这样得到的 nums = [1,2,2,3] 是一个美丽数组。可以证明,要想使 nums 变为美丽数组,至少需要删除 2 个元素。

提示:

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

思路:
贪心

  1. class Solution {
  2. public int minDeletion(int[] nums) {
  3. int n = nums.length;
  4. if (n == 0) return 0;
  5. if (n == 1) return 1;
  6. int cnt = 0;
  7. for (int i = 0, j = 1; j < n; j++) {
  8. if (nums[i] == nums[j]) {
  9. cnt++;
  10. } else {
  11. i = j + 1;
  12. j++;
  13. }
  14. }
  15. if ((n - cnt) % 2 != 0)
  16. cnt++;
  17. return cnt;
  18. }
  19. }

5253. 找到指定长度的回文数

给你一个整数数组 queries 和一个 整数 intLength ,请你返回一个数组 answer ,其中 answer[i] 是长度为 intLength 的 正回文数 中第_ _queries[i] 小的数字,如果不存在这样的回文数,则为 -1 。
回文数 指的是从前往后和从后往前读一模一样的数字。回文数不能有前导 0 。

示例 1:
输入:queries = [1,2,3,4,5,90], intLength = 3 输出:[101,111,121,131,141,999] 解释: 长度为 3 的最小回文数依次是: 101, 111, 121, 131, 141, 151, 161, 171, 181, 191, 201, … 第 90 个长度为 3 的回文数是 999 。
示例 2:
输入:queries = [2,4,6], intLength = 4 输出:[1111,1331,1551] 解释: 长度为 4 的前 6 个回文数是: 1001, 1111, 1221, 1331, 1441 和 1551 。

提示:

  • 1 <= queries.length <= 5 * 104
  • 1 <= queries[i] <= 109
  • 1 <= intLength <= 15

思路:
构造回文串
注意长度限制

  1. class Solution {
  2. public long[] kthPalindrome(int[] q, int len) {
  3. int n = q.length;
  4. if (len == 1) {
  5. long[] res = new long[n];
  6. for (int i = 0; i < n; i++) {
  7. if (q[i] > 0 && q[i] <= 9)
  8. res[i] = q[i];
  9. else
  10. res[i] = -1;
  11. }
  12. return res;
  13. }
  14. long[] res = new long[n];
  15. StringBuilder sb = new StringBuilder();
  16. sb.append(1);
  17. int minus = (len + 1) / 2 - 1;
  18. while (minus > 0) {
  19. sb.append(0);
  20. minus--;
  21. }
  22. long s = Long.parseLong(sb.toString());
  23. // System.out.println(s);
  24. for (int i = 0; i < n; i++) {
  25. int idx = q[i];
  26. StringBuilder sb2 = new StringBuilder();
  27. long v = s + idx - 1;
  28. if (len % 2 == 1) {
  29. long s2 = v / 10;
  30. sb2.append(v);
  31. sb2.append(new StringBuilder().append(s2).reverse().toString());
  32. if (sb2.length() > len) {
  33. res[i] = -1;
  34. continue;
  35. }
  36. res[i] = Long.parseLong(sb2.toString());
  37. } else {
  38. sb2.append(v);
  39. sb2.append(new StringBuilder().append(v).reverse().toString());
  40. if (sb2.length() > len) {
  41. res[i] = -1;
  42. continue;
  43. }
  44. res[i] = Long.parseLong(sb2.toString());
  45. }
  46. }
  47. return res;
  48. }
  49. }

5269. 从栈中取出 K 个硬币的最大面值和

一张桌子上总共有 n 个硬币 。每个栈有 正整数 个带面值的硬币。
每一次操作中,你可以从任意一个栈的 顶部 取出 1 个硬币,从栈中移除它,并放入你的钱包里。
给你一个列表 piles ,其中 piles[i] 是一个整数数组,分别表示第 i 个栈里 从顶到底 的硬币面值。同时给你一个正整数 k ,请你返回在 恰好 进行 k 次操作的前提下,你钱包里硬币面值之和 最大为多少

示例 1:
image.png
输入:piles = [[1,100,3],[7,8,9]], k = 2 输出:101 解释: 上图展示了几种选择 k 个硬币的不同方法。 我们可以得到的最大面值为 101 。
示例 2:
输入:piles = [[100],[100],[100],[100],[100],[100],[1,1,1,1,1,1,700]], k = 7 输出:706 解释: 如果我们所有硬币都从最后一个栈中取,可以得到最大面值和。

提示:

  • n == piles.length
  • 1 <= n <= 1000
  • 1 <= piles[i][j] <= 105
  • 1 <= k <= sum(piles[i].length) <= 2000

思路:
分组背包

  1. class Solution {
  2. public int maxValueOfCoins(List<List<Integer>> p, int k) {
  3. int n = p.size();
  4. int[][] f = new int[n + 1][k + 1];
  5. for (int i = 1; i <= n; i++) {
  6. int len = p.get(i - 1).size();
  7. for (int j = 0; j <= k; j++) {
  8. int sum = 0;
  9. for (int l = 0; l <= len; l++) {
  10. if (j >= l)
  11. f[i][j] = Math.max(f[i - 1][j - l] + sum, f[i][j]);
  12. if (l != len)
  13. sum += p.get(i - 1).get(l);
  14. }
  15. }
  16. }
  17. return f[n][k];
  18. }
  19. }