演算法與資料結構
  • 簡介
  • 前言
    • 事前準備
    • 資料結構場景
    • 複雜度分析
      • 時間複雜度
      • 空間複雜度
  • 分類題型
    • Array 陣列
      • 88. Merge Sorted Array
      • 1089. Duplicate Zeros
      • 941. Valid Mountain Array
      • 1710. Maximum Units on a Truck
      • 54. Spiral Matrix
      • 73. Set Matrix Zeroes
      • 498. Diagonal Traverse
      • 238. Product of Array Except Self
      • HackerRank Counting Valleys
      • 1089. Duplicate Zeros
    • Backtrack 回溯法
      • 51. & 52. N Queens
      • 37. Sudoku Solver
      • 77. Combinations
      • 39. Combination Sum
        • 40. Combination Sum II
        • 216. Combination Sum III
      • 78. Subsets
        • 90. Subsets II
      • 46. Permutations
        • 47. Permutations II
      • 22. Generate Parentheses
      • 1087. Brace Expansion
      • 332. Reconstruct Itinerary
      • 489. Robot Room Cleaner
      • 17. Letter Combinations of a Phone Number
      • 79. Word Search
        • 212. Word Search II
      • 425. Word Squares
      • 1219. Path with Maximum Gold
      • 247. Strobogrammatic Number II
    • Binary Search 二分搜索
      • Rotated Array 旋轉陣列問題
        • 33. Search in Rotated Sorted Array
        • 81. Search in Rotated Sorted Array II
        • 153. Find Minimum in Rotated Sorted Array
        • 154. Find Minimum in Rotated Sorted Array II
      • 374. Guess Number Higher or Lower
      • 704. Binary Search
      • 34. Find First and Last Position of Element in Sorted Array
      • 69. Sqrt(x)
      • 367. Valid Perfect Square
      • 374. Guess Number Higher or Lower
      • 278. First Bad Version
      • 162. Find Peak Element
      • 852. Peak Index in a Mountain Array
      • 35. Search Insert Position
      • 875. Koko Eating Bananas
      • 1011. Capacity To Ship Packages Within D Days
      • 173. Binary Search Tree Iterator
      • 1586. Binary Search Tree Iterator II
    • Dynamic Programming 動態規劃
      • 509. Fibonacci Number
      • 70. Climbing Stairs
      • 55. Jump Game
      • 62. Unique Paths
      • 64. Minimum Path Sum
      • 174. Dungeon Game
      • 91. Decode Ways
      • 72. Edit Distance
      • 221. Maximal Square
      • 329. Longest Increasing Path in a Matrix
      • 198. House Robber
        • 213. House Robber II
      • 1109. Corporate Flight Bookings
      • 983. Minimum Cost For Tickets
      • 1143. Longest Common Subsequence
        • 583. Delete Operation for Two Strings
        • 712. Minimum ASCII Delete Sum for Two Strings
      • 53. Maximum Subarray
      • 152. Maximum Product Subarray
      • 975. Odd Even Jump
      • 115. Distinct Subsequences
      • 416. Partition Equal Subset Sum
      • 10. Regular Expression Matching
      • 651. 4 Keys Keyboard
    • Hash Table/Set 雜湊表
      • 242. Valid Anagram
      • 49. Group Anagrams
      • 217. Contains Duplicate
        • 219. Contains Duplicate II
        • 220. Contains Duplicate III
      • 187. Repeated DNA Sequences
      • 1170. Compare Strings by Frequency of the Smallest Character
      • 448. Find All Numbers Disappeared in an Array
      • 560. Subarray Sum Equals K
      • 1010. Pairs of Songs With Total Durations Divisible by 60
    • Heap 堆
      • 347. Top K Frequent Elements
      • 692. Top K Frequent Words
      • 973. K Closest Points to Origin
      • 128. Longest Consecutive Sequence
      • 1167. Minimum Cost to Connect Sticks
    • Linked List 鏈結串列
      • 876. Middle of the Linked List
      • 21. Merge Two Sorted Lists
        • 23. Merge k Sorted Lists
      • 148. Sort List
      • 206. Reverse Linked List
        • 92. Reverse Linked List II
    • Stack 棧
      • 20. Valid Parentheses
      • 394. Decode String
      • 84. Largest Rectangle in Histogram
      • 155. Min Stack
    • String 字串
      • 43. Multiply Strings
      • 344. Reverse String
      • 726. Number of Atoms
      • 8. String to Integer (atoi)
      • 12. Integer to Roman
      • 696. Count Binary Substrings
    • Tree 樹
      • Breadth-first search 廣度優先搜索
        • 111. Minimum Depth of Binary Tree
        • 200. Number of Islands
        • 752. Open the Lock
        • 279. Perfect Squares
        • 286. Walls and Gates
        • 417. Pacific Atlantic Water Flow
        • 994. Rotting Oranges
        • 429. N-ary Tree Level Order Traversal
        • 116. Populating Next Right Pointers in Each Node
        • 117. Populating Next Right Pointers in Each Node II
        • 430. Flatten a Multilevel Doubly Linked List
        • 1135. Connecting Cities With Minimum Cost
      • Preorder 前序遍歷
        • 105. Construct Binary Tree from Preorder and Inorder Traversal
        • 144. Binary Tree Preorder Traversal
        • 589. N-ary Tree Preorder Traversal
        • 255. Verify Preorder Sequence in Binary Search Tree
      • Inorder 中序遍歷
        • 94. Binary Tree Inorder Traversal
        • 426. Convert Binary Search Tree to Sorted Doubly Linked List
      • Postorder 後序遍歷
        • 106. Construct Binary Tree from Inorder and Postorder Traversal
        • 145. Binary Tree Postorder Traversal
        • 590. N-ary Tree Postorder Traversal
        • 114. Flatten Binary Tree to Linked List
        • 652. Find Duplicate Subtrees
        • 124. Binary Tree Maximum Path Sum
        • 543. Diameter of Binary Tree
        • 337. House Robber III
      • BST
        • 98. Validate Binary Search Tree
        • 450. Delete Node in a BST
        • 700. Search in a Binary Search Tree
        • 701. Insert into a Binary Search Tree
        • 1373. Maximum Sum BST in Binary Tree
        • 230. Kth Smallest Element in a BST
        • 99. Recover Binary Search Tree
      • Serialization & Deserialization
        • 606. Construct String from Binary Tree
        • 536. Construct Binary Tree from String
        • 297. Serialize and Deserialize Binary Tree
        • 428. Serialize and Deserialize N-ary Tree
      • Graph 圖
        • 1971. Find if Path Exists in Graph
        • 323. Number of Connected Components in an Undirected Graph
        • 547. Number of Provinces
      • 100. Same Tree
        • 572. Subtree of Another Tree
      • 1379. Find a Corresponding Node of a Binary Tree in a Clone of That Tree
      • 226. Invert Binary Tree
      • 104. Maximum Depth of Binary Tree
      • 559. Maximum Depth of N-ary Tree
      • 102. Binary Tree Level Order Traversal
      • 261. Graph Valid Tree
      • 250. Count Univalue Subtrees
      • 222. Count Complete Tree Nodes
      • 112. Path Sum
      • 113. Path Sum II
      • 437. Path Sum III
    • Trie 字典樹
      • 208. Implement Trie (Prefix Tree)
      • 677. Map Sum Pairs
      • 648. Replace Words
      • 588. Design In-Memory File System
      • 642. Design Search Autocomplete System
      • 211. Design Add and Search Words Data Structure
      • 1268. Search Suggestions System
    • Two Pointers 雙指針
      • 977. Squares of a Sorted Array
      • 1095. Find in Mountain Array
      • 27. Remove Element
      • 141. Linked List Cycle
        • 142. Linked List Cycle II
      • 19. Remove Nth Node From End of List
      • 26. Remove Duplicates from Sorted Array
      • 83. Remove Duplicates from Sorted List
      • 283. Move Zeroes
    • Sliding Window 滑動窗口
      • 3. Longest Substring Without Repeating Characters
      • 76. Minimum Window Substring
      • 567. Permutation in String
      • 438. Find All Anagrams in a String
      • 424. Longest Repeating Character Replacement
      • 485. Max Consecutive Ones
      • 1004. Max Consecutive Ones III
      • 904. Fruit Into Baskets
      • 1248. Count Number of Nice Subarrays
      • 1358. Number of Substrings Containing All Three Characters
      • 1234. Replace the Substring for Balanced String
      • 930. Binary Subarrays With Sum
      • 209. Minimum Size Subarray Sum
      • 992. Subarrays with K Different Integers
      • 713. Subarray Product Less Than K
      • 862. Shortest Subarray with Sum at Least K
      • 239. Sliding Window Maximum
      • 159. Longest Substring with At Most Two Distinct Characters
      • 340. Longest Substring with At Most K Distinct Character
      • 992. Subarrays with K Different Integers
    • Bit Manipulation 位元運算
      • 136. Single Number
      • 7. Reverse Integer
      • 191. Number of 1 Bits
    • Math 數學
      • 553. Optimal Division
      • 204. Count Primes
      • 372. Super Pow
      • 829. Consecutive Numbers Sum
      • 1492. The kth Factor of n
    • Other 其他
      • 31. Next Permutation
      • 1446. Consecutive Characters
      • 386. Lexicographical Numbers
      • 269. Alien Dictionary
      • 48. Rotate Image
      • 157. Read N Characters Given Read4
        • 158. Read N Characters Given Read4 II - Call multiple times
      • 246. Strobogrammatic Number
    • Object Oriented Design 物件導向設計
      • 710. Random Pick with Blacklist
      • 380. Insert Delete GetRandom O(1)
      • 271. Encode and Decode Strings
      • 348. Design Tic-Tac-Toe
  • 經典題目
    • Best Time to Buy and Sell Stock 股票買賣問題
      • 121. Best Time to Buy and Sell Stock
      • 122. Best Time to Buy and Sell Stock II
      • 123. Best Time to Buy and Sell Stock III
      • 188. Best Time to Buy and Sell Stock IV
      • 309. Best Time to Buy and Sell Stock with Cool down
      • 714. Best Time to Buy and Sell Stock with Transaction Fee
    • Palindrome 回文
      • 125. Valid Palindrome
      • 680. Valid Palindrome II
      • 266. Palindrome Permutation
      • 9. Palindrome Number
      • 866. Prime Palindrome
      • 5. Longest Palindromic Substring
      • 647. Palindromic Substrings
      • 516. Longest Palindromic Subsequence
      • 1930. Unique Length-3 Palindromic Subsequences
      • 234. Palindrome Linked List
    • Time Intervals 時間區間問題
      • 252. Meeting Rooms
      • 253. Meeting Rooms II
      • 56. Merge Intervals
      • 57. Insert Interval
      • 495. Teemo Attacking
      • 759. Employee Free Time
      • 986. Interval List Intersections
      • 435. Non-overlapping Intervals
      • 452. Minimum Number of Arrows to Burst Balloons
      • 729. My Calendar I
      • 731. My Calendar II
      • 732. My Calendar III
      • 163. Missing Ranges
      • 1024. Video Stitching
    • Calculator 計算機問題
      • 224. Basic Calculator
      • 227. Basic Calculator II
      • 772. Basic Calculator III
    • Add One 加一問題
      • 66. Plus One
      • 67. Add Binary
      • 369. Plus One Linked List
      • 2. Add Two Numbers
        • 445. Add Two Numbers II
      • 989. Add to Array-Form of Integer
    • Clone Graph 複製圖形
      • 133. Clone Graph
      • 1490. Clone N-ary Tree
      • 138. Copy List with Random Pointer
      • 1485. Clone Binary Tree With Random Pointer
    • Cache 快取問題
      • 146. LRU Cache 最久未使用演算法
      • 460. LFU Cache 最近最少使用演算法
    • n Sum 問題
      • 1. 2 Sum
      • 15. 3Sum
      • 18. 4Sum
      • 454. 4 Sum II
      • 167. Two Sum II - Input array is sorted
      • 170. Two Sum III - Data structure design
      • 653. Two Sum IV - Input is a BST
      • 16. 3Sum Closest
      • 259. 3Sum Smaller
      • 16. 3Sum Closest
    • Lowest Common Ancestor of a Binary Tree 最近共同祖先問題
    • The Maze 球滾迷宮問題
      • 490. The Maze
      • 505. The Maze II
    • Find Median 尋找中位數
      • 295. Find Median from Data Stream
      • 4. Median of Two Sorted Arrays
    • Course 課程問題
      • 207. 210. Course Schedule I & II
      • 1136. Parallel Courses
    • Coin Change 零錢問題
      • 322. Coin Change
      • 518. Coin Change 2
    • Binary Indexed Tree 樹狀陣列或二元索引樹
      • 303. Range Sum Query - Immutable
      • 307. Range Sum Query - Mutable
      • 315. Count of Smaller Numbers After Self
    • Longest Increasing Subsequence 最長遞增子序列的問題
      • 300. Longest Increasing Subsequence
      • 354. Russian Doll Envelopes
      • 673. Number of Longest Increasing Subsequence
    • Robot Bounded In Circle 掃地機器人
    • Containing Water 裝水問題
      • 11. Container With Most Water
      • 42. Trapping Rain Water
      • 755. Pour Water
    • Word Ladder 文字梯問題
      • 127. Word Ladder
      • 126. Word Ladder II
    • Egg Drop 高樓扔雞蛋
    • Custom sorting 排序技巧
      • 937. Reorder Data in Log Files
    • Word Break 字串組合問題
      • 139. Word Break
      • 140. Word Break II
      • 472. Concatenated Words
  • 常見演算法
    • Sorting 排序
      • Merge Sort (Accepted)
      • Quick Sort (Accepted)
      • Heap Sort (Accepted)
      • Bubble Sort (TLE)
      • Insertion Sort (TLE)
      • Selection Sort (TLE)
    • Shuffle Array 打亂陣列內的元素
    • 池塘抽樣
      • 382. Linked List Random Node
      • 398. Random Pick Index
  • Python 技巧
    • 陣列複製
    • 矩陣操作
      • 向矩陣中的四個方向移動
      • 矩陣遍歷的方法
