Perfect Squares

来源:互联网 发布:telnet连接linux 编辑:程序博客网 时间:2024/06/05 16:11

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

采用动态规划的思路做这道题。首先想到的是一个O(n3)的解法,在比较大的数的时候发生了超时。代码:

public int numSquares(int n) {        if(n == 0) return 0;        int [] dp = new int[n+1];        for(int i=1;i<=n;i++){            dp[i] = Integer.MAX_VALUE;        }        for(int i=1;i<=n;i++){            for(int j=0;j<i;j++){                int k = 1;                while(( j+ k * k )<= i){                    if((j + k* k) == i){                        dp[i] = Math.min(dp[i], 1+dp[j]);                        //System.out.println("dp["+i+"] = "+dp[i]);                    }                    k++;                }            }        }        return dp[dp.length-1];    }

外层的循环表示当前在统计第i个数。它所对应能到达它的全部可能情况,并保存其最小值,内层j表示从比i考前的元素开始找,再内层表示的是j+k*k如果等于当前元素i的时候,更新i的值。


参考了网上的o(n2)的解法,更为巧妙一些。代码:

public int numSquares(int n) {        if(n == 0) return 0;        int [] dp = new int [n+1];        Arrays.fill(dp, Integer.MAX_VALUE);        for(int i=0;i*i<=n;i++){            dp[i*i] = 1;//表示可以直接由一个数的平方得到        }        for(int i=1;i<=n;i++){            for(int j=1;(i+j*j)<=n;j++){                    //那么可以更新 i + j * j的值                    dp[i+j*j] = Math.min(dp[i+j*j], dp[i]+1);            }        }        return dp[dp.length-1];    }

内层循环的终止条件是 i + j*j > n, 这样会一直更新 i + j* j的值,这种思路更巧妙。

0 0
原创粉丝点击