[Leetcode] 279. Perfect Squares

这题一开始的想法是backtrack,但是任何只求数目不求具体路径的题目都是dp题(误)。所以,这题是dp题!

嗯,这一题的dp递归式其实是这样的
f(i) = min(f(i - j)) + 1  (j = 1 * 1, 2 * 2, 3 * 3.... j * j 的范围要小于i)
base case很简单,就是f(0) = 0。

原理就是,我们从下往上堆叠解。每一个解都是由一个子解和一个square number组成。这个子解就是当前数字减去那个square number所对应的子解。再求出这个过程里最小的那个数字,就是当前解。这个过程可以保证你的解或者子解都必然是square number构成的,而且是最小的。这其实也就是backtrack引申出来的dp解。根据上述算法,得到代码如下:

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

猜你喜欢

转载自blog.csdn.net/chaochen1407/article/details/82263688