Powered by GitBook
On this page
  1. 經典題目

Egg Drop 高樓扔雞蛋

Previous126. Word Ladder IINextCustom sorting 排序技巧

Last updated 3 years ago

這個題目其實是一個經典的演算法: ,這是一個很經典的考題,但是我是面試完了才知道。

題目的敘述如同維基百科所寫:

給你兩個相同的異常堅硬的雞蛋,通過在一棟100層的樓的不同層扔下雞蛋進行實驗,試驗出可以摔碎該雞蛋的最高樓層(臨界樓層)。已知未碎的雞蛋可以重複使用。求最少的實驗次數 n,使得在 n 次實驗後,一定能判斷出該臨界樓層。

為了更加精確地思考問題,該問題中必須滿足以下的條件:

  1. 如果雞蛋在某一層沒有碎,它不會在任何更低層的破碎。

  2. 如果雞蛋在某一層碎了,它在更高層上一定會碎。

  3. 雞蛋可能在一樓摔破,也可能在最高層還不摔破。

以上就是這個題目的精神,其實這個題目很像是我們在求時間複雜度的最糟狀況。

先思考的是如果我有無限顆雞蛋的情況下,最少的實驗次數一定是從中間的樓層開始丟,如果沒有破掉,我就在往更高樓的地方找,如果破掉了,我就往下找,每次的搜尋我都減少一半的搜索空間,如果我有一百層樓,搜索的次數會是 log2100=6.643856log_{2}100 = 6.643856log2​100=6.643856 至少需要七次的測試,時間複雜度 O(logN)O(logN)O(logN) 。

