(每日一题) 力扣 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+bb+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. 贪心策略正确性:通过字典序比较保证局部最优解即为全局最优💡。

相关推荐
明志数科40 分钟前
4D时序标注技术详解:让机器人理解连续动作的数据基础
java·算法·机器人
feng_you_ying_li1 小时前
C++复习二,继承与多态
c++
小小de风呀1 小时前
de风——【从零开始学C++】(十一):list的基本使用和模拟实现
开发语言·c++·list
KaMeidebaby1 小时前
卡梅德生物技术快报|原核表达系统工艺优化:包涵体重折叠 + 分子筛纯化实现功能 RBD 高效制备,附全参数配置
前端·人工智能·算法·数据挖掘·数据分析
陌路201 小时前
C++高级进阶--夯实进阶基础(1)
开发语言·c++
无限码力1 小时前
携程0510笔试真题【单数组交换】
算法·携程笔试·携程笔试真题·携程0510笔试真题
zlinear数据采集卡2 小时前
基准电压电路深度解析:从理论参数到ZLinear采集卡的精准参考实战
c语言·单片机·嵌入式硬件·fpga开发·自动化
BlockWay2 小时前
WEEX Labs 周度观察:微软-OpenAI 合作调整与AI 多云趋势
大数据·人工智能·算法·安全·microsoft
风筝在晴天搁浅2 小时前
快手 CodeTop LeetCode 224.基本计算器
数据结构·算法·leetcode
Smoothcloud润云2 小时前
5大功能精修,重构AI算力使用体验!
java·人工智能·windows·算法·重构·编辑器·sublime text