马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?立即注册
x
给你一个整数 n ,返回 和为 n 的完全平方数的最少数量 。
完全平方数 是一个整数,其值等于另一个整数的平方;换句话说,其值等于一个整数自乘的积。例如,1、4、9 和 16 都是完全平方数,而 3 和 11 不是。
:痕迹
- class Solution {
- public int numSquares(int n) {
- // 从nums(完全平方数构成的数组)选和为n的组合
- // 1、4、9、16、25、36、49、64...
- int sqrt = (int)Math.sqrt(n);
- int[] nums = new int[sqrt];
- for(int i = 0; i < nums.length; i++){
- nums[i] = (i + 1) * (i + 1);
- }
- // 容量n
- // dp代表数量,
- // dp[j]的值是如何保证,当容量为j的时候,找到【数量最少】的【和为j】的
- int[] dp = new int[n + 1];
- int max = Integer.MAX_VALUE;
- for(int i = 1; i <= n; i++) dp[i] = max;
- /*
- for(int i = 1; i <= n; i++){
- for(int j = 0; j < nums.length; j++){
- // 每次就决定加 / 不加 这个数。而这个数不是连续递增的,1.4.9.16.25.
- // 那就说明,必定有一些数,不能由nums中的数相加的来(不是的,nums中还有1,所以必定能表示所有数字)
-
- // 加不了当前的数
- if(i < nums[j]) dp[i] = dp[i - 1];
- // 加上当前这个nums[j],则数量dp +1
- else dp[i] = Math.min(dp[i], dp[i - nums[j]] + 1);
- }
- }
- */
- // dp[0] = 1;
- for(int i = 0; i < nums.length; i++){
- for(int j = nums[i]; j <= n; j++){
- if(j == nums[i]) dp[j] = 1;
- else dp[j] = Math.min(dp[j], dp[j - nums[i]] + 1);
- }
- }
- return dp[n];
- }
- }
复制代码 感想:dp不知道先遍历容量还是数组的话,就都实行一下。
| i=0 | i=1 | i=2 | 0 | 0 | 0 | 0 | 1 | 1 | | | 2 | 2 | | | 3 | 3 | | | 4 | 4 | 1 | | 5 | 5 | 2 | | 6 | 6 | 3 | | 7 | 7 | 4 | | 8 | 8 | 2 | | 9 | 9 | 3 | 1 | 10 | 10 | 4 | 2 | 11 | 11 | 5 | 3 | 12 | 12 | 3 | 4 | 每个容量(上图中的行数据)取背面的最小值。对应代码:dp[j] = Math.min(dp[j], dp[j - nums] + 1);
:默写加深印象
- public int numSquares(int n){
- // 需要自己构造数组
- int sqrt = (int)Math.sqrt(n);
- int[] nums = new int[sqrt];
- for(int i = 0; i < sqrt; i++) nums[i] = (i + 1) * (i + 1);
- //
- int[] dp = new int[n + 1];
- int max = Integer.MAX_VALUE;
- for(int i = 1; i <= n; i++) dp[i] = max;
- for(int i = 0; i < nums.length; i++){
- for(int j = nums[i]; j <= n; j++){
- if(j == nums[i]) dp[j] = 1;
- else dp[j] = Math.min(dp[j], dp[j - nums[i]] + 1);
- }
- }
- return dp[n];
- }
复制代码 :改进
- public int numSquares(int n){
- // 需要自己构造数组
- int sqrt = (int)Math.sqrt(n);
- int[] nums = new int[sqrt];
- for(int i = 0; i < sqrt; i++) nums[i] = (i + 1) * (i + 1);
- //
- int[] dp = new int[n + 1];
- int max = Integer.MAX_VALUE;
- // 这里要么从1开始遍历,要么从0开始,但还要把dp[0] = 0初始化。
- for(int i = 1; i <= n; i++) dp[i] = max;
- for(int i = 0; i < nums.length; i++){
- for(int j = nums[i]; j <= n; j++){
- dp[j] = Math.min(dp[j], dp[j - nums[i]] + 1);
- }
- }
- return dp[n];
- }
复制代码
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |