leetcode 279-Perfect Squares(medium)
阿新 • • 發佈:2018-09-29
是否 ins amp fir tco -i ... n) true
Given a positive integer n, find the least number of perfect square numbers (for example, 1, 4, 9, 16, ...
) which sum to n.
1. DP
Set an array, first initiate index=i^2 with 1.
Then calculate others with dp[j]=Math.min(dp[j],dp[j-i*i]+dp[i*i]) //註意,這裏在自己第一次寫的時候,最後一項寫成了dp[i],要仔細!前面更新的是dp[i*i]為1,而不是dp[i]為1。
class Solution { public int numSquares(int n) { if(n<=0) return 0; int[] dp=new int[n+1]; Arrays.fill(dp,Integer.MAX_VALUE); dp[0]=0; int sr=(int)Math.sqrt(n); for(int i=1;i<=sr;i++){ dp[i*i]=1; } for(int i=1;i<=sr;i++){for(int j=i*i+1;j<=n;j++){ dp[j]=Math.min(dp[j-i*i]+dp[i*i],dp[j]); } } return dp[n]; } }
2. BFS
按照bfs的思想,每輪依次入隊需要1,2,3,……步到達的點,如果遇到n則直接返回這一輪對應的步數。
自己寫的第一版。註意queue的size是會變的,一開始寫的時候還出了低級錯誤,沒有把queue的size先取出來然後在一輪循環中固定不變,而是直接寫了queue.size(),忽視了這個量每個循環下來都會變的。以下這種方法會MLE,主要是在入隊的時候沒有判斷這個數是否已經入隊過,如果已經入隊過就不需要再入隊了,我們只關心一個數最小的組成成分個數,即到達該數最小的步數。(其實寫的時候已經註意到了入隊的元素會有重復,但都竟然沒想到用一個set去避免,對數據結構的運用還是太不熟悉啊)
class Solution { public int numSquares(int n) { //bfs if(n==0) return 0; int sr=(int)Math.sqrt(n); Queue<Integer> queue=new LinkedList<>(); queue.offer(0); int count=0; while(true){ count++; int s=queue.size(); for(int j=0;j<s;j++){ int num=queue.poll(); for(int i=1;i<=sr;i++){ if(num+i*i==n) return count; if(num+i*i>n) continue; queue.offer(num+i*i); } } } } }
改進後:(加入set visited來記錄是否入隊過)(s-->0這種寫法比較簡潔)
class Solution { public int numSquares(int n) { //bfs if(n==0) return 0; int sr=(int)Math.sqrt(n); Queue<Integer> queue=new LinkedList<>(); queue.offer(0); Set<Integer> visited=new HashSet<>(); int count=0; while(true){ count++; int s=queue.size(); while(s-->0){ int num=queue.poll(); for(int i=1;i<=sr;i++){ if(num+i*i==n) return count; if(num+i*i>n) break;//第一次寫的時候寫成了continue,當大於n的時候,後面的就不需要再考慮了,所以應該直接break if(!visited.contains(num+i*i)){ queue.offer(num+i*i); visited.add(num+i*i); } } } } } }
leetcode 279-Perfect Squares(medium)