欢迎访问我的GitHub

这里分类和汇总了欣宸的全部原创(含配套源码):https://github.com/zq2599/blog_demos

本篇概览

本篇概览

  • 这是道高频面试题,值得一看
  • 首先,这道题的难度是中等
  • 来看题目描述:
给你一个整数 n ,返回 和为 n 的完全平方数的最少数量 。

完全平方数 是一个整数,其值等于另一个整数的平方;换句话说,其值等于一个整数自乘的积。例如,1、4、9 和 16 都是完全平方数,而 3 和 11 不是。
  • 示例1:
输入:n = 12
输出:3
解释:12 = 4 + 4 + 4
  • 示例 2:
输入:n = 13
输出:2
解释:13 = 4 + 9
  • 提示:
1 <= n <= 104

解题思路

  • 该题的解题思路是动态规划,核心解法有两点:
  1. 数字i,可能是某个数字的平方,例如数字9是数字3的平方
  2. 数字i,如果不是某个数字的平方,该数字能用此表达式表达:i = i - j*j + j*j
  • 对于上述第二种情况,就是动态规划状态转移方程的核心啦!
  • 假设dp[i]的定义是数字i的完全平方数的最少数量,那么表达式i = i - j*j + j*j就很容易用来分析dp[i]了

  • 简单地说,就是:dp[i] = dp[i-j*j] + 1
  • 当然了,上述只是最基本的推测,不代表已经解完了,还剩一个重点:j到底是几?
  • 以10为例,10=(10-3*3) + 3*3,但是这不是唯一,还有10=(10-2*2) + 2*2,所以到底j等于几?根据题意,应该是dp[10-3*3]和dp[10-2*2]中最小的那个
  • 至此,分析完毕,可以愉快的写代码了

编码

  • 完整源码如下所示,可见,对应前面分析的j的多种可能,要取最小值
class Solution {
public int numSquares(int n) {
// i = i-j*j + j*j - 注意这个j*j,就是完全平方数中的一个 // dp[i]定义:数字i的完全平方数
int[] dp = new int[n+1]; dp[0] = 1; for (int i=1;i<=n;i++) {
dp[i] = Integer.MAX_VALUE; for(int j=1;j*j<=i;j++) {
// 如果出现i等于某个数字的平方,那么i的完全平方数就是1
if (j*j==i) {
dp[i] = 1;
break;
} // +1的意思就是j*j表示完全平方数中的一个
dp[i] = Math.min(dp[i-j*j]+1, dp[i]);
}
} return dp[n];
}
}
  • 编码完成后提交,顺利AC,只是成绩很不理想,仅超过45%,如下图

反思,为啥成绩这么差?

  • 这么简单的动态规划操作,为何成绩这么落后?
  • 于是,我想到了一种可能:说不定可以作弊...
  • 理由有二
  1. 首先,这道题的输入是个数字,输出也是个数字,那就存在提前算好的可能,然后按输入返回提前算好的记过
  2. 其次,也是最关键的,就是题目要求中的那句提示,如下图,n小于等于一万,所以,我只要存一万个数字的对应关系,就行了呗:

  • 看到这里,聪明的您应该知道我要如何作弊了,没错,就是把每个数字的完全平方数算出来,改动如下图

  • 然后,运行上述代码,入参是10000,即可在控制台得到一个字符串,那就是从0到10000,每个数字的完全平方数
  • 接下来的要做的就很简单了,如下所示,用上述字符串做成一个int数组array,然后numSquares方法中就一行代码,返回入参n对应的完全平方数就行了
class Solution {
// 数组的值就是刚才打印出来的字符串,太长了,就不完全贴出来了
private int[] array = new int [] {1,1,2,3,1,2,3,4,2,1...};
public int numSquares(int n) {
return array[n];
}
}
  • 至此,就一行代码了,相信成绩不会差了吧,运行一下试试,如下图,大跌眼镜了,一行代码也要45ms,从之前的超过45%跌落到超过22%

  • 突如其来的丢脸...

  • 好吧,让我对着这一行代码捋捋,代码太少了,很容易捋清楚,如下图

  • 找到了问题,改起来也就很容易了,如下图黄框所示,这一下,array数组在编译成class文件的时候被丢进了常量区,每次创建Solution实例的时候,不会再去创建array对象了

  • 再次提交,这一回,作弊成功,用时和内存消耗双双超过百分之九十七

  • 总的来说,动态规划是正解,如果条件允许,也能用歪门邪道作弊试试,可以开阔思路,同时取得好成绩,令人身心愉悦

欢迎关注博客园:程序员欣宸

学习路上,你不孤单,欣宸原创一路相伴...

