leetcode 279 完全平方數

2021-10-08 18:38:52 字數 1665 閱讀 7643

給定正整數 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...