(排序) 剑指 Offer 45. 把数组排成最小的数 ——【Leetcode每日一题】

news/2025/1/3 6:27:37/

❓ 剑指 Offer 45. 把数组排成最小的数

难度:中等

输入一个非负整数数组,把数组里所有数字拼接起来排成一个数,打印能拼接出的所有数字中最小的一个。

示例 1:

输入: [10,2]
输出: “102”

示例 2:

输入: [3,30,34,5,9]
输出: “3033459”

提示:

  • 0 < nums.length <= 100

说明:

  • 输出结果可能非常大,所以你需要返回一个字符串而不是整数
  • 拼接起来的数字可能会有前导 0,最后结果不需要去掉前导 0

💡思路:

可以看成是一个排序问题,在比较两个字符串 s1s2 的大小时,应该比较的是 s1+s2s2+s1 的大小:

  • 如果 s1+s2 < s2+s1,那么应该把 s1 排在前面,否则应该把 s2 排在前面。

总体流程:

  1. 初始化: 字符串列表 strs ,保存各数字的字符串格式;
  2. 列表排序: 应用以上 “排序判断规则” ,对 strs 执行排序;
  3. 返回结果: 拼接 strs 中的所有字符串,并返回。

法一:快速排序

需修改快速排序函数中的排序判断规则。字符串大小(字典序)对比的实现方法:

  • C++ 中可直接用 < , >
  • Java 中使用函数 A.compareTo(B)

法二:内置函数

  • C++ 定义为 (string& x, string& y){ return x + y < y + x; } ;
  • Java 定义为 (x, y) -> (x + y).compareTo(y + x);

🍁代码:(C++、Java)

法一:快速排序
C++

