【2024华为OD-E卷-100分-数组组成的最小数字】(题目+思路+Java&C++&Python解析)

题目描述

给定一个由非负整数组成的数组,你需要将这些数字按照某种顺序重新排列,使得它们组合成的数字最小。

例如,输入数组 [3, 30, 34, 5, 9],重新排列后的数字为 3033459。

解题思路

  1. 自定义排序规则:我们需要定义一个自定义的排序规则来比较两个数字组成的字符串。例如,对于数字 a 和 b,我们需要比较 ab 和 ba,取字典序较小的组合。
  2. 处理前导零:由于数字可能包含零,我们需要特别处理前导零的情况。如果某个数字是零,且它不是唯一的一个数字(即数组中还有其他数字),那么它应该排在非零数字之后,以避免产生前导零。
  3. 实现排序:根据自定义的规则对数组进行排序。
  4. 拼接结果:将排序后的数字拼接成最终的结果字符串。

Java 代码解析

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

public class Solution {
    public String smallestNumber(int[] nums) {
        String[] strNums = new String[nums.length];
        for (int i = 0; i < nums.length; i++) {
            strNums[i] = String.valueOf(nums[i]);
        }
        
        Arrays.sort(strNums, new Comparator<String>() {
            @Override
            public int compare(String a, String b) {
                if (a.equals("0") || b.equals("0")) {
                    if (!a.equals("0")) return -1;
                    if (!b.equals("0")) return 1;
                }
                String order1 = a + b;
                String order2 = b + a;
                return order1.compareTo(order2);
            }
        });
        
        StringBuilder sb = new StringBuilder();
        for (String num : strNums) {
            sb.append(num);
        }
        
        // Remove leading zeros if the result is not just "0"
        while (sb.length() > 1 && sb.charAt(0) == '0') {
            sb.deleteCharAt(0);
        }
        
        return sb.toString();
    }

    public static void main(String[] args) {
        Solution solution = new Solution();
        int[] nums = {3, 30, 34, 5, 9};
        System.out.println(solution.smallestNumber(nums)); // Output: 3033459
    }
}

C++ 代码解析

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

bool compare(const std::string &a, const std::string &b) {
    if (a == "0" || b == "0") {
        return !(a == "0") && b == "0";
    }
    std::string order1 = a + b;
    std::string order2 = b + a;
    return order1 < order2;
}

std::string smallestNumber(std::vector<int>& nums) {
    std::vector<std::string> strNums;
    for (int num : nums) {
        strNums.push_back(std::to_string(num));
    }
    
    std::sort(strNums.begin(), strNums.end(), compare);
    
    std::string result;
    for (const std::string &num : strNums) {
        result += num;
    }
    
    // Remove leading zeros if the result is not just "0"
    size_t pos = result.find_first_not_of('0');
    if (pos != std::string::npos) {
        result = result.substr(pos);
    } else if (!result.empty()) {
        result = "0";
    }
    
    return result;
}

int main() {
    std::vector<int> nums = {3, 30, 34, 5, 9};
    std::cout << smallestNumber(nums) << std::endl; // Output: 3033459
    return 0;
}

Python 代码解析

def smallest_number(nums):
    def compare(a, b):
        if a == '0' or b == '0':
            return (a != '0') - (b != '0')
        order1 = a + b
        order2 = b + a
        return (order1 < order2) - (order1 > order2)
    
    str_nums = list(map(str, nums))
    str_nums.sort(key=cmp_to_key(compare))
    
    result = ''.join(str_nums)
    
    # Remove leading zeros if the result is not just "0"
    result = result.lstrip('0')
    if not result:
        result = '0'
    
    return result

# Helper function for Python 2 compatibility (not needed in Python 3.x with functools.cmp_to_key)
# In Python 3, you can use `sorted` directly with `key=cmp_to_key(compare)`
from functools import cmp_to_key

nums = [3, 30, 34, 5, 9]
print(smallest_number(nums))  # Output: 3033459

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

执着的小火车

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值