[Leetcode Weekly Contest]321
链接:LeetCode
[Leetcode]2485. 找出中枢整数
给你一个正整数 n ,找出满足下述条件的 中枢整数 x :
1 和 x 之间的所有元素之和等于 x 和 n 之间所有元素之和。
返回中枢整数 x 。如果不存在中枢整数,则返回 -1 。题目保证对于给定的输入,至多存在一个中枢整数。
1 到 x 的元素和为 $\dfrac{x(x+1)}{2} $ ,x 到 n 的元素和为 1 到 n 的元素和减去 1 到 x−1 的元素和,即 $\dfrac{n(n+1)-x(x-1)}{2} $ 。
两式相等,简化后即
\(x = \sqrt{\dfrac{n(n+1)}{2}}\)
如果 x 不是整数则返回 −1。
public class Solution {
public int pivotInteger(int n) {
double x = Math.sqrt((n+n*n)/2.0);
return x == (int)x ? (int)x: -1 ;
}
}
[Leetcode]2486. 追加字符以获得子序列
给你两个仅由小写英文字母组成的字符串 s 和 t 。
现在需要通过向 s 末尾追加字符的方式使 t 变成 s 的一个 子序列 ,返回需要追加的最少字符数。
子序列是一个可以由其他字符串删除部分(或不删除)字符但不改变剩下字符顺序得到的字符串。
贪心,双指针遍历 s 和 t,t[j] 应匹配 i 尽量小(但大于上一个的匹配的位置)的 s[i]。
class Solution {
public int appendCharacters(String s, String t) {
int start = 0, end = t.length()-1;
for(char ch:s.toCharArray()) {
if(ch == t.charAt(start)) {
start ++;
if(start > end) return 0;
}
}
return t.length()-start;
}
}
[Leetcode]2487. 从链表中移除节点
给你一个链表的头节点 head 。
对于列表中的每个节点 node ,如果其右侧存在一个具有 严格更大 值的节点,则移除 node 。
返回修改后链表的头节点 head 。
单调栈。通过ArrayDeque实现。
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode() {}
* ListNode(int val) { this.val = val; }
* ListNode(int val, ListNode next) { this.val = val; this.next = next; }
* }
*/
class Solution {
public ListNode removeNodes(ListNode head) {
ListNode dummy = new ListNode((int)1e5, head);
ListNode cur = head;
Deque<ListNode> queue = new ArrayDeque<>();
queue.push(dummy);
while(cur != null) {
while(cur.val > queue.peek().val) {
queue.pop();
}
queue.peek().next = cur;
queue.push(cur);
cur = cur.next;
}
return dummy.next;
}
}
[Leetcode]2488. 统计中位数为 K 的子数组
给你一个长度为 n 的数组 nums ,该数组由从 1 到 n 的 不同 整数组成。另给你一个正整数 k 。
统计并返回 num 中的 中位数 等于 k 的非空子数组的数目。
注意:
- 数组的中位数是按 递增 顺序排列后位于 中间 的那个元素,如果数组长度为偶数,则中位数是位于中间靠 左 的那个元素。
例如,[2,3,1,4] 的中位数是 2 ,[8,4,3,5,1] 的中位数是 4 。 - 子数组是数组中的一个连续部分。
枚举 & 分类讨论
class Solution {
public int countSubarrays(int[] nums, int k) {
int pos = 0, n = nums.length;
while (nums[pos] != k) ++pos;
var cnt = new HashMap<Integer, Integer>();
cnt.put(0, 1); // i=pos 的时候 c 是 0,直接记到 cnt 中,这样下面不是大于就是小于
for (int i = pos + 1, c = 0; i < n; ++i) {
c += nums[i] > k ? 1 : -1;
cnt.put(c, cnt.getOrDefault(c, 0) + 1);
}
int ans = cnt.get(0) + cnt.getOrDefault(1, 0); // i=pos 的时候 c 是 0,直接加到答案中,这样下面不是大于就是小于
for (int i = pos - 1, c = 0; i >= 0; --i) {
c += nums[i] < k ? 1 : -1;
ans += cnt.getOrDefault(c, 0) + cnt.getOrDefault(c + 1, 0);
}
return ans;
}
}
参考:LeetCode