可是如果我只有一顆蛋,我的策略就必須要保守一點,如果我從中間開始丟,雞蛋直接破掉了,那我就完全不知道解答是什麼了,一樣是一百層樓,那我就必須要從一樓開始丟,我需要丟 99 次,時間複雜度 O(N)O(N)O(N) 。

不過這一題要問的,都不是上面兩種情況,要問的是如果只有兩顆蛋呢,可以是這樣嗎?我先用第一顆蛋嘗試,我從中間丟下去,沒有破,我就往上走,直到破掉為止,不過也很有可能我從五十樓一丟,蛋就破掉了,那我剩下個一顆蛋勢必要再從一樓開始,所以我總共要花 1 + 49 次,去實驗嗎?這是一個最糟的情況,可是其實這並不是答案,如果是有一百樓,正確的答案是只要花 14 次就可以了,這就是這個題目最困難的地方了,為什麼正確答案是 14 ?

要了解這個題目,也是要從二分法開始說起,二分法總共會分了兩邊,但是接下來就是一個線性搜尋,如果說一開始的分法,分多一點的話,是不是可以節省一點?這裡以十分法為例,把樓層總共分十等分,在 10, 20, 30, 40, 50, 60, 70, 80, 90 這些樓層丟雞蛋。

首先先看如果在 10 樓就碎了第一顆雞蛋,那接下來只要嘗試 1 - 9 樓,那總共的嘗試次數就是 1 + 9 = 10,如果 10 樓沒有碎,就在 20 樓再丟一次,如果碎了,那就是我們要嘗試 11 - 19 樓,總共是 2 + 9 = 11 次,

