【LeetCode】279. Perfect Squares

版权声明:本文为博主原创文章,欢迎大家转载,但是要注明我的文章地址。 https://blog.csdn.net/program_developer/article/details/84145827

279. Perfect Squares

Description:

Given a positive integer n, find the least number of perfect square numbers (for example, 1, 4, 9, 16, ...) which sum to n.

Example 1:

Input: n = 12
Output: 3 
Explanation: 12 = 4 + 4 + 4.

Example 2:

Input: n = 13
Output: 2
Explanation: 13 = 4 + 9.

 题目分析:

这是一道动态规划题目,要解决动态规划题目需要掌握三个信息:

  • 最优子结构(最难的是发现最优子结构)
  • 边界条件
  • 根据最优子结构写出状态转移方程

重叠子问题:

我们用数组dp[i]表示第i个数字的完美平方数。我们来寻找重叠子问题:

 我们要找到13的完美平方数,就把13拆成两个数的和,在分别找到这两个数的完美平方数,这就是这道题的重叠子问题。但是有一点我们不能忽略,如果这个13刚好是一个数的平方,那么它的完美平方数就是1。

最优子结构分析:

13的完美平方数 = Min( dp[i]+dp[13-i] , dp[13]) ; i = 1到 13/2。

状态转移方程:

根据上面分析出来的最优子结构,我们可以写出来这道题的状态转移方程:

dp[i] = Math.min(dp[j] + dp[i - j],dp[i])

 i 的完全平方数是从和为 i 的两个完全平方数 dp[j] 和 dp[i-j]之和 与 dp[i ]中取最小。

【类似题目】

【LeetCode】343. Integer Break

已经AC的代码:

import java.util.Arrays;

public class Numsquares_279 {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		for(int i=1; i<=20; i++)
			System.out.println(numSquares(i));
	}
	
    public static int numSquares(int n) {
    	int[] dp = new int[n+1];
    	Arrays.fill(dp, Integer.MAX_VALUE);
    	dp[1] = 1;
    	for(int i=1; i<=n; i++) {
    		int sqr = (int)Math.sqrt(i);
    		//如果i本身是个平方数,就将dynamicProgramming[i]置为1
    		if(sqr * sqr == i)
    			dp[i] = 1;
    		else {
    			//从1开始遍历所有和为i的最优解dp[i],使得dp[i]取值最小
    			for(int j=1; j<=i/2; j++)
    				dp[i] = Math.min(dp[j]+dp[i-j], dp[i]);
    		}
    	}
    	return dp[n]; 	
    }

}

Reference:

【1】leetcode 279. Perfect Squares-完美平方数|动态规划

猜你喜欢

转载自blog.csdn.net/program_developer/article/details/84145827