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



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值