1. 程式人生 > 其它 >[Leetcode Weekly Contest]321

[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