LeetCode Hot100(67/100)——279. 完全平方数

Leetcode 279:完全平方数(最详细解决方案!!!) 给定正整数 n,找到若干个完全平方数(比如 1, 4, 9, 16, ...)使得它们的和等于 n。你需要让组成和的完全平方数的个数最少。 示例 1: 输入: n = 12 输出: 3 解释: 12 = 4 + 4 + 4. 示例 2: 输入: n = 13 输出: 2 解释: 13 = 4 + 9. 解题思路 很多人第一眼看到这个问题,想到的第一种做法就是使用贪心算法,但是... 阅读详情

题目链接

题目说明

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

  • 完全平方数:形如 1, 4, 9, 16, ...(即某个整数的平方)
  • 示例:
    • n = 12,答案是 3(12 = 4 + 4 + 4)
    • n = 13,答案是 2(13 = 4 + 9)

约束(LeetCode):

  • 1 <= n <= 10^4

解题思路总览

Perfect Squares

动态规划

状态dp[i]

转移dp[i]=min(dp[i-j*j]+1)

复杂度O(n*sqrt(n))

BFS最短路

节点是剩余值

边是减去一个平方数

层数即使用个数

数学定理

拉格朗日四平方定理

勒让德三平方定理


解法一:动态规划(推荐,通用且好理解)

原理

定义 dp[i]:表示组成整数 i 所需的最少完全平方数个数。
那么:

d p [ i ] = min ⁡ j 2 ≤ i ( d p [ i − j 2 ] + 1 ) dp[i] = \min_{j^2 \le i}(dp[i-j^2] + 1) dp[i]=j2≤imin​(dp[i−j2]+1)

含义是:最后一次选了一个平方数 j*j,前面剩下 i-j*j 的最优解再加 1。

状态转移流程图

是

否

是

否

初始化 dp[0]=0

计算 i=1..n

枚举 j, 满足 j*j <= i

dp[i] = min(dp[i], dp[i-j*j] + 1)

j继续?

i继续?

返回 dp[n]

Java 代码

import java.util.Arrays;

class Solution {
    public int numSquares(int n) {
        int[] dp = new int[n + 1];
        Arrays.fill(dp, Integer.MAX_VALUE);
        dp[0] = 0;

        for (int i = 1; i <= n; i++) {
            for (int j = 1; j * j <= i; j++) {
                dp[i] = Math.min(dp[i], dp[i - j * j] + 1);
            }
        }
        return dp[n];
    }
}

复杂度分析

  • 时间复杂度:O(n * sqrt(n))
  • 空间复杂度:O(n)

解法二:BFS(把问题看成最短路径)

原理

把每个数字看作图中的一个节点。
从 n 出发,每次可以减去一个平方数 s(s <= 当前值),到达新节点 cur - s。
每减一次平方数,相当于走一条边。问题就变成:

从 n 到 0 的最短路径长度是多少?

BFS 天然求无权图最短路,层数即答案。

BFS 时序示意

Level(step) Visited Queue Level(step) Visited Queue 初始:Q=[n], step=0 alt [生成0] [未生成0] 取当前层全部节点 对每个cur,尝试cur-j*j 新状态且未访问则入队 返回step+1 step++ 进入下一层

Java 代码

import java.util.*;

class Solution {
    public int numSquares(int n) {
        Queue<Integer> queue = new LinkedList<>();
        boolean[] visited = new boolean[n + 1];

        queue.offer(n);
        visited[n] = true;
        int step = 0;

        while (!queue.isEmpty()) {
            int size = queue.size();
            step++;
            for (int k = 0; k < size; k++) {
                int cur = queue.poll();
                for (int j = 1; j * j <= cur; j++) {
                    int next = cur - j * j;
                    if (next == 0) return step;
                    if (!visited[next]) {
                        visited[next] = true;
                        queue.offer(next);
                    }
                }
            }
        }
        return step;
    }
}

复杂度分析

  • 时间复杂度:最坏 O(n * sqrt(n))
  • 空间复杂度:O(n)

解法三:数学定理(性能很强)

原理

利用两个经典定理:

  1. 拉格朗日四平方定理:任意正整数都可表示为最多 4 个平方数之和
    → 答案只可能是 1,2,3,4

  2. 勒让德三平方定理推论:若 n = 4^a(8b+7),则 n 不能表示为 3 个平方数之和
    → 这种情况答案一定是 4

判定流程:

  1. 若 n 本身是完全平方数,答案 1
  2. 把 n 中因子 4 全部除掉(while n % 4 == 0)
  3. 若 n % 8 == 7,答案 4
  4. 枚举 a^2,判断 n-a^2 是否平方数,若是则答案 2
  5. 否则答案 3

判定流程图

是

否

是

否

是

否

是

否

输入 n

n 是否完全平方数?

返回 1

不断除以4: while n%4==0

n%8==7?

返回 4

枚举 a:1..sqrt(n)

n-a*a 是否完全平方数?

返回 2

继续枚举?

返回 3

Java 代码

class Solution {
    public int numSquares(int n) {
        if (isSquare(n)) return 1;

        // 去掉 4 的因子
        while (n % 4 == 0) {
            n /= 4;
        }

        // n = 8b + 7 的形式 => 4
        if (n % 8 == 7) return 4;

        // 检查是否可由两个平方数组成
        for (int a = 1; a * a <= n; a++) {
            int b = n - a * a;
            if (isSquare(b)) return 2;
        }

        // 不是1、2、4,则是3
        return 3;
    }

    private boolean isSquare(int x) {
        int r = (int) Math.sqrt(x);
        return r * r == x;
    }
}

复杂度分析

  • 时间复杂度:O(sqrt(n))
  • 空间复杂度:O(1)

不同解法的实现复杂度与性能对比

解法核心思想时间复杂度空间复杂度实现复杂度性能表现适用场景
动态规划dp[i] 最优子结构O(n*sqrt(n))O(n)中等稳定、通用面试高频,易讲清楚
BFS无权图最短路(层数)最坏 O(n*sqrt(n))O(n)中等偏上可能较快,依赖剪枝与数据分布想用图论视角时
数学定理四平方/三平方定理判定O(sqrt(n))O(1)较高(需要定理)通常最快追求极致性能、理解数学结论后使用

总结

如果你想要最稳妥的解法:用 动态规划。
如果你想要最优复杂度:用 数学定理法。
如果你想训练图论建模能力:可以写 BFS。

在 LeetCode 279 中,三种方法都很经典,建议至少掌握 DP + 数学法。

【hot100-动态规划-279.完全平方数】 力扣第 279 题“完全平方数”要求找到最少数量的完全平方数,使其和为给定的正整数 n。该问题可以通过动态规划解决。定义一个数组 dp,其中 dp[i] 表示和为 i 时所需的最少完全平方数个数。初始化 dp[0] 为 0,其余为无穷大。通过双重循环,外层遍历所有可能的和 i,内层遍历所有小于等于 i 的完全平方数 j * j,并更新 dp[i] 为 dp[i - j * j] + 1 的最小值。最终,dp[n] 即为所求。该算法的时间复杂度为 $O(n \sqrt{n})$,空间复杂度为 $O(n)$。 阅读详情

相关推荐

力扣hot100二刷——链表

第二次刷题不在idea写代码,而是直接在leetcode网站上写,“逼”自己掌握常用的函数。

weixin_49426115的博客 1822

【LeetCode - 279】完全平方数(四平方和定理,数论,图论,dp)

题干: 给定正整数 n,找到若干个完全平方数(比如 1, 4, 9, 16, ...)使得它们的和等于 n。你需要让组成和的完全平方数的个数最少。 示例 1: 输入: n = 12 输出: 3 解释: 12 = 4 + 4 + 4. 示例 2: 输入: n = 13 输出: 2 解释: 13 = 4 + 9. 解题报告: 很多人第一眼看到这个问题,想到的第一种做法就是使用贪心算...

xuanweiace的博客 1925

TwinCAT 3 实战指南:从系统配置到高级运动控制

本文详细介绍了TwinCAT 3工业自动化控制平台的实战应用,从系统配置、PLC编程到EtherCAT总线配置和高级运动控制。通过倍福(Beckhoff)的TwinCAT 3平台,工程师可以高效实现复杂的工业自动化任务,包括运动控制、PLC编程等。文章还提供了常见问题排查和性能优化技巧,帮助用户提升系统稳定性和实时性。

weixin_30831529的博客 304

leetcode完全平方数(BFS)

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

dzydzy7的博客 1196

【物联网毕设】多模态智能门禁系统设计(STM32+人脸识别+蓝牙联动)

本文详细介绍了基于STM32的多模态智能门禁系统设计,整合了人脸识别、蓝牙联动、RFID和密码等多种开锁方式。文章从硬件选型、电路设计、嵌入式软件编程到手机APP开发,提供了完整的毕设实现方案与调试指南,帮助物联网与嵌入式方向的学生构建一个功能全面、可扩展的智能门禁系统。

rain6的博客 246

单细胞monocle3分析流程再整理

定义root cell, 推断拟时方向# 结合先验知识自定(示例数据)# 可视化示例数据,起点是随便点的。

zfyyzhys的博客 2100

leetcode 279 完全平方数(Perfect Squares) python BFS,四平方定理

所有Leetcode题目不定期汇总在 Github, 欢迎大家批评指正,讨论交流。 ''' 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 ...

Jasmine_dream 1707

Spring WebFlux响应式编程实战(三):优雅处理异常与高效调试技巧

本文深入探讨了Spring WebFlux响应式编程中的异常处理与调试技巧。文章通过电商订单流处理场景,详细解析了Reactor核心操作符onErrorReturn、onErrorResume和onErrorMap的实战应用,并介绍了如何构建@ControllerAdvice和WebExceptionHandler全局异常处理防线。同时,提供了使用.log()操作符、Hooks.onOperatorDebug()及BlockHound进行高效调试的方法,旨在帮助开发者构建健壮、可维护的响应式应用。

weixin_29252171的博客 65

LeetCode 279——完全平方数(DP + BFS)

一、题目介绍 给定正整数n,找到若干个完全平方数(比如1, 4, 9, 16, ...)使得它们的和等于n。你需要让组成和的完全平方数的个数最少。 示例1: 输入: n = 12 输出: 3 解释: 12 = 4 + 4 + 4. 示例 2: 输入: n = 13 输出: 2 解释: 13 = 4 + 9. 二、解题思路 该题有两种解决思路,第一种广度搜索优先的思想(...

Asher 412

Agentic AI上下文工程架构终极指南:全面解决智能体理解问题

在开始架构设计前,我们需要先明确两个核心概念——Agentic AI和上下文工程。Agentic AI(智能体AI)是具备自主目标、环境交互、任务分解能力的AI系统。自主性:不需要人类逐步指令,能自己规划任务(比如“帮我订机票”→自动分解为“查航班→选座位→填信息→支付”);动态性:能根据环境变化调整行为(比如订机票时发现航班延误,自动改签到下一班);连续性:能记住历史交互(比如“上次你说喜欢靠窗位,这次帮你预留了”)。

AI开发架构师 1116

python opencv的车牌识别分割详细教程 毕业设计

python opencv的车牌识别分割详细教程 毕业设计

机器学习深度学习业余选手 1326

力扣HOT100合集

对于当前考虑的元素 nums[i],如果 dp[ j - nums[ i ] ] 为 true,说明可以用前面的元素构成和为 j -nums[ i ] 的子集,那么在加上当前元素 nums[ i ] 的情况下,就可以构成和为 j 的子集,因此 dp[ j ] 更新为 true。这样left往回走会导致错误的结果。最终得到的结果为[[1, 2, 3], [2, 1, 3], [3, 1, 2], [1, 3, 2], [2, 3, 1], [3, 2, 1]],即给定数组[1, 2, 3]的全排列结果。

qq_61504864的博客 5875

使用HART Server PC软件进行HART设备的组态、调试和分析的完整指南

HART协议是一种用于工业自动化中的双向通信协议,能够在4-20mA模拟信号的基础上叠加数字信号,从而实现设备的远程监控和管理。HART协议兼具模拟和数字通信的优点,被广泛应用于过程控制系统中。设备组态:通过软件可以对HART设备进行组态,配置设备参数。设备调试:支持设备的在线调试和故障诊断,方便快速解决问题。数据分析:提供设备运行数据的实时监控和历史数据分析功能。报表生成:支持生成各类报表,便于数据记录和管理。

qq_38334677的博客 2468

Leetcode HOT 100 题目总结(已完结)

文章目录前引题目博客链接Easy No.1 - No.21 前引 这段时间感觉动态规划已经做伤了 就是真的没什么动力再做下去了 后面没做的也都是难的不行的dp题目了 想着还是要做的 这段时间换点口味 把力扣HOT 100题给全做了 写个总结 题目博客链接 Easy No.1 - No.21 461. 汉明距离 617. 合并二叉树 104. 二叉树的最大深度 206. 反转链表 169. 多数元素 21. 合并两个有序链表 ...

Love 6's Private Blog 1万+

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版

Part-E1-SDIO-Specification-Ver4.00-Final-120220.pdf:最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版,包括SDIO 接口的外设,SDIO 接口官方协议等。

【Leetcode hot 100】279.完全平方数

本题要求用最少数量的完全平方数之和表示整数n。提供了三种解法:动态规划(O(n√n)时间,O(n)空间,基础解法)、BFS(O(n)时间,O(n)空间,最短路径思想)和数学方法(O(√n)时间,O(1)空间,基于四平方和定理)。推荐:小规模用动态规划理解原理,大规模优先数学解法。

专注Java和MySQL领域知识分享 1191

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

力扣hot100

因为 HashSet 使用的是对象的引用进行比较,所以如果两个节点是同一个节点(即内存地址相同),HashSet 会检测到这个重复的引用,从而判断链表中存在环。我的思路是通过排序后的字符串作为哈希表的键,将原字符串作为值添加到相应的键对应的列表中。否则,更新 merged 列表中最后一个区间的结束值。思路是通过遍历两个链表,计算对应节点值与进位的和,处理进位并构建新链表,最后返回不含虚拟头节点的结果链表。评论区看到一个【还有句话:走到尽头见不到你,于是走过你来时的路,等到相遇时才发现,你也走过我来时的路。

分享技术,分享经验 1962

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

(LeetCode-Hot100)279. 完全平方数

文章摘要 LeetCode 279题要求找到和为n的完全平方数的最少数量。提供了三种解法: 动态规划:定义dp[i]为组成i所需的最少平方数,通过遍历和状态转移求解,时间复杂度较高但易于理解。 BFS:将问题视为从n出发逐层减去平方数,使用队列和visited集合避免重复,天然求最短路径,效率较高。 数学解法:基于四平方和定理,通过数学性质直接判断结果可能为1、2、3或4,时间复杂度最优(O(√n))。 三种方法各具特点,可根据场景选择:DP通用性强,BFS适合中等规模,数学解法最优但需要理论知识。代码示例

小飞的博客 544

【Hot100】LeetCode—279. 完全平方数

279. 完全平方数。

weixin_44382896的博客 658

leetcode HOT100总结

本人菜鸡一枚,历时两个月时间把HOT100题做完(Ctrl C-V)了,做完之后还是感觉到很虚,很多中等题还是不会做,于是乎花几天时间把这100题给总结一下。一方面,对自己的知识梳理;另一方面,便于后续回顾。(完成度99,是因为有一道题目收费,没有做!哈哈哈!)以下所有题目都是用Python3实现的。 下面是对这些题目按照算法进行分类整体,主要包括排序、哈希表、递归\回溯、链表、双指针、动态规划、二分查找、贪心、树、深度优先搜索、广度优先搜索等。 在整理之前,先学习一下Python的基本数据类型有哪些,请

qq_36561737的博客 4744

Leetcode C++《热题 Hot 100-67》279. 完全平方数

Leetcode C++《热题 Hot 100-67》279. 完全平方数 题目 思路 代码 class Solution { public: int numSquares(int n) { //动态规划问题 dp[i] = min (dp[i], dp[i-j*j]+1) int dp[n+1]; dp[0] = 0; ...

快乐划水程序猿的专栏 253

【Hot 100】279. 完全平方数

DP 三要素的完整框架状态定义:明确 dp[i] 的具体含义(如您的定义:dp[i] 表示和为 i 的最小完全平方数数量)。转移方程:如何从子问题推导当前问题(如 dp[i] = min(dp[i - j²] + 1))。初始条件:边界值的处理(如 dp[0] = 0,dp[1] = 1)。DP 的两种实现方式自顶向下(记忆化搜索):递归 + 备忘录,适合问题结构不直观时。自底向上(迭代填表):您的代码采用的方式,更高效且避免递归开销。常见 DP 类型线性 DP(如斐波那契、爬楼梯)。

hhw_hhw的博客 804

力扣(leetcode)hot 100普通数组看这一篇就够了

这期带来的是关于力扣 hot 100当中关于普通数组这一节的内容。保证看了的人都能够学会

yyyCode的博客 2363

【leetcode hot 100 279】完全平方数

j完全平方数的最少数量,改数加上j。,其中,dp[i - j。

longii11的博客 484

力扣Hot100(Java版本)

给定一个整数数组nums和一个整数目标值target,请你在该数组中找出target的那整数,并返回它们的数组下标。你可以假设每种输入只会对应一个答案,并且你不能使用两次相同的元素。你可以按任意顺序返回答案。https://leetcode.cn/problems/two-sum/description/【简单】实例化一个HashMap来保存<值, 索引>遍历HashMap,找到就返回索引下标,找不到就添加元素。

weixin_69032308的博客 1679
上一篇: LeetCode Hot100(66/100)——118. 杨辉三角
下一篇: LeetCode Hot100(68/100)——198. 打家劫舍
TracyCoder123
博客等级 码龄8年 1万+粉丝 226原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

TracyCoder123

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值