LeetCode Weekly Contest 96 解題報告
Contest 96
三維形體投影面積
題目描述
每個物體長寬高都是 1,告訴三維座標系裡每個座標點 i (x,y) 上有 Ti 個物體堆疊,求所有物體在每個面的投影面積。(原題是求總投影面積,實際上求出每個面的投影面積,三個加起來就行了)
題解
- 最簡單的,在 xy 平面裡的投影面積,其實就是有多少個座標上有物體
- 在 xz 平面上的投影:看看兩個點 (x1,y1,z1), (x1,y2,z1),這兩個點在 xz 平面上的投影面積是什麼? 因為在 xz 平面上,所以從 y 軸來看,對於同樣的 x,不論 y 怎麼變,只能看到最高的那個。也就是說,當 x=x1 時,求出所有 (x1, yi) 的最大值 k1,投影就是 k1。列舉所有 x,求出所有 kx 即可。
- yz 軸同理
很簡單的題目,詳見AC 程式碼
救生艇
題目描述
有 N 個人,每個人體重是 people[i]。已知救生艇最大載重為 limit,且每艘救生艇不論如何最多載兩人。問需要多少救生艇。
題解
這道題是個貪心,先把體重按從小到大排序。兩個指標 left,right,分別指向剩下的人中最輕和最重的。每個人都要上一艘救生艇,因此 people[left] 先選一艘。left 選了一艘之後,這艘救生艇還可以載一個人,那肯定在能力範圍內載一個越重的人越好,因此就是 right 了。如果 people[left]+people[right]>limit,那 right 那位兄臺只能自己做一艘船了(因為當前最輕的人和他一起坐都超重了)。
詳見AC 程式碼
索引處的解碼字串
題目描述
對於一個字串a2b2c2d2
和一個空串 S,每當遇到字元 c,就往 S 後面追加一個 c。如果遇到一個數字 t,就把 S repeat t 次。 對於a2b2c2d2
,S 最後就成了:aabaabcaabaabcdaabaabcaabaabcd。 給定這個字串,問最後 S 第 k 個字元是什麼
題解
暴力的做法就是模擬 S 串的生成過程,然後輸出第 K 位。但是這個不論是時間複雜度還是空間複雜度都太高。我們一起來想一想,純模擬的方法到底哪些步驟浪費了時間或空間。首先我們可以把整個過程劃分成兩個狀態:
- append
- repeat
append 狀態是說,最近一次 S 串的 repeat 操作完成了,現在讀到了字元,直接 append 到 S 後面。repeat 狀態是說,讀到了一個數字,現在把串 S repeat N 次。串 S 要麼處在 append 狀態要麼處在 repeat 狀態。
那麼如果已知串 S,repeat N 次,這時候我們真的需要開闢一個 N*len(S) 的空間來存新的串嗎?是不是隻需要存成 (S,N) 這樣的 tuple 就好了?由於串是以 len(S) 的長度迴圈的,因此求第 K 位,等價於求第 K%len(S) 位。
想清楚了這個,我們就接著繼續思考。要求整個串的第 K 位,實際上當 S 擴充套件到長度 K 時,它要麼是通過 append 擴充套件的,要麼是通過 repeat 擴充套件的。那我們怎麼知道它是從 append 還是 repeat 擴充套件出來的呢?——記錄最後一次 repeat。怎麼理解記錄最後一次repeat
?假設我們有一個 sum[i] 表示第 i 次 repeat 之後 S 串的總長度,接下來假設讀到了連續 T 個字元,第 T+1 是數字 M。我們很容易發現:
- 下一次迴圈節的長度是 sum[i]+T
- 下一次 repeat 之後的總長度是 (sum[i]+T)*M
假設K>sum[i] && K<=sum[i]+T
,說明第 K 位是 append 狀態擴充套件而來,這時直接輸出新讀到的第 K-sum[i] 個字元就行了。
假設K>sum[i]+T && K<(sum[i]+T)*M
,說明第 K 位是 repeat 擴充套件得到的,迴圈節長度是 sum[i]+T。由前面的推論得知,此時第 K 位是第 K%(sum[i]+T) 位是一樣的,因此問題轉化成了求 S 的第 K%(sum[i]+T) 位。
這就變成了一個相同子問題,我們通過遞迴就能求解了。再想一想遞迴的邊界是什麼?一個字元首先得經過 append,才會進入後續的 repeat 狀態,因此對於某個字元 c,它第一次一定是由 append 擴充套件得到的。所以我們的遞迴只要有判斷 append 的分支,是一定能到達遞迴邊界的。
詳見AC 程式碼
細分圖中的可到達結點
題解
這道題我的解法比較繞,官方的題解簡單易懂。下面說說我的做法吧: 首先用最短路演算法來先求出點 0 到其它所有點的最短路,我這裡使用的是 SPFA。求最短路有什麼用呢?考慮以下 case,假設從 0 出發,經過各種繞走到了 3 號點,耗費了 8 步。假設最多走 10 步,這就意味著從 3 號點繼續走還剩兩步可以走。但是如果從 0 走到 3 的最短路是 5,那麼意味著沿著最短路徑走到 3,此時從 3 出發還能再走 5 步,這意味著可達的點更多。 也就是說,如果某條邊屬於最短路徑上的邊,那麼這條邊上所有點一定是可達的,累加到答案 ans。如果某條邊不是最短路徑上的邊,那麼這條邊能走多長是多長。但是走完之後得記錄這條邊有多長已經是被走過了。
具體實現還有很多細節處理,詳見AC 程式碼
總結
這套題還是有點兒難度的,能在 1 個半小時內全部 AC 的都是大佬,我最後一道題加上除錯花了差不多一個晚上…
- 加微信實戰群請加微信(註明:實戰群):gocnio
相關文章
- Leetcode Weekly Contest 95解題報告LeetCode
- Leetcode Weekly Contest94 解題報告LeetCode
- Weekly Contest 387
- Leetcode 第136場周賽解題報告LeetCode
- LeetCode解題報告 279. Perfect Squares [medium]LeetCode
- [leetcode] 252. Meeting Rooms 解題報告LeetCodeOOM
- LeetCode 解題報告 - 2. Add Two NumbersLeetCode
- [Leetcode] 253. Meeting Rooms II 解題報告LeetCodeOOM
- LeetCode解題報告 120. Triangle [medium]LeetCode
- 【LeetCode】253. Meeting Rooms II 解題報告(C++)LeetCodeOOMC++
- LeetCode解題報告 241. Different Ways to Add Parentheses [medium]LeetCode
- [熵值] 解題報告熵
- LeetCode解題報告 452. Minimum Number of Arrows to Burst Balloons [medium]LeetCode
- 【LeetCode】 Best Time to Buy and Sell Stock I II III IV 解題報告LeetCode
- LeetCode 熱題 HOT 100 Java題解——96. 不同的二叉搜尋樹LeetCodeJava
- ARC173 解題報告
- Educational Codeforces Round 96 A-E 題解
- 【LeetCode】416. Partition Equal Subset Sum 解題報告(Python & C++)LeetCodePythonC++
- LeetCode解題報告 102. Binary Tree Level Order Traversal [easy]LeetCode
- 題解:AtCoder Beginner Contest 367
- CF720B 解題報告
- P10499 解題報告
- LeetCode解題報告 108. Convert Sorted Array to Binary Search Tree [medium]LeetCode
- AtCoder Beginner Contest 352題解
- AtCoder Beginner Contest 376 題解
- 題解:AtCoder Beginner Contest 371
- AtCoder Beginner Contest 378 題解
- AtCoder Beginner Contest 380 (A~E)題解
- 【Flutter 專題】96 圖解 Draggable + DragTarget 基本拖拽效果Flutter圖解
- Kotlin Weekly 中文週報 —— 17Kotlin
- Kotlin Weekly 中文週報 —— 18Kotlin
- Kotlin Weekly 中文週報 —— 19Kotlin
- Kotlin Weekly 中文週報 —— 16Kotlin
- Kotlin Weekly 中文週報 —— 24Kotlin
- 【演算法解題報告】求眾數演算法
- P11188 解題報告
- SP30906 解題報告
- AtCoder Beginner Contest 238 A - F 題解