LeetCode 2023/12/01-2023/12/10 每日一題
每日第1題為中文站(LCCN) ,第2題為英文站(LCUS) ,題目連結皆統一為英文站的題目連結。
Easy 、Medium 、Hard 難度的題目分別用🟢🟡🔴表示。
若為周賽題目會額外標註由 @zreotrac
零神計算的rating分數。
All problems solved by python
2023-12-01
🟡 2661. First Completely Painted Row or Column 1503
題意
- 給定一個 和 的矩陣 , 和 都包含 的所有整數
- 依照 的順序,對矩陣中值為 的位置 著色,即 。若 所在的row和col都已經全部著色,返回下標 。
思路:Hash Table + 模擬
- 因為每個元素都是唯一的(洽出現一次),所以可以用 Hash Table 來記錄每個元素出現的位置
- 再來就模擬過程就好了,用 和 紀錄過程中每個 row 和 col 的塗色狀況
1 | class Solution: |
🟢 1662. Check If Two String Arrays are Equivalent 1217
題意
給定 和 ,求兩者組成的字串是否相等。
思路:Build-in function / 逐字模擬
- 令 , 分別表示當前是 和 中第 和 第 個字串,, 表示 和 中第 和 第 個字元,逐字模擬,超過當前字串長度則檢查下一個字串,最後檢查是否已經檢查完所有字串即可。
1 | class Solution: |
2023-12-02
🟡 1094. Car Pooling 1441
題意
- 車上有 個座位,車在一條直線上行駛,且只能往前不能調頭。
- 給定 , 表示有 名乘客要從 搭車到
- 若可以接送所有乘客,則返回 ,否則返回
思路:模擬 + 差分陣列
- 用一個 Arrray 紀錄在 的上車或下車人數,正數表示上車,負數表示下車。從起點一直開到旅途終點,在每個位置檢查車上人數有沒有超載。
1 | class Solution: |
🟢 1160. Find Words That Can Be Formed by Characters 1206
題意
- 給定一份「單字表」 和 一張「字母表」 ,計算可以由 中的字母組合出的所有 的總長度。
- 每次構建一個 時, 中的所有字母都只能使用一次。
思路:Counter
- 根據範例,若一個字母 在 中的出現次數 在 中的出現次數,則被認為可以被構建的。
- 用兩個Counter分別記錄 在 和 中的出現次數,檢查是否滿足條件即可
1 | class Solution: |
2023-12-03
🟡 1423. Maximum Points You Can Obtain from Cards 1574
題意
給定 張卡片, 表示卡片對應的點數,每次可以從牌組的頂端或尾端抽一張卡,最後必需有 張手牌,求可以獲得最好的手牌點數總和,即手牌點數的最大值。
思路:轉化 + 滑動窗口 / 前綴和
將問題轉化為:求長度為n-k的連續子陣列的最小和,此時就能用滑動窗口或前綴和解決了。
1 | class Solution: |
🟢 1266. Minimum Time Visiting All Points 1303
題意
- 給定 個平面上的點 ,座標為整數。計算訪問所有點所需要的「最小時間」,必需按照給定的順序訪問。
- 移動方式為:
- 沿水平方向移動一個單位長度
- 沿垂直方向移動一個單位長度
- 沿對角線移動 個單位長度
思路:模擬
根據題目,從 移動到 ,所需要的時間為 , 直接模擬即可。
1 | class Solution: |
2023-12-04
🟡 1038. Binary Search Tree to Greater Sum Tree 1375
題意
給定一個 Binary Search Tree (BST) 的 ,將其每隔節點的值都替換成 當前節點值的所有節點值之和。
思路
根據 BST 性質,右子樹的節點值皆大於當前節點,因此以DFS方式依次訪問右子樹、當前節點、左子樹,並且維護比當前節點大的值的和 。
1 | class Solution: |
類題
🟢 2264. Largest 3-Same-Digit Number in String 1309
題意
- 給定一個字串 ,求其中長度為 的子字串所有字元皆相等的最大字典序。
- 中只包含 的數字。
思路:Sliding window
- 窗口大小固定為 ,每次移動一格,並更新窗口內的數字出現次數。
- 若檢查所有數字的出現次數,則時間複雜度為
- 若同時統計出現次數的出現次數,則不用逐個字檢查,時間複雜度為
1 | class Solution: |
2023-12-05
🟡 2477. Minimum Fuel Cost to Report to the Capital 2012
一開始沒看到是tree,以為是graph卡了一陣子,後來看到是tree就簡單多了XD
題意
- 給定一個有 個節點的樹,每個節點代表一個城市,其中下標為
0
的節點代表首都。 - 每個城市都有一輛車,每輛車可以載 位乘客,且每個城市都要派出 名代表前往首都,中途中可以換乘別人城市的車,只要不要超載即可。
- 相鄰兩個城市間的 固定為 ,求使得所有代表都能到達首都的最小花費。
思路:DFS
- 因為是樹,所以任意兩節點的最短路徑是唯一的。
- 用DFS訪問每個節點,返回這個節點的子樹中所有節點的數量(包含自己)。也就是到首都數浪會經過當前城市的人數(包含當前城市的代表),計算到前往上一個城市的花費即可。
- 小提醒:樹上的節點數量 等於邊數 加一,
1 | class Solution: |
🟢 1688. Count of Matches in Tournament 1203
題意
- 給定 支隊伍,每場比賽都會淘汰一隊,若剩下偶數支隊伍,進行 場比賽,,若剩下奇數支隊伍,則進行 場比賽,並且其中1支隊伍直接輪空晉級,求比賽的數量。
思路:數學
- 每場比賽都會淘汰一隊,要淘汰 隊,因此需要進行比賽的數量為 。
1 | class Solution: |
2023-12-06
🔴 2646. Minimize the Total Price of the Trips 2238
這題剛好是我的 LeetCode 第500題,紀念一下XD
題意
- 給定一個有 個節點的樹,每個節點代表一個城市,給定一個Array 表示每個城市的旅遊費用。給定 表示旅遊路線,其中 該次旅遊從 城市到 城市,對所有經過的城市都要計算旅遊費用。
- 在開始旅行之前,可以選擇一些城市減半旅遊費用,但選擇的城市不能相鄰,求最小的旅遊費用。
思路:樹形DP + LCA + DFS
-
為方便思考與計算,令下標為
0
的節點代表樹根。 -
選/不選的問題,可以用樹形DP解決,令 表示不選 的最小花費, 表示選 的最小花費。
-
所以這題可以分成兩個部分:
- 根據 的起點和終點,計算每個城市經過的次數
- 用樹形DP判斷每個城市的選或不選
-
為計算樹形DP,需要先計算每個節點的經過次數。因為樹上任意兩點的最短路徑是唯一的,所以可以透過計算兩個節點的
最近公共祖先(Lowest Common Ancestor,LCA)
,來計算每個節點經過的次數。 -
為了方便計算LCA,可以先用DFS計算每個節點的父節點和深度,再以此計算LCA。
1 | class Solution: |
類題
樹形DP
- 🟢 543. Diameter of Binary Tree
- 🔴 124. Binary Tree Maximum Path Sum
- 🔴 2246. Longest Path With Different Adjacent Characters 2126
- 🟡 687. Longest Univalue Path
- 🔴 1617. Count Subtrees With Max Distance Between Cities 2309
- 🔴 2538. Difference Between Maximum and Minimum Price Sum
- 🟡 337. House Robber III
- 🟡 2925. Maximum Score After Applying Operations on a Tree 1940
- 🔴 1377. Frog Position After T Seconds 1824
- 🔴 2646. Minimize the Total Price of the Trips 2238
LCA
- 🔴 1483. Kth Ancestor of a Tree Node 2115
- 🟡 235. Lowest Common Ancestor of a Binary Search Tree
- 🟡 236. Lowest Common Ancestor of a Binary Tree
- 🟡 1123. Lowest Common Ancestor of Deepest Leaves 1607
題單來自: @灵茶山艾府
🟢 1716. Calculate Money in Leetcode Bank 1295
題意
每周一存入 塊錢,從周二到周日,每天都比前一天多存入 塊錢。而在下一周,也會比上一周的同一天多存入 塊錢。計算在 天後,總共存了多少錢。
思路:簡單模擬
對每天算出當天是第幾周、是該周的第幾天,再計算出當天存入的錢即可。
1 | class Solution: |
2023-12-07
🟡 1466. Reorder Routes to Make All Paths Lead to the City Zero 1634
題意
- 給定一個有 個節點的樹,每個節點代表一個城市,有 條 有向邊 作為單向道路連接這些城市。
- 重新規劃道路方向,使得所有城市都能夠前往下標為
0
的城市,求最少需要改變的道路方向數量。
思路:DFS紀錄正向邊數量
- 為方便思考與計算,令下標為
0
的節點代表樹根。將 正向邊 定義為從父節點指向子節點的邊, 反向邊 定義為從子節點指向父節點的邊。 - 對根節點進行DFS,計算每個節點的正向邊數量,即為改變道路方向的數量。
- 題外話,除了在DFS時傳入 的父節點,也可以用 來記錄每個節點是否被訪問過
1 | class Solution: |
🟢 1903. Largest Odd Number in String 1249
題意
給定一個字串 ,表示一個大整數,在 的所有 非空子字串中 找出值最大的奇數,並以字串形式返回,若不存在奇數,則返回空字串。
思路
要使值最大,則前面的數要盡可能的多,所以找到最後一個奇數,返回前面的數字即可。
1 | class Solution: |
2023-12-08
🟡 2008. Maximum Earnings From Taxi 1872
題意
- 給定一條道路的長度 ,從 到 編號,給定一個下標由
0
開始 表示 個乘客的訂單,其中 表示第 個乘客從 到 ,願意支付 的小費,對於每個乘客的收益是 ,以下用 表示。 - 你必需從 開到 ,並且只能往右走,不能回頭 ,每次只能接受一位乘客,求最大的收益總和。
- 注意:你可以在一個地點放下一位乘客,並在同一個地點接上另一位乘客。
思路:DP + 二分搜尋
Weighted Job Scheduling / Weighted Interval Scheduling
- 這題可以對 做DP,也能對地點做DP,而對 做DP,本質上就是 Weighted Interval Scheduling 問題,可以將每個乘客的上下車地點視為區間 。
- 令 表示只考慮前 個乘客的最大收益,對於第 個乘客(下標為
i
),我們可以選擇接或不接。- 若接的話則需要考慮上一個乘客是誰,目標是找到上一個相容(compatible) 的乘客(令其下標為
j
),也就是說上一個乘客的結束時間要小於等於當前乘客的開始時間 () ,此種情況 - 若不接的話,則 ,考慮兩種情況的最大值即可。
- 若接的話則需要考慮上一個乘客是誰,目標是找到上一個相容(compatible) 的乘客(令其下標為
- 首先對 按照結束時間排序,確保若上一個相容相容(compatible) 的區間若存在,其下標必在當前區間的下標之前,因此具有單調性 ,可以用二分搜尋找到上一個相容的乘客。
- 這裡使用
bisect
,其中bisect.bisect_right
回傳 的第一個下標 (相當於C++中的upper_bound
),bisect.bisect_left
回傳 第一個下標 (相當於C++中的lower_bound
)。- 使用
hi
參數,可以用來限制搜尋的範圍,因為 已經按照結束時間排序,所以只要限制在當前區間的下標之前即可。
- 上一個相容的乘客的下標 ,即第一個滿足 的 前一個下標 。
- 舉個🌰,為方便理解,令 表示與 兼容的下標 。對於範例2(已排序): = [(1, 6, 1), (3, 10, 2), (10, 12, 3), (11, 12, 2), (12, 15, 2), (13, 18, 1)]
- ,表示在 之前,不存在和其相容的區間
- ,同上。
- ,表示在 之前,第一個和其相容的區間
- ,表示在 之前,第一個和其相容的區間
- ,表示在 之前,第一個和其相容的區間
- ,表示在 之前,第一個和其相容的區間
1 | class Solution: |
類題
- 🟡 2830. Maximize the Profit as the Salesman 1851
- 🔴 1235. Maximum Profit in Job Scheduling 2023
- 🟡 435. Non-overlapping Intervals
- 🔴 1751. Maximum Number of Events That Can Be Attended II 2041
- 🟡 2054. Two Best Non-Overlapping Events 1883
- 🟢 1576. Replace All ?'s to Avoid Consecutive Repeating Characters 1368
參考資料
🟢 606. Construct String from Binary Tree
題意
- 給定一個二元樹的樹根 ,用preorder traversal的方式,將二元樹轉換為一個由括號和整陣列成的字串。
- 若子節點為空,則用括號表示。轉換後需維持和二元樹的對應關係,並且需要省略字串中多餘的括號。
思路:Recursion
- 根據題意,需要維持對應關係。顯然的,當只有一個子節點時,需要加上括號,否則無法區分是左子樹還是右子樹。
- 由範例說明,若左子樹不為空、右子樹為空,可以省略右子樹的括號;若左子樹為空、右子樹不為空,左子樹的括號不能省略。
- 用DFS遍歷樹,判斷左右子樹是否為空,根據不同情況在不同位置加上括號。返回當前子樹的字串表示即可。
1 | class Solution: |
2023-12-09
🟡 2048. Next Greater Numerically Balanced Number 1734
題意
- 如果整數 滿足:對於每個位數 ,恰好在 中出現 次。 那麼整數 就是一個 數值平衡數。
- 給定一個整數 ,返回 的 最小數值平衡數 。
思路:打表 / 枚舉 / 回溯 + 二分
- 枚舉出現了哪些數字,並且計算每個數字出現的次數,
- 對於1位數:1
- 對於2位數:22
- 對於3位數:122 / 333
- 對於4位數:1333 / 4444
- 對於5位數:14444 / 22333
- 對於6位數:122333 / 155555 / 224444
- 若出現4種數字,則位數至少為 ,超出題目範圍,故考慮最多出現3種數字即可
- 在 位數中,必存在 個 和 個 (對 ),所以檢查 的位數 和所 位數即可。
一些優化
- 重複物排列可以用
backtracking
,枚舉出現的數字也能用backtracking
。 - 但還是打表快多了XD
1 | class Solution: |
1 | class Solution: |
1 | class Solution: |
🟢 94. Binary Tree Inorder Traversal
題意
給定一個Binary Tree的樹根 ,返回其Inorder Traversal的結果。
思路
就是DFS的中序遍歷,先遍歷左子樹,再遍歷根節點,最後遍歷右子樹。
1 | class Solution: |
2023-12-10
🟢 70. Climbing Stairs
題意
從第 階爬到第 階,每次只能爬 階或 階,求有幾種不同的爬法。
思路:DP
因為每次只能爬 階或 階,所以爬到第 階的方法數,等於爬到第 階的方法數加上爬到第 階的方法數。轉移方程為 ,初始條件為 。
1 | class Solution: |
🟢 867. Transpose Matrix
題意
給定一個二維陣列 , 返回 的 轉置矩陣 。
思路
直接模擬即可。
1 | class Solution: |
寫在最後
從12月開始,除了原本的每天做題外,強迫自己開始寫解題記錄,深刻體會到寫題10分鐘,寫題解1小時的感覺,但也學到了很多東西,希望能持續下去。