华为机试题—把数组排成最小的数 c++

题目描述:
输入一个正整数数组,把数组里所有数字拼接起来排成一个数,打印能拼接出的所有数字中最小的一个。例如输入数组{3,32,321},则打印出这三个数字能排成的最小数字为321323。
输入:
输入可能包含多个测试样例。
对于每个测试案例,输入的第一行为一个整数m (1<=m <=100)代表输入的正整数的个数。
输入的第二行包括m个正整数,其中每个正整数不超过10000000。
输出:
对应每个测试案例,
输出m个数字能排成的最小数字。
样例输入:

3
23 13 6
2
23456 56
样例输出:

13236
2345656

注:markdownpad2中,一行文字需要换行,只需要在行末尾加上两个空格即可。
解析 :按照整数形式,将若干个数字连接起来很麻烦,所以我们可以将整数转化为字符串,这样连接起来我们可以使用库函数。然后将字符串数组进行排序。 这里注意的是字符串的比较函数需要重新定义,不是比较a和b,而是比较ab与 ba。如果ab < ba,则a < b;如果ab > ba,则a > b;如果ab = ba,则a = b。比较函数的定义是本解决方案的关键。这道题其实就是希望我们能找到一个排序规则,根据这个规则排出来的数组能排成一个最小的数字。
源码

#include <iostream>
#include <math.h>
#include <assert.h>
using namespace std;
const int len =10;
char strs[100][len];
char comstr1[2*len];
char comstr2[2*len];

int mycompare(const void *str1,const void *str2)
{
    strcpy(comstr1,(char*)str1);
    strcat(comstr1,(char*)str2);

    strcpy(comstr2,(char*)str2);
    strcat(comstr2,(char*)str1);
    return strcmp(comstr1,comstr2);



void printfminnum(int *nums,int num)
{
    assert(nums);
    int i;
    for(i=0;i<num;i++)
        itoa(nums[i],strs[i],10);
      //sprintf(strs[i],"%d",nums[i]); 将nums[i]转化成10进制表示的字符串 
    qsort(strs,num,10*sizeof(char),mycompare);
    for(i=0;i<num;i++)  
        printf("%s",strs[i]);  
    printf("\n"); 
}
int main()
{

    int nums[100];
    int m;//数组元素个数
    cin>>m;
    for(int i=0;i<m;i++)
      cin>>nums[i];
    printfminnum(nums,m);

}

注:markdownpad2中加入代码块可以在代码块前后加“```”
或者Tab键 空四格

题目延伸:
1.

void qsort(void *base,int nelem,int width,int (*fcmp)(const void *,const void *));

参数:
1 待排序数组首地址
2 数组中待排序元素数量
3 各元素的占用空间大小
4 指向函数的指针,用于确定排序的顺序
举例:
对一个长为1000的数组进行排序时,int a[1000]; 那么base应为a,num应为 1000,width应为 sizeof(int),comp函数随自己的命名。

qsort(a,1000,sizeof(int),comp);
int comp(const void*a,const void*b)
{
return *(int*)a-*(int*)b;
}

2.
itoa()功能:将任意类型的数字转换为字符串。在<stdlib.h>中与之有相反功能的函数是atoi。itoa()不是C标准库中的函数,而是Windows平台下扩展的,标准库中有sprintf(),功能比这个更强,用法跟printf()类似,以后专门学习:

char str[255];
sprintf(str, "%x", 100); //将100转为16进制表示的字符串。
题目描述: 给定一个非负整数组nums,按照题目要求,将nums中的元素拼接成一个最小,并输出该最小的字符串形式。 例如,给定数组nums = [10,2],最小是102,则输出"102"。 解题思路: 要构成最小,首先需要将数组中的元素按照一定的规则进行排序。排序的规则是将两个元素进行拼接后,比较大小。 具体步骤如下: 1. 将数组转化为字符串数组,方便拼接和比较。 2. 对字符串数组进行排序,排序规则是如果拼接后的字符串a+b小于b+a,则a排在b前面。 3. 将排序后的字符串数组按顺序拼接起来,形成最小。 具体实现如下: 首先,将数组nums转换为字符串数组strs。 然后,使用排序算法对字符串数组strs进行排序,排序规则是使用自定义的函compare,实现拼接后的字符串的大小比较。 最后,将排序后的字符串数组strs按顺序拼接起来,形成最小min_num。 返回min_num。 时间复杂度分析: 对于给定的n个元素的数组,首先需要将数组转换成字符串数组,时间复杂度为O(n)。 然后,使用排序算法对字符串数组进行排序,其时间复杂度为O(nlogn)。 最后,将排序后的字符串数组按顺序拼接起来,时间复杂度为O(n)。 所以,总的时间复杂度为O(nlogn)。 空间复杂度分析: 除了题目给定的数组外,需要额外的空间来存储转换后的字符串数组,其空间复杂度为O(n)。 综上所述,解决该题的算法的时间复杂度为O(nlogn),空间复杂度为O(n)。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值