首页 > 编程语言 >【华为OD-E卷 - 组合出合法最小数 100分(python、java、c++、js、c)】

【华为OD-E卷 - 组合出合法最小数 100分(python、java、c++、js、c)】

时间:2025-01-03 22:04:51浏览次数:3  
标签:arr java 数字 python OD 拼接 开头 排序 String

【华为OD-E卷 - 组合出合法最小数 100分(python、java、c++、js、c)】

题目

给一个数组,数组里面哦都是代表非负整数的字符串,将数组里所有的数值排列组合拼接起来组成一个数字,输出拼接成的最小的数字

输入描述

  • 一个数组,数组不为空,数组里面都是代表非负整数的字符串,可以是0开头,例如:[“13”, “045”, “09”, “56”]。

数组的大小范围:[1, 50]

数组中每个元素的长度范围:[1, 30]

输出描述

  • 以字符串的格式输出一个数字,

如果最终结果是多位数字,要优先选择输出不是“0”开头的最小数字 如果拼接出来的数字都是“0”开头,则选取值最小的,并且把开头部分的“0”都去掉再输出 如果是单位数“0”,可以直接输出“0”

用例

用例一:
输入:
20 1
输出:
120
用例二:
输入:
08 10 2
输出:
10082
用例三:
输入:
01 02
输出:
102

python解法

  • 解题思路:
  • 这道题目要求的是给定一组数字,组合成一个最小的数字。我们可以把每个数字视为字符串,比较不同数字的拼接顺序,找到使得拼接后的结果最小的顺序。

比较规则:对于任意两个数字 x 和 y,我们将它们拼接成两种顺序的字符串:x + y 和 y + x,然后比较它们的大小。若 x + y 小于 y + x,则 x 应该排在前面;反之,则 y 排在前面。

排序:根据上述的比较规则,将数字按顺序排列。

去除前导零:排序后得到的数字可能会有前导零,特别是当数组中包含多个零时。需要去除这些前导零。

特殊情况:如果排序后的数字全部是零(例如输入的是 [0, 0, 0]),则最终结果应该是 “0”。

from functools import cmp_to_key

def min_combination(arr):
    # 自定义比较函数:比较拼接后的两个字符串的大小
    def compare(x, y):
        # 比较 x + y 和 y + x 两种拼接方式的结果
        return -1 if x + y < y + x else 1 if x + y > y + x else 0

    # 使用 sorted 排序数组,排序的依据是自定义的比较函数
    sorted_arr = sorted(arr, key=cmp_to_key(compare))
    
    # 将排序后的数组拼接成一个字符串,并去除前导零
    result = ''.join(sorted_arr).lstrip('0')
    
    # 如果拼接结果为空字符串(说明原始数组全是零),返回 '0'
    return result if result else '0'

if __name__ == "__main__":
    # 输入数组并进行处理
    arr = input().split()
    # 输出最小组合数字
    print(min_combination(arr))

java解法

  • 解题思路
  • 本题要求将若干个数字组合成一个最小的数字。在解决过程中,我们需要考虑两方面:

数字排序规则:对于每一对数字,比较它们的拼接顺序。例如,两个数字 a 和 b,我们需要比较 a + b 和 b + a,然后决定它们的顺序。拼接后较小的排列应该排在前面。

特殊处理零的情况:如果所有的数字都是零(例如 0 0 0),那么最终的结果应为单一的 “0”。

解题步骤:
输入分离:首先将输入的数字分为两类:一类是以零开头的数字(例如 0, 00 等),另一类是非零开头的数字。

排序规则:

对于零开头的数字,直接按拼接后顺序排序。
对于非零开头的数字,按字典序排序(最小的在前)。
拼接组合:

对于零开头的数字,直接拼接起来并去掉前导零。
对于非零开头的数字,找到最优的组合顺序。通过对这些数字进行排序,拼接成最小的结果。
去除前导零:最后将拼接后的数字去掉可能的前导零,特别是在数字全为零的情况下,返回 “0”。