樓層
最少嘗試次數

10

10 (1+9)

20

11 (2+9)

30

12 (3+9)

40

13 (4+9)

50

14 (5+9)

60

15 (6+9)

70

16 (7+9)

80

17 (8+9)

90

19 (9+10) 這裡包含了最後的第一百樓

這裡我們可以看到需要嘗試的比起二分法來說,所需要嘗試的次數已經很接近到每次嘗試的次數都差不多了,這就是這一題的精髓了,那就是上面的所有的想法,都是我們把總共 n 層樓,分成 k 等分,每一等分都數量都一樣,可是每一等分的數量相同這件事情不是必須的,這也就是最難想到的地方,如果我們要有 x 等分,每一個等分是應該要是 x, x-1, x-2, ..., 1 ,才對,為什麼是這樣呢?因為第一等分的時候,代表我嘗試丟了一次雞蛋就碎了,接下來我要嘗試丟 x 樓,才能找到答案,如果在第二等份才碎掉,那要再嘗試的就是 x - 1 次才能知道答案,也就是每一個等分的搜尋,都會丟了 x + 1 次。

等分
該等分樓層數量
最少嘗試次數

1

x

1 + x

2

x-1

2 + x - 1 = 1 + x

3

x-2

3 + x - 2 = 1 + x

