給定正整數 n,找到若干個完全平方數(比如1, 4, 9, 16, ...
)使得它們的和等於n。你需要讓組成和的完全平方數的個數最少。
示例 1:
輸入: n = 12
輸出: 3
解釋: 12 = 4 + 4 + 4.
示例 2:
輸入: n = 13
輸出: 2
解釋: 13 = 4 + 9.
class solution(object):
def numsquares(self, n):
""":type n: int
:rtype: int
"""if n == 0:
return 0
queue = deque([n])
visited = set()
path = 0
while queue:
path += 1
length = len(queue)
for i in range(length):
num = queue.popleft()
for j in range(1, int(num**0.5+1)):
x = num - j*j
if x == 0:
return path
if x not in set():
visited.add(x)
return none
解析:
遍歷所有的可能組合是比較直觀的一種方式。但是暴力的遍歷顯然是不行的,一旦當n較大時就肯定會耗費大量的時間。這裡遍歷設計的是採用佇列的方式,用廣度優先的方式來搜尋。這樣做的好處是一旦在某一層得到我們想要的答案,就能立馬返回結果,不需要進行後面的計算。因為每一層列舉了所有的組合可能,如果這一層的某乙個路徑符合答案,那麼就不需要進行後面層的遍歷。
這裡用到的乙個小技巧是用乙個set來儲存所有已經出現過的節點值,當遍歷到的節點值是前面已經訪問過的節點值,即具有相同的值,此時就不對其進行入隊操作,因為相同節點一定是出現在當前節點之前,可能是當前層的,也可能是前面層的,那麼該節點在前面都不符合要求,在這裡更不會符合要求,因為層更深,如果該節點符合要求,選擇的也不會是這個點而是前面的點。所以利用這個集合set可以減少大量的計算,這也是這種遍歷方法可行的最大原因,相比於暴力解法每種都嘗試。
class solution(object):
def numsquares(self, n):
""":type n: int
:rtype: int
"""dp = [i for i in range(n+1)]
for i in range(2,n+1):
for j in range(1,int(i**0.5)+1):
dp[i] = min(dp[i],dp[i-j*j]+1)
return dp[-1]
想到動態規劃解題是相對容易的,但是如何確定狀態轉移方程是比較難的。對於dp[i]而言表示的是對於數字i,其最少的完全平方數。那麼i其實可以分解為兩部分,i = x + j*j,其中j是完全平方數,那麼此時的總數就變成了dp[x]+1,dp[x]是組成x的最少完全平方數。那麼我們只需要遍歷所有j的可能,就能獲得dp[i]。
在初始化dp陣列的時候,可以先將其設為最多的完全平方數,那麼就是全部都由1組成。
Leetcode 279 完全平方數
給定正整數 n,找到若干個完全平方數 比如1,4,9,16,使得它們的和等於n。你需要讓組成和的完全平方數的個數最少。示例 1 輸入 n 12輸出 3解釋 12 4 4 4.示例 2 輸入 n 13輸出 2解釋 13 4 9.解題思路 比較容易想到的方法是bfs 廣度優先搜尋 如果知道四平方和的話就...
LeetCode 279 完全平方數
題目描述 提示幫助 提交記錄社群討論閱讀解答 隨機一題 給定正整數 n,找到若干個完全平方數 比如1,4,9,16,使得它們的和等於n。你需要讓組成和的完全平方數的個數最少。示例 1 輸入 n 12輸出 3解釋 12 4 4 4.示例 2 輸入 n 13輸出 2解釋 13 4 9.class sol...
Leetcode279 完全平方數
給定正整數 n,找到若干個完全平方數 比如 1,4,9,16,使得它們的和等於 n。你需要讓組成和的完全平方數的個數最少。示例 1 輸入 n 12 輸出 3 解釋 12 4 4 4.示例 2 輸入 n 13 輸出 2 解釋 13 4 9.解法1 bfs public intnumsquares in...