image.png
最后一题想歪了,写麻烦了

6204. 与对应负数同时存在的最大正整数

显示英文描述
我的提交返回竞赛

  • 通过的用户数5165
  • 尝试过的用户数5232
  • 用户总通过次数5245
  • 用户总提交次数7285
  • 题目难度Easy

给你一个 不包含 任何零的整数数组 nums ,找出自身与对应的负数都在数组中存在的最大正整数 k 。
返回正整数_ _k ,如果不存在这样的整数,返回 -1 。

示例 1:
输入:nums = [-1,2,-3,3] 输出:3 解释:3 是数组中唯一一个满足题目要求的 k 。
示例 2:
输入:nums = [-1,10,6,7,-7,1] 输出:7 解释:数组中存在 1 和 7 对应的负数,7 的值更大。
示例 3:
输入:nums = [-10,8,6,7,-2,-3] 输出:-1 解释:不存在满足题目要求的 k ,返回 -1 。

提示:

  • 1 <= nums.length <= 1000
  • -1000 <= nums[i] <= 1000
  • nums[i] != 0

思路:哈希

  1. class Solution {
  2. public int findMaxK(int[] nums) {
  3. Set<Integer> set = new HashSet<>();
  4. int max = 0;
  5. for (int x : nums) set.add(x);
  6. for (int x : set) {
  7. if (set.contains(-x))
  8. max = Math.max(max, x);
  9. }
  10. return max == 0 ? -1 : max;
  11. }
  12. }

6205. 反转之后不同整数的数目

显示英文描述
我的提交返回竞赛

  • 通过的用户数4878
  • 尝试过的用户数5017
  • 用户总通过次数4965
  • 用户总提交次数6595
  • 题目难度Medium

给你一个由 整数组成的数组 nums 。
你必须取出数组中的每个整数,反转其中每个数位,并将反转后得到的数字添加到数组的末尾。这一操作只针对 nums 中原有的整数执行。
返回结果数组中 不同 整数的数目。

示例 1:
输入:nums = [1,13,10,12,31] 输出:6 解释:反转每个数字后,结果数组是 [1,13,10,12,31,1,31,1,21,13] 。 反转后得到的数字添加到数组的末尾并按斜体加粗表示。注意对于整数 10 ,反转之后会变成 01 ,即 1 。 数组中不同整数的数目为 6(数字 1、10、12、13、21 和 31)。
示例 2:
输入:nums = [2,2,2] 输出:1 解释:反转每个数字后,结果数组是 [2,2,2,2,2,2] 。 数组中不同整数的数目为 1(数字 2)。

提示:

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


思路:哈希

  1. class Solution {
  2. public int countDistinctIntegers(int[] nums) {
  3. Set<Integer> set = new HashSet<>();
  4. for (int x : nums) {
  5. set.add(x);
  6. set.add(reverse(x));
  7. }
  8. return set.size();
  9. }
  10. int reverse(int x) {
  11. int res = 0;
  12. while (x > 0) {
  13. res = res * 10 + x % 10;
  14. x /= 10;
  15. }
  16. return res;
  17. }
  18. }

6219. 反转之后的数字和

给你一个 非负 整数 num 。如果存在某个 非负 整数 k 满足 k + reverse(k) = num ,则返回 true ;否则,返回_ _false 。
reverse(k) 表示 k 反转每个数位后得到的数字。

示例 1:
输入:num = 443 输出:true 解释:172 + 271 = 443 ,所以返回 true 。
示例 2:
输入:num = 63 输出:false 解释:63 不能表示为非负整数及其反转后数字之和,返回 false 。
示例 3:
输入:num = 181 输出:true 解释:140 + 041 = 181 ,所以返回 true 。注意,反转后的数字可能包含前导零。

提示:

  • 0 <= num <= 105

思路:暴力

  1. class Solution {
  2. public boolean sumOfNumberAndReverse(int num) {
  3. for (int x = 0; x <= num; x++) {
  4. if (x + reverse(x) == num)
  5. return true;
  6. }
  7. return false;
  8. }
  9. int reverse(int x) {
  10. int res = 0;
  11. while (x > 0) {
  12. res = res * 10 + x % 10;
  13. x /= 10;
  14. }
  15. return res;
  16. }
  17. }

6207. 统计定界子数组的数目

显示英文描述
我的提交返回竞赛

  • 通过的用户数942
  • 尝试过的用户数2456
  • 用户总通过次数1113
  • 用户总提交次数5562
  • 题目难度Hard

给你一个整数数组 nums 和两个整数 minK 以及 maxK 。
nums 的定界子数组是满足下述条件的一个子数组:

  • 子数组中的 最小值 等于 minK 。
  • 子数组中的 最大值 等于 maxK 。

返回定界子数组的数目。
子数组是数组中的一个连续部分。

示例 1:
输入:nums = [1,3,5,2,7,5], minK = 1, maxK = 5 输出:2 解释:定界子数组是 [1,3,5] 和 [1,3,5,2] 。
示例 2:
输入:nums = [1,1,1,1], minK = 1, maxK = 1 输出:10 解释:nums 的每个子数组都是一个定界子数组。共有 10 个子数组。

