(每日一题) 力扣 179 最大数

文章目录

      • [🎯 LeetCode 179 最大数:最优解法详解(C++实现)](#🎯 LeetCode 179 最大数:最优解法详解(C++实现))
        • [📋 问题描述](#📋 问题描述)
        • [💡 核心思路](#💡 核心思路)
        • [🚀 完整代码实现](#🚀 完整代码实现)
        • [🔍 分步解析](#🔍 分步解析)
          • [1. 全零检测](#1. 全零检测)
          • [2. 字符串转换](#2. 字符串转换)
          • [3. 自定义排序规则](#3. 自定义排序规则)
          • [4. 拼接结果](#4. 拼接结果)
          • [5. 处理前导零](#5. 处理前导零)
        • [📊 示例验证](#📊 示例验证)
        • [⏱️ 复杂度分析](#⏱️ 复杂度分析)
        • [🚀 优化总结](#🚀 优化总结)

🎯 LeetCode 179 最大数:最优解法详解(C++实现)

📋 问题描述

给定一组非负整数 nums,重新排列每个数的顺序,使其组成一个最大的整数。例如,输入 [3, 30, 34, 5, 9],输出应为 "9534330"。由于结果可能非常大,需返回字符串而非整数。


💡 核心思路

贪心策略 :通过自定义排序规则,确保每两个数字的拼接结果局部最优,从而得到全局最大值。
关键步骤:

  1. 🔍 全零检测 :若输入全为 0,直接返回 "0"。
  2. 🔄 字符串转换:将每个数字转为字符串,避免大数拼接时的溢出问题。
  3. 📊 自定义排序 :按 a+b > b+a 的字典序降序排列。
  4. 🧩 拼接结果:直接拼接排序后的字符串。
  5. ⚠️ 处理前导零 :仅在结果全零时返回 "0"。

🚀 完整代码实现
cpp 复制代码
#include <vector>
#include <algorithm>
#include <string>

using namespace std;

class Solution {
public:
    string largestNumber(vector<int>& nums) {
        // 1. 🔍 全零检测
        if (all_of(nums.begin(), nums.end(), [](int x) { return x == 0; })) {
            return "0";
        }
        
        // 2. 🔄 转换为字符串数组
        vector<string> strs;
        for (int num : nums) {
            strs.push_back(to_string(num));
        }
        
        // 3. 📊 自定义排序:a+b > b+a
        sort(strs.begin(), strs.end(), [](const string& a, const string& b) {
            return a + b > b + a;
        });
        
        // 4. 🧩 拼接结果
        string result;
        for (const string& s : strs) {
            result += s;
        }
        
        // 5. ⚠️ 处理前导零
        size_t start = 0;
        while (start < result.size() && result[start] == '0') start++;
        return (start == result.size()) ? "0" : result.substr(start);
    }
};

🔍 分步解析
1. 全零检测
cpp 复制代码
if (all_of(nums.begin(), nums.end(), [](int x) { return x == 0; })) {
    return "0";
}
  • 作用 :若输入全为 0(例如 [0, 0, 0]),直接返回 "0"✅,避免后续无效操作。
  • 复杂度 :⏱️ 时间复杂度 O(n),🗃️ 空间复杂度 O(1)。
2. 字符串转换
cpp 复制代码
vector<string> strs;
for (int num : nums) {
    strs.push_back(to_string(num));
}
  • 优化点 :提前转换所有数字为字符串,避免排序时重复调用 to_string🚀。
  • 复杂度 :⏱️ O(n),🗃️ O(n)。
3. 自定义排序规则
cpp 复制代码
sort(strs.begin(), strs.end(), [](const string& a, const string& b) {
    return a + b > b + a;
});
  • 核心逻辑 :比较两种拼接方式 a+b 和 b+a 的字典序。
    • 示例 :比较 "3" 和 "30","330" > "303",因此 "3" 排在 "30" 前👉。
  • 复杂度 :⏱️ 排序 O(n log n),字符串比较 O(k)(k 为字符串平均长度)。
4. 拼接结果
cpp 复制代码
string result;
for (const string& s : strs) {
    result += s;
}
  • 复杂度 :⏱️ O(nk),🗃️ O(nk)(k 为字符串平均长度)。
5. 处理前导零
cpp 复制代码
size_t start = 0;
while (start < result.size() && result[start] == '0') start++;
return (start == result.size()) ? "0" : result.substr(start);
  • 作用 :跳过前导零,若结果全零则返回 "0"✅。
  • 优化点:无需反转字符串,直接遍历一次即可🚀。

📊 示例验证
输入 输出 说明
[10, 2] "210" ✅ 正确排序 "10" 和 "2"
[3, 30, 34, 5, 9] "9534330" ✅ 正确处理多位数拼接顺序
[0, 0, 0] "0" ✅ 全零检测正确触发
[0, 1, 0] "100" ✅ 前导零处理正确

⏱️ 复杂度分析
步骤 时间复杂度 空间复杂度
全零检测 O(n) O(1)
字符串转换 O(n) O(n)
自定义排序 O(n log n) O(log n)
拼接结果 O(nk) O(nk)
处理前导零 O(n) O(1)
总计 O(nk log n) O(nk)

Yes No Yes No Start All zeros? Return 0 Convert to strings Sort by a+b > b+a Concatenate Leading zeros? Trim leading zeros Keep result Output

🚀 优化总结
  1. 避免冗余操作:直接遍历处理前导零,而非反转字符串✅。
  2. 减少重复转换:提前将数字转为字符串数组,节省排序时间🚀。
  3. 贪心策略正确性:通过字典序比较保证局部最优解即为全局最优💡。

相关推荐
alphaTao1 分钟前
LeetCode 每日一题 2026/9/21-2026/9/27
python·算法·leetcode
88号技师9 分钟前
2026年9月SCI-天气状态蚂蚁优化算法Weather State Ants Optimizer-附Matlab免费代码
开发语言·算法·matlab·优化算法
TAN-90°-17 分钟前
Deep Learning for Computer Vision——Vision and Language
人工智能·深度学习·神经网络·算法·目标检测·机器学习·计算机视觉
芯祥联29 分钟前
STM32 上跑 MQTT 怎么选?嵌入式 MQTT 客户端 C 语言实现对比
c语言·stm32·单片机·嵌入式硬件·网络协议·开源·broker
chenbingjie_c8 小时前
C++ 进阶核心知识点总结:模板、内存分区、new/delete、内存池
开发语言·c++
专注仿真8 小时前
ACM算法
算法·深度优先
Escalating_xu9 小时前
【C 语言】深入理解指针(1·下):指针运算、野指针、assert 与传址实战
java·c语言·开发语言
Frank_refuel9 小时前
【C++】Json库介绍和使用
c++
重生之小比特9 小时前
【C++进阶】map和set
java·开发语言·c++
阿钱真强道10 小时前
20 嵌入式操作系统 | ubus:把自己的程序状态暴露出去
c语言·进程通信·ubus·ubusd·blobmsg