[LeetCode] 279. Perfect Squares
Posted CNoodle
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[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.
Example 1:
Input: n =12
Output: 3 Explanation:12 = 4 + 4 + 4.
Example 2:
Input: n =13
Output: 2 Explanation:13 = 4 + 9.
完全平方数。题意是给一个数字N,请你返回最少的需要几个完全平方数的加和的个数。比如第一个例子,12是由三个4组成,4也是完全平方数。
思路是动态规划。首先说一下暴力解,这个题的暴力解是从1到N一个个看是否是完全平方数,如果N是某个数的平方,那么结果自然等于2;如果N不是某个数的平方,那么可以试着从1开始,用N减去每个数的平方,看看需要几个完全平方数才能得到N。举个例子,比如找15好了,第一个完全平方数是1,需要15个1;第二个完全平方数是4,需要3个4 + 3个1。
其实动态规划的思路是从暴力解延伸出来的,只是我们用了一个额外的数组记录了之前的结果。首先创建一个长度为N + 1的数组记录DP的结果,并且DP[0] = 1。从i= 1开始,一直遍历到N。当遇到一个新的数字N的时候,需要再次从1开始遍历,看看当前的这个数字i是否整体或者部分能被某一个更小的数的平方代替。比如遍历到7的时候,我们发现7是可以被一个2的平方和三个1的平方代替的,所以DP的转移方程是
dp[i] = Math.min(dp[i], dp[i - j * j] + 1);
这里j的范围是[1, i)
最后返回的是dp[n]
时间O(n * sqrt(n))
空间O(n)
Java实现
1 class Solution { 2 public int numSquares(int n) { 3 int[] res = new int[n + 1]; 4 Arrays.fill(res, Integer.MAX_VALUE); 5 res[0] = 0; 6 for (int i = 0; i <= n; i++) { 7 for (int j = 1; j * j <= i; j++) { 8 res[i] = Math.min(res[i], res[i - j * j] + 1); 9 } 10 } 11 return res[n]; 12 } 13 }
1 /** 2 * @param {number} n 3 * @return {number} 4 */ 5 var numSquares = function (n) { 6 let dp = new Array(n + 1).fill(0); 7 for (let i = 0; i <= n; i++) { 8 dp[i] = i; 9 for (let j = 1; j * j <= i; j++) { 10 dp[i] = Math.min(dp[i], dp[i - j * j] + 1); 11 } 12 } 13 return dp[n]; 14 };
以上是关于[LeetCode] 279. Perfect Squares的主要内容,如果未能解决你的问题,请参考以下文章
[LeetCode] 279. Perfect Squares