把数组排成最小的数 ----《剑指offer》面试题33

本文介绍一种算法,用于解决给定正整数数组,如何拼接数组中所有数字形成最小可能数值的问题。通过将数字转为字符串,定义特殊排序规则,并运用qsort函数实现排序,最终打印出最小组合数字。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目

  输入一个正整数数组,把数组里所有数字拼接起来排成一个数,打印能拼接出的所有数字中最小的一个。例如输入数组{3,32,321},则打印出这3个数组能排成的最小数字321323。

思路

 (1) 将数组中的每个数字转换成字符串
 (2) 定义A、B两个数字的排序规则,如果 AB < BA ,则 A < B
 (3) 利用qsort函数,将所有字符串进行排序
 (4) 依次打印,最终获取结果

个人想法

怎样将A、B两个数字进行排序? 比如 A=3, B=321,A应该排序在B的后面。
  (1)先将A、B两个数字位数对齐,A的位数比B少,少的位上补9: A=399
  (2) 比较A、B, 321 < 399 所以 B < A

代码

#include <iostream>
#include <string.h>
#include <algorithm>
using namespace std;

const int g_MaxNumberLength = 10;   //  如果将数字A、B转换成字符串,字符串的最大长度用g_MaxNumberLength表示

char* g_StrCombine1 = new char[g_MaxNumberLength * 2 + 1];
char* g_StrCombine2 = new char[g_MaxNumberLength * 2 + 1];

//  定义排序规则,对于两个数A、B,判断是AB > BA ?
int compare(const void* strNumber1, const void* strNumber2)
{
    strcpy(g_StrCombine1, *(const char**)strNumber1);
    strcat(g_StrCombine1, *(const char**)strNumber2);

    strcpy(g_StrCombine2, *(const char**)strNumber2);
    strcat(g_StrCombine2, *(const char**)strNumber1);

    return strcmp(g_StrCombine1, g_StrCombine2);
}

void PrintMinNumber(int* numbers, int length)
{
    if (numbers == NULL || length <= 0)
        return;

    char** strNumbers = (char**) (new int[length]);         // 定义一个字符串的二级指针,strNumbers包含length条子字符串
    for (int i = 0; i < length; ++i)
    {
        strNumbers[i] = new char[g_MaxNumberLength + 1];    //  记住结束符'\0'
        sprintf(strNumbers[i], "%d", numbers[i]);           //  将数字转换成字符串
    }

    /*
    qsort   功 能: 使用快速排序例程进行排序   

    用 法: void qsort(void *base, int nelem, int width, int (*fcmp)(const void *,const void *));  
     
    各参数:1 待排序数组首地址 2 数组中待排序元素数量 3 各元素的占用空间大小 4 指向函数的指针
     */

    qsort(strNumbers, length, sizeof(char*), compare);      //  快排


    for (int i = 0; i < length; ++i)
    {
        printf("%s", strNumbers[i]);
    }
    printf("\n");

    for (int i = 0; i < length; ++i)                        // 释放
    {
        delete[] (strNumbers[i]);
    }
    delete[] (strNumbers);
}


int main()
{
    int nums[] = {3,32,321};
    PrintMinNumber(nums, sizeof(nums) / sizeof(int));

    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值