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

相关推荐
Evand J3 分钟前
MATLAB程序演示与编程思路,相对导航,四个小车的形式,使用集中式扩展卡尔曼滤波(fullyCN-EKF)
人工智能·算法
椰萝Yerosius2 小时前
[题解]2023CCPC黑龙江省赛 - Ethernet
算法·深度优先
IT猿手2 小时前
基于 Q-learning 的城市场景无人机三维路径规划算法研究,可以自定义地图,提供完整MATLAB代码
深度学习·算法·matlab·无人机·强化学习·qlearning·无人机路径规划
C++实习生3 小时前
powerbuilder9.0中文版
c语言·c++
oioihoii4 小时前
C++23 std::generator:用于范围的同步协程生成器 (P2502R2, P2787R0)
开发语言·c++·c++23
竹下为生4 小时前
LeetCode --- 448 周赛
算法·leetcode·职场和发展
未名编程4 小时前
LeetCode 88. 合并两个有序数组 | Python 最简写法 + 实战注释
python·算法·leetcode
Cuit小唐5 小时前
C++ 迭代器模式详解
c++·算法·迭代器模式
2401_858286115 小时前
CD37.【C++ Dev】string类的模拟实现(上)
开发语言·c++·算法
CQY05315 小时前
蓝桥杯2025年第十六届省赛真题-水质检测
职场和发展·蓝桥杯