LeetCode Weekly Contest 376 解題紀錄
被第3題繞暈了,一開始試了一些暴力的作法,後來才想到題目的問的就是數線上距離,從中位數兩側取就可以了。第4題想到了中位數+前綴和計算花費,但是就是沒想到可以用滑動窗口,又是臨門一腳,特別難受。
All problems solved by python
Q1: 🟢 2965. Find Missing and Repeated Values _
tags: 計數(Counting)
陣列(Array)
雜湊表(Hash Table)
數學(Math)
矩陣(Matrix)
題意
- 給定一個大小為 的二維矩陣 ,其中的值在 範圍內。除了 出現兩次, 缺失之外,每個整數都恰好出現一次。
- 返回一個長度為 2 的整數陣列 ,其中 等於 , 等於 。
思路:計數
- 用一個陣列 紀錄每個數字出現的次數
- 掃過一次 ,找出 的 ,即為 ,找出 的 ,即為
- 時間複雜度:
- 空間複雜度:
1 | class Solution: |
Q2: 🟡 2966. Divide Array Into Arrays With Max Difference 1396
tags: 貪心(Greedy)
排序(Sorting)
陣列(Array)
題意
- 給定一個長度為 的整數陣列 ,以及一個正整數 ,將這個陣列分成一個或多個長度為 的子陣列,並滿足以下條件:
- 中的 每個 元素都必須 恰好 存在於某個子陣列中。
- 子陣列中 任意 兩個元素的差必須小於或等於 。
- 傳回一個 二維陣列 ,包含所有的子陣列。 如果不可能滿足條件,就回傳一個空陣列。 如果有多個答案,返回 任一個 即可。
思路:排序
- 由於條件1要求每個元素都要恰好存在於某個子陣列中,因此可以將答案視為將 個數字分成 個子陣列,每個子陣列長度為 。
- 為了滿足條件2,我們可以讓同一個子陣列中的元素盡量接近,因此我們可以先將 排序後,每次取出 個數字,檢查是否滿足條件,如果滿足條件,就加入答案中,否則回傳空陣列。
- 時間複雜度: ,排序的時間複雜度為 ,每次取出 個數字的時間複雜度為 ,因此總時間複雜度為 。
- 空間複雜度: ,排序的空間複雜度為 ,答案的空間複雜度為 ,因此總空間複雜度為 。
1 | class Solution: |
Q3: 🟡 2967. Minimum Cost to Make Array Equalindromic _
tags: 中位數貪心
數學(Math)
貪心(Greedy)
排序(Sorting)
陣列(Array)
題意
- 給定一個長度為 的整數陣列 , 可以對 執行 任意次 操作,每一次操作可以把 中的一個元素變為任意正整數 ,所需花費為 。
- 目標是把 的所有元素都變成相同的數字,且這個數字是一個 回文數,且所需花費最小,返回最小花費。
思路:中位數貪心
- 首先先不考慮回文數的限制,我們可以發現,如果我們把所有數字都變成中位數,那麼所需花費最小,可以由 畫數線 來證明,所需花費即為數線上兩點的距離。
- 若 為奇數,則中位數為 ,將所有數變成 的代價最小。
- 若 為偶數,則不管取 之間的任意數字都可以使代價最小。
- 若中位數為 回文數 ,則將其作為目標數 即為答案,所需代價為 。
- 若中位數不是 回文數 ,則我們可以找兩側最接近的回文數,並計算所需代價,取較小的那個。
- 若 為奇數很好處理,因為中位數只有一個,我們只要找到左右兩側最接近的回文數即可;若 為偶數,則中位數有兩個,但不管取哪一個的左右兩側最接近的回文數皆可,為了在 為奇數或偶數時都能統一處理,取 為中位數。
- 若 存在回文數 ,則不管取 或 作為中位數,和不管兩點之間的回文數數量,都可以找到兩點之間的回文數,根據上面的推論,所需代價皆相同。
- 若 不存在回文數 ,則取 或 向兩側所搜尋到的回文數必定相同。
- 因此,我們只要找到 中最接近中位數的回文數,即可得到答案。
- 時間複雜度: ,排序的時間複雜度為 。
- 空間複雜度:,不考慮排序的空間複雜度
1 | class Solution: |
Q4: 🔴 2968. Apply Operations to Maximize Frequency Score _
tags: 中位數貪心
數學(Math)
貪心(Greedy)
排序(Sorting)
前綴和(Prefix Sum)
滑動窗口(Sliding Window)
陣列(Array)
二分搜尋(Binary Search)
題意
- 給定一個整數陣列 和一個整數 ,可以對陣列執行 最多 次操作,每次操作可以讓陣列中的一個元素 增加或減少 。
- 定義陣列的 頻率分數 為陣列中眾數的 出現次數, 返回操作後最大的頻率分數。
思路:中位數貪心 + 前綴和 + 滑動窗口
- 這題本質上和上一題類似,都是要找到一個數字,使得陣列中的數字變成這個數字,且代價越小越好。為了使代價盡可能的小,我們可以先將陣列 排序 ,則對目標數字 來說,我們只需要操作 左右兩側的數字即可。
- 排序後,此問題變成是否能存在一個子陣列,使得子陣列中的數字都變成相同的數 ,且所需 ,且子陣列的長度最長。
- 承上題的說明,中位數 可以使子陣列變成相同的數字,且所需花費最小。
- 再來考慮如何快速計算花費,我們可以先將陣列的 前綴和 計算出來,則對於一個子陣列 來說,我們可以用 來表示將 變成 所需花費,其中 為陣列的前綴和。
- 最後可以用 滑動窗口 的方式來找到最長的子陣列,若當前窗口的 ,則將窗縮小窗口,直到 為止,更新答案。
- 時間複雜度: ,排序的時間複雜度為 ,計算前綴和的時間複雜度為 ,滑動窗口的時間複雜度為 ,因此總時間複雜度為 。
- 空間複雜度: ,排序的空間複雜度為 ,前綴和的空間複雜度為 ,因此總空間複雜度為 。
1 | class Solution: |
類題
- 🟡 2602. Minimum Operations to Make All Array Elements Equal 1903
相比本題只少了滑動窗口
本部落格所有文章除特別聲明外,均採用 CC BY-NC-SA 4.0 許可協議。轉載請註明來自 十六個天亮!
評論
WalineGiscus