class Solution {
private:void quickSort(vector<string>& strs, int l, int r){if(l >= r) return;int i = l + 1, j = r;while(i <= j){//从前往后找第一个比str[l] 大的字符串while(i <= j && strs[i] + strs[l] <= strs[l] + strs[i])i++;//从后往前找第一个比str[l] 小的字符串while(i <= j && strs[j] + strs[l] >= strs[l] + strs[j])j--;//交换if(i < j)swap(strs[i++], strs[j--]);}swap(strs[l], strs[j]);quickSort(strs, l, j - 1);quickSort(strs, j + 1, r);}
public:string minNumber(vector<int>& nums) {// 1. 初始化vector<string> strs;for(int i = 0; i < nums.size(); i++){strs.push_back(to_string(nums[i]));}// 2. 排序quickSort(strs, 0, strs.size() - 1);// 3. 返回结果string ans;for(string s : strs){ans.append(s);}return ans;}
};

Java

class Solution {private void quickSort(String[] strs, int l, int r){if(l >= r) return;int i = l + 1, j = r;String temp;while(i <= j){//从前往后找第一个比str[l] 大的字符串while(i <= j && (strs[i] + strs[l]).compareTo(strs[l] + strs[i]) <= 0)i++;//从后往前找第一个比str[l] 小的字符串while(i <= j && (strs[j] + strs[l]).compareTo(strs[l] + strs[j]) >= 0)j--;//交换if(i < j){temp = strs[i];strs[i++] = strs[j];strs[j--] = temp;}}//此时j + 1 = i,strs[i]左边的字符串一定比strs[l]小,strs[j]右边的字符串一定比strs[l]大temp = strs[l];strs[l] = strs[j];strs[j] = temp;quickSort(strs, l, j - 1);quickSort(strs, j + 1, r);}public String minNumber(int[] nums) {// 1. 初始化String[] strs = new String[nums.length];for(int i = 0; i < nums.length; i++){strs[i] = String.valueOf(nums[i]);}// 2. 排序quickSort(strs, 0, strs.length - 1);// 3. 返回结果StringBuilder ans = new StringBuilder();for(String s : strs){ans.append(s);}return ans.toString();}
}

法二:内置函数
C++

class Solution {
public:string minNumber(vector<int>& nums) {// 1. 初始化vector<string> strs;for(int i = 0; i < nums.size(); i++){strs.push_back(to_string(nums[i]));}// 2. 内置函数排序sort(strs.begin(), strs.end(), [](string& x, string& y){return x + y < y + x;});// 3. 返回结果string ans;for(string s : strs){ans.append(s);}return ans;}
};

Java

class Solution {public String minNumber(int[] nums) {// 1. 初始化String[] strs = new String[nums.length];for(int i = 0; i < nums.length; i++){strs[i] = String.valueOf(nums[i]);}// 2. 内置函数排序Arrays.sort(strs, (x, y) -> (x + y).compareTo(y + x));// 3. 返回结果StringBuilder ans = new StringBuilder();for(String s : strs){ans.append(s);}return ans.toString();}
}

🚀 运行结果:

在这里插入图片描述

🕔 复杂度分析:

  • 时间复杂度 O ( n l o g n ) O(nlogn) O(nlogn),其中 n 为数组的长度,使用快排或内置函数的平均时间复杂度为 O ( n l o g n ) O(nlogn) O(nlogn) ,最差为 O ( n 2 ) O(n^2) O(n2)
  • 空间复杂度 O ( n ) O(n) O(n),字符串列表 strs 占用线性大小的额外空间。

题目来源:力扣。

放弃一件事很容易,每天能坚持一件事一定很酷,一起每日一题吧!
关注我LeetCode主页 / CSDN—力扣专栏,每日更新!

注: 如有不足,欢迎指正!


http://www.ppmy.cn/news/1052179.html

相关文章

方案:AI边缘计算智慧工地解决方案

一、方案背景 在工程项目管理中&#xff0c;工程施工现场涉及面广&#xff0c;多种元素交叉&#xff0c;状况较为复杂&#xff0c;如人员出入、机械运行、物料运输等。特别是传统的现场管理模式依赖于管理人员的现场巡查。当发现安全风险时&#xff0c;需要提前报告&#xff0…

服务器在使用过程中如何保护数据

在租用服务器搭建网站运营的时候&#xff0c;除了保证网站的正常运营之外&#xff0c;对于网站数据安全的保护也不容忽视&#xff0c;那么租用服务器的 时候如何做好防御呢&#xff0c;租用服务器建站的时候如何做好数据库的安全工作呢&#xff1f; 数据库的备份工作 对于数据库…

MyBatis plus 多数据源实现

1. 项目背景 最近写文章发布到【笑小枫】小程序和我的个人网站上&#xff0c;因为个人网站用的是halo框架搭建&#xff0c;两边数据结构不一致&#xff0c;导致我每次维护文章都需要两边维护&#xff0c;这就很烦~ 于是&#xff0c;本文就诞生了。通过项目连接这两个数据库&a…

二、1.保护模式

访问外部硬件有两个方式&#xff1a; 将某个外设的内存映射到一定范围的地址空间中&#xff0c; CPU 通过地址总线访问该内存区域时会落到外设 的内存中&#xff0c;这种映射让 CPU 访问外设的内存就如同访问主板上的物理内存一样外设是通过 IO 接口与 CPU 通信的&#xff0c;…

在Hive/Spark上执行TPC-DS基准测试 (PARQUET格式)

在上一篇文章:《在Hive/Spark上运行执行TPC-DS基准测试 (ORC和TEXT格式)》中,我们介绍了如何使用 hive-testbench 在Hive/Spark上执行TPC-DS基准测试,同时也指出了该项目不支持parquet格式。 如果我们想要生成parquet格式的测试数据,就需要使用其他工具了。本文选择使用另…

linux定时备份MySQL数据库循环删除前30天的备份文件

linux定时备份MySQL数据库循环删除前30天的备份文件 一、 检查有没安装crond,如果没有&#xff0c;先安装 1、先检查一下有没有cron rpm -qa|grep cron如果输入上面命令有如下显示&#xff0c;则不需要安装 2、没有安装的话&#xff0c;就使用一下命令安装 yum -y install …

【Go 基础篇】Go语言获取用户终端输入:实现交互式程序的关键一步

介绍 在许多编程场景中&#xff0c;我们需要编写交互式程序&#xff0c;以便用户可以在终端中输入数据并与程序进行交互。Go语言提供了丰富的方式来获取用户终端输入&#xff0c;使得编写交互式程序变得简单而有趣。本篇博客将深入探讨Go语言中获取用户终端输入的各种方法&…

“深入探索JVM:Java虚拟机背后的奥秘“

标题&#xff1a;深入探索JVM&#xff1a;Java虚拟机背后的奥秘 摘要&#xff1a;本文将深入探索Java虚拟机&#xff08;JVM&#xff09;的内部工作原理和关键组成部分&#xff0c;揭示JVM背后的奥秘。通过对类加载机制、内存管理、垃圾回收、即时编译等方面的详细介绍&#x…