1. 程式人生 > >leetcode谷歌面試題279. Perfect Squares

leetcode谷歌面試題279. Perfect Squares

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;
    					  }
    				  } 

    具體程式碼:
    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));
    	  }
    }
    藉助的pair類
    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;
    }
    
    }