[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

posted @ 2022-11-29 21:10  Jamest  阅读(23)  评论(0编辑  收藏  举报