目录

​一,题目描述​

​英文描述​

​中文描述​

​示例与说明​

​二,解题思路​

​三,AC代码​

​Java​

​四,解题过程​

​第一搏​

​第二搏​


 

一,题目描述

英文描述

Given an integer n, return the least number of perfect square numbers that sum to n.

A perfect square is an integer that is the square of an integer; in other words, it is the product of some integer with itself. For example, 1, 4, 9, and 16 are perfect squares while 3 and 11 are not.

中文描述

给你一个整数 n ,返回 和为 n 的完全平方数的最少数量 。

完全平方数 是一个整数,其值等于另一个整数的平方;换句话说,其值等于一个整数自乘的积。例如,1、4、9 和 16 都是完全平方数,而 3 和 11 不是。

示例与说明

LeetCode_Array_279. Perfect Squares 完全平方数【动态规划】【Java】【中等】_中等

LeetCode_Array_279. Perfect Squares 完全平方数【动态规划】【Java】【中等】_leetcode_02

  

来源:力扣(LeetCode)
链接:​​​https://leetcode-cn.com/problems/perfect-squares​​ 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

二,解题思路

参考​​@画手大鹏【画解算法:279. 完全平方数】​

动态规划。核心思想很简单,举个例子就明白了

以计算dp[12]为例:

依次计算:dp[12-1*1]+1、dp[12-2*2]+1、dp[12-3*3]+1,取其中最小值即可

三,AC代码

Java

class Solution {
public int numSquares(int n) {
int ans = 0;
int[] dp = new int[n + 1];
for (int i = 1; i <= n; i++) {
dp[i] = i;
// 计算dp[12]时,依次计算dp[12-1]+1、dp[12-4]+1、dp[12-9]+1
for (int j = 1; i - j * j >= 0; j++) {
dp[i] = Math.min(dp[i], dp[i - j * j] + 1);
}
}
return dp[n];
}
}

四,解题过程

第一搏

最开始想的贪心。比如求12时,找到小于12的第一个完全平方数9,接下来找12-9后第一个完全平方数...然而发现9+1+1+1需要四次,而4+4+4只需要三次,因此算法本身是有问题的。于是转向动态规划。

简单粗暴的动态规划思路。dp[12]需要计算dp[10]+dp[2]、dp[9]+dp[3]、dp[8]+dp[4]...、dp[6]+dp[6],从中取最小值进行更新。时间复杂度O(n^2)

class Solution {
public int numSquares(int n) {
int ans = 0;
int[] dp = new int[n + 1];
// 给所有完全平方数赋值为1
for (int i = 1; i <= (int)Math.sqrt(n); i++) {
dp[i * i] = 1;
}

for (int i = 2; i <= n; i++) {
// dp数组中为0,表示尚未赋值,为方便后面迭代求最小值,这里先直接赋值为dp[i - 1] + 1;
if (dp[i] == 0) {
dp[i] = dp[i - 1] + 1;
}
// 向左迭代,遍历每一个可能的结果并取最小值。如dp[12]需要判断dp[10]+dp[2]、dp[9]+dp[3]、...、dp[6]+dp[6],从中取最小值
for (int j = i - 1; j >= i / 2; j--) {
dp[i] = Math.min(dp[i], dp[j] + dp[i - j]);
}
}
return dp[n];
}
}

LeetCode_Array_279. Perfect Squares 完全平方数【动态规划】【Java】【中等】_动态规划_03

第二搏

动态规划的思路需要转变一下,以计算dp[12]为例:

  • 原先需要计算:dp[10]+dp[2]、dp[9]+dp[3]、dp[8]+dp[4]、dp[7]+dp[5]、dp[6]+dp[6]
  • 现在需要计算:dp[12-1]+1、dp[12-4]+1、dp[12-9]+1

思路很巧妙,但还是很容易看明白的

LeetCode_Array_279. Perfect Squares 完全平方数【动态规划】【Java】【中等】_leetcode_04