leetcode contest 321
前三题确实是太简单了,最后一题稍微有点难度。
6245. 找出中枢整数
给你一个正整数 n
,找出满足下述条件的 中枢整数 x
:
1
和x
之间的所有元素之和等于x
和n
之间所有元素之和。
返回中枢整数 x
。如果不存在中枢整数,则返回 -1
。题目保证对于给定的输入,至多存在一个中枢整数。
示例 1:
输入:n = 8 |
示例 2:
输入:n = 1 |
示例 3:
输入:n = 4 |
提示:
1 <= n <= 1000
地址
https://leetcode.cn/contest/weekly-contest-321/problems/find-the-pivot-integer/
题意
直接遍历即可
思路
- 直接遍历求出前 $i$ 项和与后 $n - i + 1$ 项的和,利用等差数列求和公式即可。
- 复杂度分析:
- 时间复杂度:$O(1)$。
- 空间复杂度:$O(1)$。
代码
class Solution { |
6246. 追加字符以获得子序列
给你两个仅由小写英文字母组成的字符串 s
和 t
。
现在需要通过向 s
末尾追加字符的方式使 t
变成 s
的一个 子序列 ,返回需要追加的最少字符数。
子序列是一个可以由其他字符串删除部分(或不删除)字符但不改变剩下字符顺序得到的字符串。
示例 1:
输入:s = "coaching", t = "coding" |
示例 2:
输入:s = "abcde", t = "a" |
示例 3:
输入:s = "z", t = "abcde" |
提示:
1 <= s.length, t.length <= 105
s
和t
仅由小写英文字母组成
地址
题意
双指针
思路
- 典型的双指针,$i$ 指向 $s$,$j$ 指向 $t$,如果满足 $s[i] = t[j]$,此时向右移动 $j$,最终返回 $|t| - j$ 即可。即找到此时 $s$ 中为 $t$ 的子序列的最多数目。
- 复杂度分析:
- 时间复杂度:时间复杂度为 $O(m + n)$,其中 $m,n$ 表示两个字符串的长度。
- 空间复杂度:空间复杂度为 $O(1)$。
代码
class Solution { |
6247. 从链表中移除节点
给你一个链表的头节点 head
。
对于列表中的每个节点 node
,如果其右侧存在一个具有 严格更大 值的节点,则移除 node
。
返回修改后链表的头节点 head
。
示例 1:
输入:head = [5,2,13,3,8] |
示例 2:
输入:head = [1,1,1,1] |
提示:
- 给定列表中的节点数目在范围
[1, 105]
内 1 <= Node.val <= 105
地址
https://leetcode.cn/contest/weekly-contest-321/problems/remove-nodes-from-linked-list/
题意
单调栈
思路
- 不知道这个题目有啥意思,简单的一个单调栈就全部搞定。
- 复杂度分析
- 时间复杂度:时间复杂度为 $O(n)$,$n$ 为给定的节点的数目。
- 空间复杂度:空间复杂度为 $O(n)$,$n$ 为给定的节点的数目。
代码
class Solution { |
- 递归
class Solution {
public:
ListNode* removeNodes(ListNode* head) {
if (!head) {
return nullptr;
}
ListNode *node = removeNodes(head->next);
if (node && node->val > head->val) {
return node;
} else {
head->next = node;
return head;
}
}
};
6248. 统计中位数为 K 的子数组
给你一个长度为 n
的数组 nums
,该数组由从 1
到 n
的 不同 整数组成。另给你一个正整数 k
。
统计并返回 num
中的 中位数 等于 k
的非空子数组的数目。
注意:
数组的中位数是按
递增
顺序排列后位于
中间
的那个元素,如果数组长度为偶数,则中位数是位于中间靠
左
的那个元素。
- 例如,
[2,3,1,4]
的中位数是2
,[8,4,3,5,1]
的中位数是4
。
- 例如,
子数组是数组中的一个连续部分。
示例 1:
输入:nums = [3,2,1,4,5], k = 4 |
示例 2:
输入:nums = [2,3,1], k = 3 |
提示:
n == nums.length
1 <= n <= 105
1 <= nums[i], k <= n
nums
中的整数互不相同
地址
https://leetcode.cn/contest/weekly-contest-321/problems/count-subarrays-with-median-k/
题意
滑动窗口
思路
- 设 $i$ 指向连续子数组的左侧, $j$ 指向符合题目要求的连续子数组的右侧,则此时子数目的数目为 $j - i + 1$,子数组 $nums[i,\cdots,j]$ 中大于 $k$ 的数目为 $x$,小于 $k$ 的数目为 $y$,则分类讨论如下:
- 此时一定满足 $j - i + 1 = x + y + 1$;
- 如果满足 $k$ 为中位数,则此时一定满足:
- 如果 $j - i + 1$ 为偶数,则此时一定满足 $y - x = 1$ 才能使得连续子数组 $nums[i,\cdots,j]$ 的中位数为 $k$, 此时 $y - x = 1$;
- 如果 $j - i + 1$ 为奇数数,则此时一定满足 $x = y$,才能使得连续子数组 $nums[i,\cdots,j]$ 的中位数为 $k$, 此时 $y - x = 0$;
- 我们依次记录所有 $i < index(k)$ 处当前大于 $k$ 的数目与小于 $k$ 的数目之差为 $diff$ 的索引个数 $cnt[diff]$。根据上述推论可以知道,加入我们当前遍历到索引 $j, j \ge index(k)$ 处,则,此时大于 $k$ 的数字个数为 $g[i]$,小于 $k$ 的数字个数为 $l[i]$,此时二者之差为 $diff = g[i] - l[i]$,
- 假设我们当前的使得大于 $k$ 的数目与小于 $k$ 的数目相等,此时我们只需在 $i < k$ 处找到符合条件的索引的 $i$ 的个数即可,此时我们只需要查询 $cnt[g[i] - l[i]]$ 即可。
- 假设我们当前的使得大于 $k$ 的数目与小于 $k$ 的数目之差为 $1$,此时我们只需在 $i < k$ 处找到符合条件的索引的 $i$ 的个数即可,此时我们只需要查询 $cnt[g[i] - l[i] - 1]$ 即可。
- 以 $i$ 为结尾的连续子数组中符合满足要求的子数组的个数即为 $cnt[g[i] - l[i]] + cnt[g[i] - l[i] - 1]$。
- 复杂度分析:
- 时间复杂度:$O(n)$,其中 $n$ 表示给定的数组的长度。
- 空间复杂度:$O(n)$,其中 $n$ 表示给定的数组的长度。
代码
class Solution { |
欢迎关注和打赏,感谢支持!
- 关注我的博客: http://whistle-wind.com/
- 关注我的知乎:https://www.zhihu.com/people/da-hua-niu
- 关注我的微信公众号: 公务程序猿
扫描二维码,分享此文章