返回

揭开 LeetCode 179. 最大数 的幕后秘密:打卡算法的深入解析

后端

LeetCode 179. 最大数:揭秘算法背后的奥秘

简介

在算法学习的道路上,“打卡算法”是一个既让人又爱又恨的标签。它既代表着坚持不懈的努力,也承载着对技术攻关的渴望。今天,我们将把目光投向 LeetCode 上的第 179 道题——“最大数”,一起探索算法背后的奥秘。

算法分析

“最大数”是一道基于卡牌游戏的算法题:给定一组非负整数,将它们重新排列,形成一个最大的整数。乍一看,这似乎是一个简单的排序问题,但细究之下,这里面隐藏着不少弯弯绕。

我们不能简单地按照数字的大小排序,因为这可能会导致错误的结果。比如,给定 [10, 2],按照数字大小排序后得到 210,但正确的答案应该是 102。这是因为当我们将数字连接成字符串时,102 比 210 大。

因此,我们需要一个特殊的排序规则,即比较两个字符串连接后的结果 。为此,我们定义了一个比较器:

bool comparator(const string& a, const string& b) {
  return (a + b) > (b + a);
}

这个比较器将两个字符串连接起来,然后比较它们的连接结果。连接结果较大的字符串会被认为是较大的数字。

代码实现

掌握了排序规则,我们就可以用编程语言实现解决方案了。下面分别给出 C++、Java 和 Python 的代码实现:

C++

#include <algorithm>
#include <vector>
#include <string>

bool comparator(const string& a, const string& b) {
  return (a + b) > (b + a);
}

string largestNumber(vector<int>& nums) {
  vector<string> num_strs;
  for (int num : nums) {
    num_strs.push_back(to_string(num));
  }
  sort(num_strs.begin(), num_strs.end(), comparator);

  string res;
  for (string num_str : num_strs) {
    res += num_str;
  }

  return res.empty() ? "0" : res;
}

Java

import java.util.Arrays;
import java.util.Comparator;

public class Solution {
    public String largestNumber(int[] nums) {
        String[] num_strs = new String[nums.length];
        for (int i = 0; i < nums.length; i++) {
            num_strs[i] = String.valueOf(nums[i]);
        }
        Arrays.sort(num_strs, new Comparator<String>() {
            @Override
            public int compare(String a, String b) {
                return (b + a).compareTo(a + b);
            }
        });

        StringBuilder res = new StringBuilder();
        for (String num_str : num_strs) {
            res.append(num_str);
        }

        return res.length() == 0 ? "0" : res.toString();
    }
}

Python

def largestNumber(nums):
    num_strs = [str(num) for num in nums]
    num_strs.sort(key=lambda a, b: (b + a) > (a + b))
    res = ''.join(num_strs)
    return res if res else "0"

结语

通过本文的解析,你已经深入了解了 LeetCode 179. “最大数”的算法原理和代码实现。“打卡算法”不仅是对算法能力的磨炼,更是一种思维的提升。希望这篇文章能助你征服算法挑战,在算法学习的道路上越走越远。加油!

常见问题解答

  1. 为什么不能直接按照数字大小排序?
    因为当我们将数字连接成字符串时,数字大小的排序结果可能不是最大数。
  2. 比较器是如何工作的?
    比较器将两个字符串连接起来,然后比较它们的连接结果。连接结果较大的字符串会被认为是较大的数字。
  3. 代码中为什么要将数字转换为字符串?
    因为我们需要比较字符串连接后的结果,而数字是不能直接连接的。
  4. 如果给定的数组中包含 0,算法会如何处理?
    如果数组中包含 0,算法会将 0 放到结果字符串的最前面,因为 0 连接任何字符串都不会改变结果。
  5. 算法的时间复杂度是多少?
    算法的时间复杂度为 O(n log n),其中 n 是数组中的元素个数。