leecode更新
This commit is contained in:
parent
a01757b6e0
commit
3f9a8642e8
|
|
@ -0,0 +1,95 @@
|
||||||
|
package com.markilue.leecode.dynamic;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @BelongsProject: Leecode
|
||||||
|
* @BelongsPackage: com.markilue.leecode.dynamic
|
||||||
|
* @Author: markilue
|
||||||
|
* @CreateTime: 2022-12-07 10:49
|
||||||
|
* @Description:
|
||||||
|
* TODO 力扣279题 完全平方数:
|
||||||
|
* 给你一个整数 n ,返回 和为 n 的完全平方数的最少数量 。
|
||||||
|
* 完全平方数 是一个整数,其值等于另一个整数的平方;换句话说,其值等于一个整数自乘的积。例如,1、4、9 和 16 都是完全平方数,而 3 和 11 不是。
|
||||||
|
* @Version: 1.0
|
||||||
|
*/
|
||||||
|
public class T16_NumSquares {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test(){
|
||||||
|
System.out.println(numSquares(12));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 思路:这题与上一题零钱兑换是一个思路,区别在于这里没有给出coins数组
|
||||||
|
* TODO 动态规划五部曲:
|
||||||
|
* (1)dp定义:dp[i][j]定义为使用[0-(i+1)^2]能凑出j所需要的最少数量
|
||||||
|
* (2)dp状态转移方程:dp[j]=min(dp[j],dp[j-(i+1)^2+1]) 即使用(i+1)^2和不使用两种取最少
|
||||||
|
* (3)dp初始化:dp[0]=0 最开始不需要硬币也能凑出dp
|
||||||
|
* (4)dp遍历顺序:与零钱兑换一样,两个for的顺序应该是不一样
|
||||||
|
* (5)dp举例推导:
|
||||||
|
* 速度击败67.62%,内存击败41.23% 25ms
|
||||||
|
* @param n
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public int numSquares(int n) {
|
||||||
|
int max=n+1; //因为最少可以用1凑n,最多只需要n个数字
|
||||||
|
int[] dp = new int[n+1];
|
||||||
|
dp[0]=0;
|
||||||
|
for (int i = 1; i < max; i++) {
|
||||||
|
dp[i]=max;
|
||||||
|
}
|
||||||
|
int maxSqrt = (int)Math.sqrt(n);
|
||||||
|
|
||||||
|
for (int i = 1; i <= maxSqrt; i++) {
|
||||||
|
for (int j = i*i; j < n + 1; j++) {
|
||||||
|
if(dp[j-i*i]!=max){
|
||||||
|
dp[j]=Math.min(dp[j],dp[j-i*i]+1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return dp[n];
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 官方提供的数学法:核心是利用数学规律得出当且有四种解法
|
||||||
|
* 时间复杂度O(sqrt(n))
|
||||||
|
* 速度击败100%,内存击败98.25%
|
||||||
|
* @param n
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public int numSquares1(int n) {
|
||||||
|
if (isPerfectSquare(n)) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if (checkAnswer4(n)) {
|
||||||
|
return 4;
|
||||||
|
}
|
||||||
|
for (int i = 1; i * i <= n; i++) {
|
||||||
|
int j = n - i * i;
|
||||||
|
if (isPerfectSquare(j)) {
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 判断是否为完全平方数
|
||||||
|
public boolean isPerfectSquare(int x) {
|
||||||
|
int y = (int) Math.sqrt(x);
|
||||||
|
return y * y == x;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 判断是否能表示为 4^k*(8m+7)
|
||||||
|
public boolean checkAnswer4(int x) {
|
||||||
|
while (x % 4 == 0) {
|
||||||
|
x /= 4;
|
||||||
|
}
|
||||||
|
return x % 8 == 7;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue