LeetCode 每日一题笔记 日期:2026.05.31 题目:2126. 摧毁小行星

LeetCode 每日一题笔记

0. 前言

  • 日期:2026.05.31
  • 题目:2126. 摧毁小行星
  • 难度:中等
  • 标签:数组、贪心、排序

1. 题目理解

问题描述 :

给定行星初始质量 mass 和小行星数组 asteroids,可以按任意顺序与小行星碰撞:

  • 行星质量 ≥ 小行星质量:行星摧毁小行星,并获得其质量;
  • 行星质量 < 小行星质量:行星被摧毁。
    判断是否存在一种顺序,让行星摧毁所有小行星。

示例:

输入:mass = 10, asteroids = 3,9,19,5,21

输出:true

解释:按 3,5,9,19,21 的顺序,行星质量依次增长为 13→18→27→46→67,可全部摧毁。

2. 解题思路

核心观察

  • 贪心策略:优先摧毁质量小的小行星,才能不断增长行星质量,为后续摧毁更大的小行星创造条件;
  • 排序后遍历,只要过程中行星质量始终不小于当前小行星,就能完成全部摧毁。

算法步骤

  1. 将小行星数组按升序排序;
  2. 用 long 类型记录行星当前质量,避免溢出;
  3. 遍历排序后的数组,若行星质量小于当前小行星,直接返回 false;
  4. 否则累加小行星质量,遍历结束返回 true。

3. 代码实现

java 复制代码
package lc2126;

import java.util.Arrays;

class Solution {
    public boolean asteroidsDestroyed(int mass, int[] asteroids) {
        Arrays.sort(asteroids);
        long cur = mass;
        for (int a : asteroids) {
            if (cur < a) return false;
            cur += a;
        }
        return true;
    }
}

4. 代码优化说明

(代码未做任何修改,仅添加注释讲解)

java 复制代码
class Solution {
public boolean asteroidsDestroyed(int mass, int[] asteroids) {
    // 找到所有小行星中的最大质量,用于确定二进制分组的最高位
    int mx = 0;
    for (int x : asteroids) {
        mx = Math.max(mx, x);
    }

    // 计算最大质量的二进制位数,确定分组数量
    int maxWidth = 32 - Integer.numberOfLeadingZeros(mx);
    // sum数组:存储每个二进制位分组内所有小行星的质量和
    long[] sum = new long[maxWidth];
    // mn数组:存储每个二进制位分组内的最小小行星质量
    int[] mn = new int[maxWidth];
    Arrays.fill(mn, Integer.MAX_VALUE);

    // 按二进制最高位对小行星进行分组
    for (int x : asteroids) {
        // 计算当前小行星的最高二进制位
        int i = 31 - Integer.numberOfLeadingZeros(x);
        sum[i] += x;
        mn[i] = Math.min(mn[i], x);
    }

    // 行星当前质量,用long避免溢出
    long m = mass;
    // 按二进制位从低到高遍历分组
    for (int i = 0; i < maxWidth; i++) {
        // 该分组无小行星,跳过
        if (mn[i] == Integer.MAX_VALUE) {
            continue;
        }
        // 行星质量小于该分组最小的小行星,无法摧毁,直接返回false
        if (m < mn[i]) {
            return false;
        }
        // 摧毁该分组所有小行星,累加质量
        m += sum[i];
    }
    // 所有分组都可摧毁,返回true
    return true;
}
}

5. 复杂度分析

  • 排序贪心解法
    • 时间复杂度:O(nlog⁡n)O(n \log n)O(nlogn),排序占主要开销,遍历为线性。
    • 空间复杂度:O(1)O(1)O(1),原地排序(不考虑排序栈开销),仅用常数变量。
  • 二进制分组优化解法
    • 时间复杂度:O(n)O(n)O(n),两次线性遍历,无排序开销。
    • 空间复杂度:O(log⁡M)O(\log M)O(logM),MMM 为最大小行星质量,分组数组大小为常数级。

6. 总结

  • 核心:贪心思想,优先处理质量小的目标,是解决此类"增长型"问题的通用策略;
  • 排序解法直观易写,面试优先使用;二进制分组解法在大数据下效率更高,可作为进阶优化;
  • 关键细节:行星质量累加可能超过 int 范围,需用 long 类型存储,避免溢出错误。
相关推荐
陈年老古董11 分钟前
Hive 函数学习笔记(上):单行函数与炸裂函数
hive·笔记·学习
垆边人似月.31 分钟前
华为机试题 :字符串压缩
算法·华为
ggb喔32 分钟前
52pojie 的图片工具:为什么无损转换后体积涨了 6 倍、照片方向还是歪的
图像处理·python·算法·计算机视觉·图形渲染·媒体
菜鸟~noob23334 分钟前
【电子战】第25篇:自由空间、双射线与菲涅尔区【含matlab代码】
开发语言·算法·matlab
喜欢打篮球的普通人44 分钟前
MiniMind 学习笔记(十八):速通强化学习——从 MDP 到 PPO 的概念与算法地图
笔记·深度学习·学习
地平线开发者1 小时前
地平线征程6M YOLOv8s 部署
算法·自动驾驶
Run_Teenage1 小时前
算法:Manacher(马拉车)算法、中心扩展算法
算法
志尊宝1 小时前
Vue3 零基础每日笔记(076):防抖节流的正确使用——搜索框、按钮防重复提交、滚动监听
javascript·vue.js·笔记
Tisfy2 小时前
LeetCode 0301.删除无效的括号:二进制枚举 / 回溯
算法·leetcode·字符串·题解·回溯·括号匹配·二进制枚举
Nil2082 小时前
leetcode 322零钱兑换
算法·leetcode·职场和发展