*Perfect Squares & DP 自底向上 & 自顶向下

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.

 

解法一:自底向上

dp[n] indicates that the perfect squares count of the given n, and we have:

 

dp[0] = 0 
dp[1] = dp[0]+1 = 1
dp[2] = dp[1]+1 = 2
dp[3] = dp[2]+1 = 3
dp[4] = Min{ dp[4-1*1]+1, dp[4-2*2]+1 } 
      = Min{ dp[3]+1, dp[0]+1 } 
      = 1                
dp[5] = Min{ dp[5-1*1]+1, dp[5-2*2]+1 } 
      = Min{ dp[4]+1, dp[1]+1 } 
      = 2
                        .
                        .
                        .
dp[13] = Min{ dp[13-1*1]+1, dp[13-2*2]+1, dp[13-3*3]+1 } 
       = Min{ dp[12]+1, dp[9]+1, dp[4]+1 } 
       = 2
                        .
                        .
                        .
dp[n] = Min{ dp[n - i*i] + 1 },  n - i*i >=0 && i >= 1

 

 

public int numSquares(int n) {
    int[] dp = new int[n + 1];
    Arrays.fill(dp, Integer.MAX_VALUE);
    dp[0] = 0;
    for(int i = 1; i <= n; ++i) {
        int min = Integer.MAX_VALUE;
        int j = 1;
        while(i - j*j >= 0) {
            min = Math.min(min, dp[i - j*j] + 1);
            ++j;
        }
        dp[i] = min;
    }        
    return dp[n];
}

reference:

https://discuss.leetcode.com/topic/26400/an-easy-understanding-dp-solution-in-java/2

 

解法二:自顶向下

public class Solution {
    public int[] dp;
    public int numSquares(int n) {
        dp = new int[n+1];
        Arrays.fill(dp, -1);
        dp[0] = 0;
        return squaresHelper(n);   
    }
    
    public int squaresHelper(int m){
        int j = 1;
        int min = Integer.MAX_VALUE; 
        while(j*j<=m)
        {
            if(j*j==m) return 1;
            if(dp[m-j*j]==-1)
            {
                dp[m-j*j] = squaresHelper(m-j*j);
            }
            min = Math.min(min,dp[m-j*j]+1);
            j++;
        }
        dp[m]=min;
        return dp[m];
    }
    
}

 

解法三:faster 的DP

https://discuss.leetcode.com/topic/24255/summary-of-4-different-solutions-bfs-dp-static-dp-and-mathematics/25

public class Solution {
    static List<Integer> result = new ArrayList<>();
    public int numSquares(int n) {
        if (result.size() == 0) {
            result.add(0);
        }
        while (result.size() <= n) {
            int m = result.size();
            int tempMin = Integer.MAX_VALUE;
            for (int j = 1; j * j <= m; j++) {
                tempMin = Math.min(tempMin, result.get(m - j * j) + 1);
            }
            result.add(tempMin);
        }
        return result.get(n);
    }
}

 static生成了class variable,leetcode执行多次test case,只生成了一次result 这个object。

posted @ 2016-08-09 06:58  Hygeia  阅读(430)  评论(0编辑  收藏  举报