import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        // 读取输入的数字并分割成数组
        String[] arr = sc.nextLine().split(" ");
        MinNumberFinder finder = new MinNumberFinder(arr);
        // 输出最小组合数字
        System.out.println(finder.getMinNumber());
    }
}

class MinNumberFinder {
    private List<String> zList; // 存储以零开头的数字
    private List<String> nzList; // 存储非零开头的数字

    // 构造函数,根据输入数组初始化并分离数字
    public MinNumberFinder(String[] arr) {
        this.zList = new ArrayList<>();
        this.nzList = new ArrayList<>();
        splitNumbers(arr);
    }

    // 分离数字:将零开头的数字放入 zList,其余放入 nzList
    private void splitNumbers(String[] arr) {
        for (String val : arr) {
            if (val.charAt(0) == '0') { // 以零开头的数字
                zList.add(val);
            } else { // 非零开头的数字
                nzList.add(val);
            }
        }
    }

    // 获取最小组合数字
    public String getMinNumber() {
        // 排序两个列表
        sortLists();

        // 将零开头的数字拼接起来
        StringBuilder zStr = combineList(zList);

        // 如果没有非零数字,则直接返回零开头部分
        if (nzList.isEmpty()) {
            return formatResult(zStr);
        }

        // 否则,找到最优的非零数字组合顺序
        return findBestCombination(zStr);
    }

    // 排序:零开头的数字按拼接顺序排序,非零开头的数字按字典序排序
    private void sortLists() {
        zList.sort((a, b) -> (a + b).compareTo(b + a)); // 零开头数字排序规则
        nzList.sort((a, b) -> a.compareTo(b)); // 非零开头数字字典序排序
    }

    // 拼接列表中的字符串
    private StringBuilder combineList(List<String> list) {
        StringBuilder sb = new StringBuilder();
        for (String s : list) {
            sb.append(s);
        }
        return sb;
    }

    // 格式化零开头的字符串:去除前导零
    private String formatResult(StringBuilder zStr) {
        String result = zStr.toString().replaceFirst("^0+", ""); // 去除前导零
        return result.isEmpty() ? "0" : result; // 如果为空,说明全部是零,返回 "0"
    }

    // 寻找最优的非零数字组合
    private String findBestCombination(StringBuilder zStr) {
        List<String> hList = new ArrayList<>();
        hList.add(nzList.remove(0)); // 取出第一个非零数字

        // 如果头部元素与下一个非零元素相同,继续取出元素
        while (!nzList.isEmpty() && hList.get(0).charAt(0) == nzList.get(0).charAt(0)) {
            hList.add(nzList.remove(0));
        }

        String bestResult = null;
        // 遍历每一种可能的排列顺序,找到字典序最小的组合
        for (int i = 0; i < hList.size(); i++) {
            String head = hList.get(i);
            List<String> tail = new ArrayList<>(nzList); // 剩余的非零数字
            tail.addAll(hList.subList(0, i)); // 拼接当前头部前的部分
            tail.addAll(hList.subList(i + 1, hList.size())); // 拼接当前头部后的部分

            // 对尾部数字按拼接顺序进行排序
            tail.sort((a, b) -> (a + b).compareTo(b + a));

            // 构建当前的组合结果
            String tempResult = head + zStr + combineList(tail);
            if (bestResult == null || tempResult.compareTo(bestResult) < 0) {
                bestResult = tempResult;
            }
        }

        return bestResult;
    }
}

C++解法

  • 解题思路
更新中

C解法

  • 解题思路

更新中

JS解法

  • 解题思路

更新中

注意:

如果发现代码有用例覆盖不到的情况,欢迎反馈!会在第一时间修正,更新。
解题不易,如对您有帮助,欢迎点赞/收藏

标签:arr,java,数字,python,OD,拼接,开头,排序,String
From: https://blog.csdn.net/CodeClimb/article/details/144835185

