leetcode contest 315
前三题确实太水的题目,都是暴力。
6204. 与对应负数同时存在的最大正整数
题目
给你一个 不包含 任何零的整数数组 nums
,找出自身与对应的负数都在数组中存在的最大正整数 k
。
返回正整数 k
,如果不存在这样的整数,返回 -1
。
示例 1:
输入:nums = [-1,2,-3,3] |
示例 2:
输入:nums = [-1,10,6,7,-7,1] |
示例 3:
输入:nums = [-10,8,6,7,-2,-3] |
提示:
1 <= nums.length <= 1000
-1000 <= nums[i] <= 1000
nums[i] != 0
地址
https://leetcode.cn/problems/largest-positive-integer-that-exists-with-its-negative/
题意
哈希
思路
- 排序后直接统计即可,即统计 $x$ 与 $-x$ 是否同时出现。
- 复杂度分析:
- 时间复杂度:$O(n)$,其中 $n$ 为数组的长度。
- 空间复杂度:$O(n)$,其中 $n$ 为数组的长度。
代码
class Solution { |
6205. 反转之后不同整数的数目
题目
给你一个由 正 整数组成的数组 nums
。
你必须取出数组中的每个整数,反转其中每个数位,并将反转后得到的数字添加到数组的末尾。这一操作只针对 nums
中原有的整数执行。
返回结果数组中 不同 整数的数目。
示例 1:
输入:nums = [1,13,10,12,31] |
示例 2:
输入:nums = [2,2,2] |
提示:
1 <= nums.length <= 105
1 <= nums[i] <= 106
地址
https://leetcode.cn/problems/count-number-of-distinct-integers-after-reverse-operations/description/
题意
遍历即可
思路
- 我们将其中的每个数 $x$ 按照数位进行反转并得到 $r(x)$,最终用哈希表存储 $x,r(x)$,最终记录哈希表的大小即可。
- 复杂度分析:
- 时间复杂度:时间复杂度为 $O(n)$,其中 $n$ 表示数组的长度。
- 空间复杂度:空间复杂度为 $O(n)$。
代码
class Solution { |
6219. 反转之后的数字和
题目
给你一个 非负 整数 num
。如果存在某个 非负 整数 k
满足 k + reverse(k) = num
,则返回 true
;否则,返回 false
。
reverse(k)
表示 k
反转每个数位后得到的数字。
示例 1:
输入:num = 443 |
示例 2:
输入:num = 63 |
示例 3:
输入:num = 181 |
提示:
0 <= num <= 105
地址
https://leetcode.cn/problems/sum-of-number-and-its-reverse/
题意
遍历
思路
- 由于 $num$ 的范围大小可知,我们直接遍历 $x \in [0,num]$ 即可,检测 $x + r(x) = num$ 是否成立即可。
- 复杂度分析
- 时间复杂度:时间复杂度为 $O(n)$,$n$ 为字符串的长度。
- 空间复杂度:时间复杂度为 $O(\log n)$。
代码
class Solution { |
6207. 统计定界子数组的数目
题目
给你一个整数数组 nums
和两个整数 minK
以及 maxK
。
nums
的定界子数组是满足下述条件的一个子数组:
- 子数组中的 最小值 等于
minK
。 - 子数组中的 最大值 等于
maxK
。
返回定界子数组的数目。
子数组是数组中的一个连续部分。
示例 1:
输入:nums = [1,3,5,2,7,5], minK = 1, maxK = 5 |
示例 2:
输入:nums = [1,1,1,1], minK = 1, maxK = 1 |
提示:
2 <= nums.length <= 105
1 <= nums[i], minK, maxK <= 106
地址
https://leetcode.cn/problems/count-subarrays-with-fixed-bounds/
题意
动态规划
思路
- 当然如果满足 $minK = maxK$ 则这个题目就非常简单了,我们直接统计 $maxK$ 的连续数字即可。如果 $minK = maxK$ 时间,我们设 $dp[i][0]$ 表示以 $i$ 为结尾且连续子数组种所有的元素范围均在 $(minK, maxK)$ 之间的数目,$dp[i][1]$ 表示以 $i$ 为结尾且连续子数组且包含 $minK$ 且不包含 $maxK$ 的数目,$dp[i][2]$ 表示以 $i$ 为结尾且连续子数组且包含 $maxK$ 且不包含 $minK$ 的数目,$dp[i][3]$ 表示以 $i$ 为结尾且连续子数组且包含 $mink, maxK$ 的数目, 则可以有如下三种判断:
当 $ minK \le num[i] \le maxK$ 时,则此时可以知道
$$
dp[i][0] = dp[i-1][0] + 1\
dp[i][1] = dp[i-1][1] \
dp[i][2] = dp[i-1][2] \
dp[i][3] = dp[i-1][3]
$$当 $ minK = num[i]$ 时,则此时可以知道:
$$
dp[i][1] = dp[i - 1][0] + dp[i - 1][1] + 1 \
dp[i][3] = dp[i - 1][3] + dp[i - 1][2]
$$当 $ maxK = num[i]$ 时,则此时可以知道:
$$
dp[i][2] = dp[i - 1][0] + dp[i - 1][2] + 1 \
dp[i][3] = dp[i - 1][3] + dp[i - 1][1]
$$
- 非常好容易理解的解法如下,设以 $i$ 为右端点的连续子树的数目为 $cnt[i]$,则此时可以知道在合法的连续子数组中一定含有 $maxK, mink$ 且其中所有的元素均满足大于等于 $minK$,且小于等于 $maxK$。则此时我们应当取 $j = \min(minIdx, maxId)$,即距离 $i$ 最近且同时出现 $minK,maxk$ 的索引为 $j$,如果距离 $i$ 最近的非法数字的索引为 $validIdx$:
- 如果 $validIdx < j$,此时可以构造的合法的连续子数组的数目为 $j - validIdx$;
- 如果 $validIdx \ge j$,此时可以构造的合法的连续子数组的数目为 $0$;
- 复杂度分析:
- 时间复杂度:$O(n)$,其中 $n$ 表示数组的长度。
- 空间复杂度:$O(1)$。
代码
class Solution { |
- 直接检测
class Solution {
public:
long long countSubarrays(vector<int>& nums, int minK, int maxK) {
int n = nums.size();
int minIdx = -1, maxIdx = -1, validIdx = -1;
long long ans = 0;
for (int i = 0; i < n; i++) {
if (nums[i] == minK) minIdx = i;
if (nums[i] == maxK) maxIdx = i;
if (nums[i] > maxK || nums[i] < minK) validIdx = i;
ans += max(0, min(minIdx, maxIdx) - validIdx);
}
return ans;
}
};
欢迎关注和打赏,感谢支持!
- 关注我的博客: http://mikemeng.org/
- 关注我的知乎:https://www.zhihu.com/people/da-hua-niu
- 关注我的微信公众号: 公务程序猿
扫描二维码,分享此文章