再度挑戰
這次的題目稍稍比上次簡單一點,前兩題解完大概還剩 20 分鐘,看看第三題好像也不難,但可惜還是沒寫完,最終成績 1170 / 2668,嗯...好像沒進步 Orz 。
第1題 671. Second Minimum Node In a Binary Tree
問題
給一棵二元樹,每一個node
的子節點不是 0 個就是 2 個,輸出所有節點當中第二小的值,若不存在則輸出-1
。
輸入
tree 的 root
範例:
2
/ \
2 5
/ \
5 7
輸出
5
方法
遍歷所有的節點,不斷刷新最小值(下界)與第二小的值(上界),夾擠出真正第二小的數值。
{% codeblock lang:python %} class Solution(object): def findSecondMinimumValue(self, root): if not root or not root.left: return -1 self.smallest = root.val self.second = max(root.left.val, root.right.val) self.find(root) if self.smallest == self.second: return -1 return self.second def find(self, root): if root.left and root.right: if root.left.val < self.smallest: self.smallest = root.left.val if root.right.val < self.smallest: self.smallest = root.right.val if root.left.val > self.smallest and root.left.val <= self.second: self.second = root.left.val if root.right.val > self.smallest and root.right.val <= self.second: self.second = root.right.val self.find(root.left) self.find(root.right) {% endcodeblock %}第2題 669. Trim a Binary Search Tree
問題
給一個 binary search tree
,以及正整數 L 與 R (L <= R),修剪這棵樹使得所有節點的值介於 [L, R] 。
輸入
tree 的 root 以及 L 與 R 的值
範例:
3
/ \
0 4
\
2
/
1
L = 1
R = 2
輸出
新的 tree 的 root
3
/
2
/
1
方法
利用二元搜尋樹的特性,左子樹的值一定小於等於 root 的值,右子樹的值一定大於等於 root 的值。因此遍歷每一個節點,若 root 的值小於 L ,捨棄左子樹;若 root 的值大於 R ,捨棄右子樹。
1 | class Solution(object): |
第3題 670. Maximum Swap
問題
給一個非負整數,問交換任兩個digit
的位置所能得到的最大值為何?
給的值範圍介於 [0, 108] 之間。
輸入
2736
輸出
7236
方法
範圍介於 [0, 108] ,代表最多有 8 個digit
,任選兩個的可能性只有 28 種,直接用暴力法窮舉所有的可能性。
1 | class Solution(object): |
第4題 672. Bulb Switcher II
問題
給兩個正整數n
與m
,分別代表燈泡的數量以及操作開關的次數,n 個燈泡依序標記為 1, 2, 3,..., n ,一開始所有的燈泡都是打開的。
有以下四種操作開關的方法:
1. 按下所有開關 2. 按下編號為偶數的開關 3. 按下編號為奇數的開關 4. 按下編號為(3k+1)的開關, k = 0, 1, 2, ...
問 n 個燈泡在操作 m 次之後,這些開關的狀態有哪些的可能性。
輸入
n = 3, m = 1.
輸出
4
方法
3 個燈泡在操作 1 次後可能的狀態為:
[off, on, off], [on, off, on], [off, off, off], [off, on, on].
一開始想說用遞迴來解,枚舉所有的可能,但是居然 TLE ,太可惡了!
{% codeblock lang:python %} class Solution(object): def flipLights(self, n, m): self.lights = [True for i in range(n)] self.times = m self.status = [] self.flipping(self.lights, 0) return len(self.status) def flipping(self, light, time): if time == self.times: if light not in self.status: self.status.append(light) return self.flipping([not v for v in light], time + 1) self.flipping([not v if (i + 1) % 2 == 0 else v for i, v in enumerate(light)], time + 1) self.flipping([not v if (i + 1) % 2 == 1 else v for i, v in enumerate(light)], time + 1) self.flipping([not v if (i + 1) % 3 == 1 else v for i, v in enumerate(light)], time + 1) {% endcodeblock %}果然 O(2n) 還是行不通嗎,但是請仔細觀察可能的狀態,就會發現最多的可能只有八種。
n = 1, m = 0
[on]
n = 1, m >= 1
[on], [off]
--------------
n = 2, m = 0
[on, on]
n = 2, m = 1
[off, off], [on, off], [off, on]
n = 2, m >= 2
[on, on], [off, off], [on, off], [off, on]
-------------------------------------------
n = 3, m = 0
[on, on, on]
n = 3, m = 1
[off, off, off], [on, off, on], [off, on, off], [off, on, on]
n = 3, m = 2
[on, on, on], [off, on, off], [on, off, on], [on, off, off], [off, off, off], [off, off, on], [on, on, off]
n = 3, m >= 3
[on, on, on], [off, on, off], [on, off, on], [on, off, off], [off, off, off], [off, off, on], [on, on, off], [off, on, on]
---------------------------------------------------------------------------------------------------------------------------
n >= 4 的情況都跟 n = 3 相同
因此根據n
與m
的值可以歸納出以下的結果:
1 | class Solution(object): |