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

news2024/12/23 18:01:47

❓ 剑指 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.coloradmin.cn/o/903061.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

不是说嵌入式是风口吗,那为什么工作还那么难找?

最近确实有很多媒体、机构渲染嵌入式可以拿高薪&#xff0c;这在行业内也是事实&#xff0c;但前提是你有足够的竞争力&#xff0c;真的懂嵌入式。 时至今日&#xff0c;能做嵌入式程序开发的人其实相当常见&#xff0c;尤其是随着树莓派、Arduino等开发板的普及&#xff0c;甚…

游戏找不到msvcr100.dll解决方法,常见的三种解决方法

在计算机领域&#xff0c;msvcr100.dll是一个非常重要的动态链接库文件。它是Microsoft Visual C 2010 Redistributable的一部分&#xff0c;用于支持Visual Studio 2010的开发环境。然而&#xff0c;在某些情况下&#xff0c;msvcr100.dll可能会出现问题&#xff0c;导致程序无…

Centos7内存高|查看占用内存命令

Centos7查看磁盘和CUP统计信息iostat命令 Centos7内存高|查看占用内存命令 docker实战(一):centos7 yum安装docker docker实战(二):基础命令篇 docker实战(三):docker网络模式(超详细) docker实战(四):docker架构原理 docker实战(五):docker镜像及仓库配置 docker实战(六…

Docker自学:利用FastAPI建立一个简单的web app

环境配置&#xff1a;下载Docker Desktop 文件一&#xff1a;main.py from typing import Unionfrom fastapi import FastAPIimport uvicornapp FastAPI()app.get("/") def read_root():return {"Hello": "World"}app.get("/items/{item…

跟着NC学作图 | 使用python绘制折线图

写在前面 今天分享一篇使用Python绘制折线图的教程&#xff0c;在我们前提的教程中&#xff0c;关于使用R语言绘制折线图的教程也很少&#xff0c;跟着PC学作图 | 小提琴图Tufte箱形图折线图的绘制教程也只有相关一部分。 Python自己也是一直在学习&#xff0c;那么也就顺带分…

透视俄乌网络战之一:数据擦除软件

数据擦除破坏 1. WhisperGate2. HermeticWiper3. IsaacWiper4. WhisperKill5. CaddyWiper6. DoubleZero7. AcidRain8. RURansom 数据是政府、社会和企业组织运行的关键要素。数据擦除软件可以在不留任何痕迹的情况下擦除数据并阻止操作系统恢复摧&#xff0c;达到摧毁或目标系统…

排名前 6 位的数学编程语言

0 说明 任何对数学感兴趣或计划学习数学的人&#xff0c;都应该至少对编程语言有一定的流利程度。您不仅会更有就业能力&#xff0c;还可以更深入地理解和探索数学。那么你应该学习什么语言呢&#xff1f; 1.python 对于任何正在学习数学的人来说&#xff0c;Python都是一门很棒…

Linux 线程并发运行

一、并发与并行 并行&#xff1a;两个线程在同一时刻同时执行&#xff0c;需要有两个处理器。 并发&#xff1a;两个线程在同一时刻交替执行&#xff0c;只有一个处理器。 并行是一种特殊的并发。 二、线程并发运行 代码如下&#xff1a; 代码分析&#xff1a; 主函数中第…

Excel/PowerPoint柱状图条形图负值设置补色

原始数据&#xff1a; 列1系列 1类别 14.3类别 2-2.5类别 33.5类别 44.5 默认作图 解决方案 1、选中柱子&#xff0c;双击&#xff0c;按如下顺序操作 2、这时候颜色会由一个变成两个 3、对第二个颜色进行设置&#xff0c;即为负值的颜色 条形图的设置方法相同

智能记账分享,轻松记录、分析和保存收支明细

在现代生活中&#xff0c;财务管理变得越来越重要。要想清晰地了解个人或家庭的财务状况&#xff0c;记录、分析和保存收支明细是必不可少的任务。现在&#xff0c;我们为你带来了一款智能记账分享工具&#xff0c;让你轻松记录、分析和保存收支明细 首先&#xff0c;我们要打…

一文带你了解如何在Java中操作Redis

文章目录 前言一、 Redis客户端简介1. Redis客户端分类2. Spring 整合 Redis 的两种方式 二、 使用 Jedis 操作 Redis1. Jedis的maven坐标2. 使用Jedis操作Redis的步骤3. Jedis 操作 Redis 示例 三、 使用 Spring Data Redis 操作 Redis1. Spring Data Redis 的 maven 坐标2. s…

【C语言】写一个程序,输入数量不确定的【0,9】范围内的整数,统计每一种数字出现的次数,输入-1表示结束

题目 写一个程序&#xff0c;输入数量不确定的【0,9】范围内的整数&#xff0c;统计每一种数字出现的次数&#xff0c;输入-1表示结束 代码 #include<stdio.h> int main() {int x;int i;int a[10];for(i0; i<10; i){//初始化数组 a[i] 0;}scanf("%d",&am…

Unity VR:XR Interaction Toolkit 输入系统(Input System):获取手柄的输入

文章目录 &#x1f4d5;教程说明&#x1f4d5;Input System 和 XR Input Subsystem&#xff08;推荐 Input System&#xff09;&#x1f4d5;Input Action Asset⭐Actions Maps⭐Actions⭐Action Properties&#x1f50d;Action Type (Value, Button, Pass through) ⭐Binding …

ARM 配置晶振频率

文章目录 前言串口乱码问题定位内核修改晶振频率uboot 修改晶振频率番外篇 前言 上篇文章《ARM DIY 硬件调试》介绍了 DIY ARM 板的基础硬件焊接&#xff0c;包括电源、SOC、SD 卡座等&#xff0c;板子已经可以跑起来了。 但是发现串口乱码&#xff0c;今天就来解决串口乱码问…

Java-数组

什么是数组 数组&#xff1a;可以看成是相同类型元素的一个集合。在内存中是一段连续的空间。 在java中&#xff0c; 数组中存放的元素其类型相同数组的空间是连在一起的每个空间有自己的编号&#xff0c;起始位置的编号为0&#xff0c;即数组的下标。 数组的创建及初始化 数…

FL Studio21最新版本升级中文语言教程

FL中文提供了跨版本升级&#xff0c;用户可以通过下载21入门版或其他非完整版的版本&#xff0c;升级为更高的版本&#xff0c;解锁更多的插件&#xff0c;下面为大家介绍在下载升级服务后&#xff0c;如何进行升级版本。 FL Studio 21 Win-安装包下载如下:https://wm.makeding…

CTF工具隐写分离神器Binwalk安装和详细使用方法

binwalk安装 1.Binwalk 介绍&#xff1a;2.Binwalk下载&#xff1a;3.Windows安装&#xff1a;4.Linux下载安装&#xff1a;5.Binwalk基本用法&#xff1a;6.Binwalk案例展示&#xff1a;7.Binwalk总结&#xff1a; 1.Binwalk 介绍&#xff1a; Binwalk 是用于搜索给定二进制镜…

Java之线程的状态

文章目录 一、线程状态二、代码演示1. Threadstate 类2. SleepUtils 类3. 运行示例 三、参考资料 一、线程状态 Java线程在运行的生命周期中可能处于下图所示的6种不同的状态,在给定的一个时刻线程只能处于其中的一个状态。 Java线程的状态 状态名称说明NEW初始状态&#xff0…

QCustomPlot的X轴是时间轴的曲线绘制

主要设置X轴的参数 SharedPointer<QCPAxisTickerTime> timeTicker(new QCPAxisTickerTime); timeTicker->setTimeFormat("%h:%m:%s");demo如下 Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget) {ui->setupUi(this);dataTimer …