...

...

x

1

x + 1 = 1 + x

有了這個概念後,我們推導出結論,那就是總共的樓層數是 n ,其存在一個關係式是

n=x+(x−1)+(x−2)+...+2+1=1+2+...+x=x(x+1)2\begin{equation} \begin{split} n & = x + (x-1) + (x-2)+ ... + 2 + 1 \\ &= 1 + 2 + ... + x \\ & = \frac{x(x+1)}{2} \end{split} \end{equation}n​=x+(x−1)+(x−2)+...+2+1=1+2+...+x=2x(x+1)​​​​

但是因為大樓的等分法是不可分割的,所以我們要找到的 x 其實應該是要找到符合以下條件的最小正整數 x :

x(x+1)2≥n\frac{x(x+1)}{2} \geq n2x(x+1)​≥n

題目要問的就是對一元二次方程式 x2+x−2n=0x^2+x-2n = 0 x2+x−2n=0求解,一元二次方程式的求解公式為:

x=−b±b2−4ac2ax = \frac{-b\pm\sqrt{b^2-4ac}}{2a}x=2a−b±b2−4ac​​

其中題目 a=1,b=1,c=−2na = 1, b = 1, c = -2n a=1,b=1,c=−2n,因此題目可以用以下方式來求解:

class Solution:
    def twoEggDrop(self, n: int) -> int:
        a = 1
        b = 1
        c = - 2 * n
    
        x = (-b + (b * b - 4 * a * c)**0.5) / 2.0
        
        # 如果 x 是整數,則直接是答案,如果不是整數,需要向上取整。
        if x - int(x) == 0 :
            return int(x)
        return int(x) + 1

一直到了這裡段落都是在講數學問題,如果是雙蛋的問題,那我們的確可以針對方程式求解,而且我們目前也僅止討論到了雞蛋數量是一顆、兩顆和無限顆的三種情況,如果蛋的數量不定的話,又要如何求解呢?也就是這個題目是不是可以泛化成一個程式來求解?

於是再度跳回來看這個題目的設定,如果我從「任意」的一個樓層開始丟雞蛋,都一定會發生有以下任一種情況,破,或是沒有破,咦?這不是前面的二分法嗎?沒錯,前面的二分法只討論了如果一開始就破了,那最糟的情況需要投幾次,可是我們並沒有繼續討論到如果沒有破的情況是怎麼樣,其實如果一直討論下去,其實就一定會討論到在每一層,到底丟了幾次,並且討論到不同分法的情況,而這個過程就是一個遞迴的方程式如下。

floori=max{f(i−1,eggs−1),f(n−i,eggs)}+1f(n,eggs)=min{floor1,floor2,...,floori,...floorn}floor_{i} = max\{f(i-1, eggs-1), f(n-i, eggs)\} + 1 \\ f(n, eggs) = min\{floor_{1}, floor_{2}, ..., floor_{i}, ... floor_{n} \}floori​=max{f(i−1,eggs−1),f(n−i,eggs)}+1f(n,eggs)=min{floor1​,floor2​,...,floori​,...floorn​}
class Solution:
    def superEggDrop(self, k: int, n: int) -> int:
        if k <= 1:
            return n
        if n == 0:
            return 0
        return min([max(self.superEggDrop(k-1, i-1), self.superEggDrop(k, n-i) + 1) for i in range(1, n+1)])

不過上面這個程式就存在著很多的重疊子問題,因此可以用記憶法的方式來搜尋如下,不過在 LeetCode 上,這樣的做法還是會「超時」!這一題要一路寫完真的是非常的折騰。

class Solution:
    def superEggDrop(self, k: int, n: int) -> int:

        memo = {}
        def dp(k, n):
            if k == 1: return n
            if n == 0: return 0
            if (k, n) in memo:
                return memo[(k, n)]
            res = float('inf')
            for i in range(1, n+1):
                res = min(res, max(dp(k - 1, i - 1), dp(k, n - i)) + 1)
            memo[(k, n)] = res
            return memo[(k, n)]

        return dp(k, n)

TODO

透過二分搜索來加速

class Solution:
    def superEggDrop(self, k: int, n: int) -> int:

        memo = {}
        def dp(floors, eggs):
            if eggs == 1: return floors
            if floors == 0: return 0
            if (floors, eggs) in memo:
                return memo[(floors, eggs)]
            res = float('inf')
            lo, hi = 1, floors
            while lo <= hi:
                mid = (lo + hi) // 2
                broken = dp(mid - 1, eggs - 1)
                not_broken = dp(floors - mid, eggs)
                if broken > not_broken:
                    hi = mid - 1
                    res = min(res, broken + 1)
                else:
                    lo = mid + 1
                    res = min(res, not_broken + 1)

            memo[(floors, eggs)] = res
            return memo[(floors, eggs)]
        
        return dp(n, k)
1884. Egg Drop With 2 Eggs and N Floors
887. Super Egg Drop
雙蛋問題