LeetCode279:完全平方数,动态规划解法超过46%,作弊解法却超过97%的更多相关文章

  1. LeetCode 62,从动态规划想到更好的解法

    本文始发于个人公众号:TechFlow,原创不易,求个关注 今天是LeetCode专题第36篇文章,我们一起来看下LeetCode的62题,Unique Paths. 题意 其实这是一道老掉牙的题目了 ...

  2. leetcode-91-解码方法(动态规划和递归两种解法)

    题目描述: 一条包含字母 A-Z 的消息通过以下方式进行了编码: 'A' -> 1 'B' -> 2 ... 'Z' -> 26 给定一个只包含数字的非空字符串,请计算解码方法的总数 ...

  3. 好!recover-binary-search-tree(难)& 两种好的空间O(n)解法 & 空间O(1)解法

    https://leetcode.com/mockinterview/session/result/xyc51it/https://leetcode.com/problems/recover-bina ...

  4. 图解leetcode279 —— 完全平方数

    每道题附带动态示意图,提供java.python两种语言答案,力求提供leetcode最优解. 描述: 给定正整数 n,找到若干个完全平方数(比如 1, 4, 9, 16, ...)使得它们的和等于  ...

  5. 98. 验证二叉搜索树 前序遍历解法以及后续遍历解法(go语言)

    leetcode题目 98. 验证二叉搜索树 前序遍历 最简洁的答案版本,由于先判断的是根节点,所以直接判断当前root的值v,是否满足大于左子树最大,小于右子树最小,然后再遍历左子树,右子树是否是这 ...

  6. [Swift]LeetCode279. 完全平方数 | Perfect Squares

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

  7. leetcode279. 完全平方数

    给定正整数 n,找到若干个完全平方数(比如 1, 4, 9, 16, ...)使得它们的和等于 n.你需要让组成和的完全平方数的个数最少. 示例 1: 输入: n = 12输出: 3 解释: 12 = ...

  8. Letter Combinations of a Phone Number:深度优先和广度优先两种解法

    Letter Combinations of a Phone Number Given a digit string, return all possible letter combinations ...

  9. LeetCode算法题-Number Complement(Java实现-五种解法)

    这是悦乐书的第240次更新,第253篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第107题(顺位题号是476).给定正整数,输出其补码数.补充策略是翻转其二进制表示的位 ...

  10. LeetCode算法题-Intersection of Two Arrays(Java实现-四种解法)

    这是悦乐书的第207次更新,第219篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第75题(顺位题号是349).给定两个数组,编写一个函数来计算它们的交集.例如: 输入: ...

随机推荐

  1. < Python全景系列-9 > Python 装饰器:优雅地增强你的函数和类

    欢迎来到我们的系列博客<Python全景系列>第九篇!在这个系列中,我们将带领你从Python的基础知识开始,一步步深入到高级话题,帮助你掌握这门强大而灵活的编程语法.无论你是编程新手,还 ...

  2. Java关键字break、continue 、return的区别,嵌套循环,数组的概念以及数组案例

    一.关键字 break.continue .return的区别 1.break : 用于在switch..case中放置语句块穿透, ​ 用于跳出循环 // 从1-100 遇到7的倍数 break f ...

  3. OCR -- 文本识别 -- 理论篇

    文本识别的应用场景很多,有文档识别.路标识别.车牌识别.工业编号识别等等,根据实际场景可以把文本识别任务分为两个大类:规则文本识别和不规则文本识别. 规则文本识别:主要指印刷字体.扫描文本等,认为文本 ...

  4. 开源 API 网关的访问策略(一)

    许多企业和组织面临着网关访问控制的挑战,因为传统的访问控制方法往往过于笨重和繁琐.这些方法可能涉及复杂的规则集.繁琐的手动配置过程.缺乏灵活性和可扩展性等问题.此外,随着云计算和移动设备的广泛应用,访 ...

  5. 2023-06-09:什么是Redis事务?原理是什么?

    2023-06-09:什么是Redis事务?原理是什么? 答案2023-06-09: Redis中的事务是以一组命令的形式出现的,这些命令被认为是最小的执行单位.事务可以保证在一个单独独立的隔离操作中 ...

  6. STM32低功耗配置

    一.相关介绍 1.1 STM32下的电源管理 电源框图 电源标号说明 电压调节器 复位后调节器总是使能.以3种不同的模式工作. 运转模式:调节器以正常功耗模式提供1.8V电源(内核,内存和外设). 停 ...

  7. [ARM 汇编]高级部分—ARM汇编编程实战—3.3.1 嵌入式系统的基本概念

    嵌入式系统是一种特殊的计算机系统,通常用于执行特定的任务.它通常包含一个或多个微处理器.存储器和外围设备.与通用计算机系统相比,嵌入式系统具有体积小.功耗低.成本低和实时性强等特点.在这一部分,我们将 ...

  8. httpx的两个坑(httpx.ReadTimeout; SSL: CERTIFICATE_VERIFY_FAILED)

    关于python异步网络请求库httpx的两个坑 其一:httpx.ReadTimeout 实测发现,网络不稳定的情况下,极其容易出现该错误. 相对于requests库, httpx库是有默认的超时时 ...

  9. 采集douban

    # -*- coding: utf-8 -*-"""Created on Thu Oct 31 16:14:02 2019 @author: DELL"&quo ...

  10. PE结构总览

    pe文件经历了从16位系统到32位系统的过度.因此32系统下的每一个PE文件都可以在16位系统下运行. 16位系统下的PE结构 在16位系统下,PE结构可以大致分为两个部分:DOS头和一些其他数据 # ...