提示:

  • 2 <= nums.length <= 105
  • 1 <= nums[i], minK, maxK <= 106

思路:贪心 + 双指针,线段树

  1. class Solution {
  2. int[] nums;
  3. int n;
  4. int N = 100010;
  5. Node[] tr = new Node[4 * N];
  6. int minK, maxK;
  7. public long countSubarrays(int[] nums, int minK, int maxK) {
  8. n = nums.length;
  9. this.minK = minK;
  10. this.maxK = maxK;
  11. this.nums = nums;
  12. build(1, 1, nums.length);
  13. for (int i = 1; i <= n; i++) {
  14. modify(1, i, nums[i - 1]);
  15. }
  16. // System.out.println(query(1, 7, 10)[1]);
  17. long c = 0;
  18. int pre = 0;
  19. for (int i = 1; i <= n; i++) {
  20. if (nums[i - 1] < minK || nums[i - 1] > maxK) {
  21. pre = i;
  22. continue;
  23. } else {
  24. int l = pre + 1, r = i;
  25. int[] v = query(1, l, r);
  26. if (v[0] != maxK || v[1] != minK) continue;
  27. // int minIdx = deal1(l, r);
  28. // int maxIdx = deal2(l, r);
  29. // l = Math.min(minIdx, maxIdx);
  30. while (l < r) {
  31. int mid = l + r + 1 >> 1;
  32. int[] t = query(1, mid, i);
  33. if (t[0] != maxK || t[1] != minK)
  34. r = mid - 1;
  35. else l = mid;
  36. }
  37. // System.out.println(i + " " + r);
  38. c += l - pre;
  39. }
  40. }
  41. return c;
  42. }
  43. int deal1(int l, int r) {
  44. while (l < r) {
  45. int mid = l + r + 1 >> 1;
  46. int[] t = query(1, mid, r);
  47. if (t[1] == minK)
  48. l = mid;
  49. else r = mid - 1;
  50. }
  51. return l;
  52. }
  53. int deal2(int l, int r) {
  54. while (l < r) {
  55. int mid = l + r + 1 >> 1;
  56. int[] t = query(1, mid, r);
  57. if (t[0] == maxK)
  58. l = mid;
  59. else r = mid - 1;
  60. }
  61. return l;
  62. }
  63. void build(int u, int l, int r) {
  64. tr[u] = new Node(l, r);
  65. if (l == r) return;
  66. int mid = l + r >> 1;
  67. build(u << 1, l, mid);
  68. build(u << 1 | 1, mid + 1, r);
  69. }
  70. void modify(int u, int idx, int x) {
  71. if (tr[u].l == idx && tr[u].r == idx) {
  72. tr[u].max = Math.max(x, tr[u].max);
  73. tr[u].min = Math.min(x, tr[u].min);
  74. } else {
  75. int mid = tr[u].l + tr[u].r >> 1;
  76. if (idx <= mid) modify(u << 1, idx, x);
  77. else modify(u << 1 | 1, idx, x);
  78. pushup(u);
  79. }
  80. }
  81. void pushup(int u) {
  82. tr[u].max = Math.max(tr[u << 1].max, tr[u << 1 | 1].max);
  83. tr[u].min = Math.min(tr[u << 1].min, tr[u << 1 | 1].min);
  84. }
  85. int[] query(int u, int l, int r) {
  86. if (tr[u].l >= l && r >= tr[u].r)
  87. return new int[]{tr[u].max, tr[u].min};
  88. int mid = tr[u].l + tr[u].r >> 1;
  89. // max, min
  90. int[] res = {-0x3f3f3f3f, 0x3f3f3f3f};
  91. if (l <= mid) res = query(u << 1, l, r);
  92. if (r > mid) {
  93. int[] t = query(u << 1 | 1, l, r);
  94. res[0] = Math.max(res[0], t[0]);
  95. res[1] = Math.min(res[1], t[1]);
  96. }
  97. return res;
  98. }
  99. }
  100. class Node {
  101. int l, r;
  102. int max = -0x3f3f3f3f;
  103. int min = 0x3f3f3f3f;
  104. Node(int l, int r) {
  105. this.l = l;
  106. this.r = r;
  107. }
  108. }
  1. class Solution {
  2. public long countSubarrays(int[] nums, int minK, int maxK) {
  3. long c = 0;
  4. int n = nums.length;
  5. int pre = -1, max = -1, min = -1;
  6. for (int i = 0; i < n; i++) {
  7. if (nums[i] < minK || nums[i] > maxK) {
  8. pre = i;
  9. max = min = -1;
  10. } else {
  11. if (max == -1) max = i;
  12. else max = nums[i] >= nums[max] ? i : max;
  13. if (min == -1) min = i;
  14. else min = nums[i] <= nums[min] ? i : min;
  15. // System.out.println(i + " " + max + " " + min);
  16. if (nums[max] == maxK && nums[min] == minK) {
  17. c += Math.min(max, min) - pre;
  18. }
  19. }
  20. }
  21. return c;
  22. }
  23. }