相关文章

  • Java面试题(八股文+场景题)及答案最全总结(2025版)
    抽空给大家整理了一份非常全面的Java面试题+场景提及答案!还有最新涉及的内容非常全面,包含:Redis、多线程、JVM、Spring、MySQL、Dubbo…等35个知识内容,希望对找工作的同学有所帮助。完整版si我,666,不收米!Redis面试题1、什么是Redis?2、Redis的数据类型?3、使用Redis......
  • Java 集合 Collection、List、Set
    一.Collection单列集合    1. Collection代表单列集合,每个元素(数据)只包含一个值    2.Collection集合特点        ①List系列集合:添加的元素是有序、可重复、有索引。            ArrayList、LinekdList:有......
  • 基于Python的毕业设计选题题目建议 开题指导
    目录毕设选题数据分析与可视化机器学习与深度学习Web开发选题迷茫选题的重要性更多选题指导最后     大四是整个大学期间最忙碌的时光,一边要忙着准备考研,考公,考教资或者实习为毕业后面临的就业升学做准备,一边要为毕业设计耗费大量精力。大四的同学马上要......
  • 题解:AtCoder [ARC176D] Swap Permutation
    题意原题链接给定一个长度为\(n\)的排列\(p\),并执行以下操作\(m\)次:选择\(1\leqi<j\leqn\),交换\(p_i\)和\(p_j\)。定义一个序列\(p\)的权值为\(\sum_{i=1}^{n-1}|p_i-p_{i-1}|\)。求在\(\binom{n}{2}^m\)种可能的操作后,\(p\)的价值之和。答案对\(998244353\)......
  • JavaScript 基础2
    js的运算符算数运算符+相加求和,如果用在字符串则是拼接-相减求差*相乘求积/相除求商%模除求余具体用法如下letnum=154letnum2=15document.write(num+num2)document.write(`<br>`)document.write(num-num2)document.write(`<br>`)document.write(num*num2)......
  • AtCoder Beginner Contest 386 补题
    E-MaximizeXOR题目大意给出\(n\)个数,要选\(k\)个使异或和最大。\(n\leq2\times10^5,k\leqn\)\(C_n^k\leq10^6\)思路由于那个组合数的性质,发现应该是直接深搜就可以的。可是发现T了。发现如果\(k\)很大那么还是不好处理。但是发现搜\(k\)个数和搜\(n-k\)个......
  • Godot引擎开发:GDScript脚本编写_游戏开发实战项目
    游戏开发实战项目在这一部分,我们将通过一个具体的动作游戏项目来实践和巩固之前学习的GDScript脚本编写知识。我们将从游戏的基本结构开始,逐步构建一个完整的动作游戏,包括角色控制、敌人AI、碰撞检测、得分系统和游戏UI等各个方面。通过这个项目,你将能够全面了解如何在Godo......
  • Godot引擎开发:GDScript脚本编写_游戏设计模式
    游戏设计模式在游戏开发中,设计模式是一种经过验证的解决方案,可以在面对常见设计问题时提供有效的解决方案。设计模式不是具体的代码,而是解决特定问题的一种思路或框架。在使用Godot引擎和GDScript进行开发时,了解和应用这些设计模式可以极大地提高代码的质量和可维护性。本......
  • Godot引擎开发:GDScript脚本编写_游戏状态管理
    游戏状态管理在动作游戏中,游戏状态管理是确保游戏流畅运行和玩家体验的关键部分。游戏状态管理涉及多个方面,包括但不限于游戏的主菜单、游戏进行中、暂停菜单、游戏结束等状态的切换和管理。本节将详细介绍如何在Godot引擎中使用GDScript来管理这些游戏状态。游戏状态的定......
  • DL00684-山体滑坡实例/语义分割检测完整python代码含数据集
    https://item.taobao.com/item.htm?ft=t&id=872378688356山体滑坡是引发重大自然灾害的常见地质现象,尤其在山区、丘陵等地带,滑坡不仅对人民生命财产安全构成威胁,还会造成环境破坏和基础设施损毁。传统的山体滑坡检测方法依赖人工监测、地质勘探和局部传感器,这些方法不仅反应速度......