leetcode谷歌面試題279. Perfect Squares
阿新 • • 發佈:2019-01-05
Given a positive integer n, find the least number of perfect square numbers (for example, 1,
4, 9, 16, ...
) which sum to n.
For example, given n = 12
, return 3
because 12
= 4 + 4 + 4
; given n = 13
, return 2
because 13
= 4 + 9
.
Credits:
Special thanks to @jianchao.li.fighter for adding this problem and creating
all test cases.
Subscribe to see which companies asked this question.
- 這道題的大致意思就是給定一個數,使這個數用完全平方數表示,並且完全平方數最少需要幾個。其中完全平方數是開平方是整數的數(sqrt(n)=k,k=1,2,3...)
- 瞭解完題意思考解決思路:
- 本題可以轉化為最短路徑問題,從0到n為n+1個節點,如果從 i (屬於0到n)到 j(屬於0到n)相差一個完全平方數就可以將兩個節點連線起來,這樣所有的點就轉化成了無向圖,就把問題轉化成了求n到0的最短路徑
- 無權最短路徑問題可以使用bfs
- 下面是一些節點的生成圖
- 例如從不同節點到不同節點所需要的步數:
- 1. 從9到0,相差一個完全平方數9,即9 = 9 + 0,需要1步就可以到0了;
- 2. 從6到0,相差完全平方數4和完全平方數1,即6 = 4 + 1 + 1 + 0 需要三步就到0了;
- 3.同理 8 = 4 + 4 + 0需要兩步到0;
- 實現:
- 藉助佇列的BFS,記錄每走一步後numpairs(剩餘數字的大小,所走的步數);//記錄每一個點到達其他節點步數然後對剩餘數字的大小進行判斷,看能否再變成完全平方數,也就是不斷將剩餘數字不斷減小直到減為0,獲取步數
-
for(int i = 1;i*i<=num;i++)//將num不斷用完全平方數代表,直至其成為0,其中1是完全平方數所以總會有解 { int temp = num - i*i; if(visit[temp] == 0) { //將其中沒有訪問過的點標記,以及將改點所到達的路徑錄入 queue.add(new numpairs(temp,step+1)); visit[temp] = 1; } }
具體程式碼:
藉助的pair類public class PerfectSquares { //使用廣度搜索藉助佇列解決 public static int numSquares(int n) { if(n == 0) return 0; Queue<numpairs> queue = new LinkedList();//每次將剩餘數字與已走步數入隊 int[] visit = new int[n+1];//新增標記陣列 numpairs pair = new numpairs(n,0);//記錄每一個點到達其他節點步數 queue.add(pair); visit[n] = 1; while(!queue.isEmpty()) { pair = queue.poll(); int num = pair.getFirst();//獲取剩餘的數字與步數 int step = pair.getSecond(); for(int i = 1;i*i<=num;i++) { int temp = num - i*i; if(temp == 0) return step+1; if(visit[temp] == 0) { //將其中沒有訪問過的點標記,以及將改點所到達的路徑錄入 queue.add(new numpairs(temp,step+1)); visit[temp] = 1; // System.out.print(i*i+" "); } } } return 0; } public static void main(String[] args) { System.out.println(numSquares(2)); } }
public class numpairs { int first; int second; public numpairs(int a,int b) { setFirst(a); setSecond(b); } public int getFirst() { return first; } public void setFirst(int first) { this.first = first; } public int getSecond() { return second; } public void setSecond(int second) { this.second = second; } }