题目:输入一个正整数数组,将它们连接起来排成一个数,输出能排出的所有数字中最小的一个。例如输入数组{32, 321},则输出这两个能排成的最小数字32132。请给出解决问题的算法,并证明该算法。
分析:这是09年6月份百度新鲜出炉的一道面试题,从这道题我们可以看出百度对应聘者在算法方面有很高的要求。
这道题其实是希望我们能找到一个排序规则,根据这个规则排出来的数组能排成一个最小的数字。要确定排序规则,就得比较两个数字,也就是给出两个数字m和n,我们需要确定一个规则m和n哪个更大,而不是仅仅只是比较这两个数字的数值哪个更大。
根据题目的要求,两个数字m
和n排成的数字mn和nm,如果mn<nm,那么我们应该输出mn,也就是m应该排在n的前面,也就是m小于n;反之,如果nm<mn,n小于m。如果mn==mn,m等于n。
接下来我们考虑怎么去拼接数字,即给出数字m和n,怎么得到数字mn和nm并比较它们的大小。直接用数值去计算不难办到,但需要考虑到的一个潜在问题是m和n都在int能表达的范围内,但把它们拼起来的数字mn和nm就不一定能用int表示了。所以我们需要解决大数问题。一个非常直观的方法就是把数字转换成字符串。
另外,由于把数字m和n拼接起来得到的mn和nm,它们所含有的数字的个数肯定是相同的。因此比较它们的大小只需要按照字符串大小的比较规则就可以了
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
const int g_MaxNumberLength=10;
char* g_StrCombine1=(char*)malloc((2*g_MaxNumberLength+1)*sizeof(char));
char* g_StrCombine2=(char*)malloc((2*g_MaxNumberLength+1)*sizeof(char));
//定义比较规则
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**)malloc(length*sizeof(int));
for(int i=0;i<length;++i)
{
strNumbers[i]=(char*)malloc((g_MaxNumberLength+1)*sizeof(char));
sprintf(strNumbers[i],"%d",numbers[i]);
}
qsort(strNumbers,length,sizeof(char*),compare);//库函数qsort排序
for(int i=0;i<length;++i)
printf("%s",strNumbers[i]);
printf("\n");
for(int i=0;i<length;i++)
free(strNumbers[i]);
free(strNumbers);
}
int main()
{
int* numbers;
int length;
scanf("%d",&length);
numbers=(int*)malloc(length*sizeof(int));
for(int i =0;i<length;i++)
scanf("%d",&numbers[i]);
printMinNumber(numbers,length);
return 0;
}
结果:
分享到:
相关推荐
【免费题库】华为OD机试 - 数组组成的最小数字(Java & JS & Python & C & C++).html
输入一个正整数数组,把数组里所有数字拼接起来排成一个数,打印能拼接出的所有数字中最小的一个。例如输入数组{3,32,321},则打印出这三个数字能排成的最小数字为321323。 解法一:cmp_to_key函数 from ...
我们可以找到数组中间的元素 array[mid],如果中间的元素位于前面的递增数组,那么它应该大于或者等于 low 下标对应的元素,此时数组中最小的元素应该位于该元素的后面,我们可以把 low 下标指向该中间元素,这样...
首先,数组是Java中的基本类型之一,它是由相同类型的数据项组成的有序集合。每个数据项都有一个唯一的索引,从0开始,到数组长度减1。例如,一个整型数组int[] numbers可以存储一系列的整数,如numbers[0], numbers...
在这段代码中,`invert()`函数使用了指针来操作数组元素。相比直接使用数组下标的方式,使用指针具有以下优势: - **内存访问速度更快**:指针直接操作内存地址,避免了下标运算带来的开销。 - **代码更简洁易懂**:...
数对由数组中的两个不同元素组成,其中一个元素位于另一个元素的右侧。计算差值是将左侧元素减去右侧元素,而不是相反,因为通常较小的数会被较大的数减去以得到较大的差值。 解决此类问题的一个常见方法是使用双...
Matlab 中去掉数组中重复的值 Matlab 是一个功能强大的数学和技术计算软件,对于数据处理和分析有着广泛的应用。在数据处理过程中,去除数组中重复的值是一个常见的问题,本文将介绍 Matlab 中去掉数组中重复的值的...
1. **数组定义**:在易语言中,定义数组的基本语法是`数组名称 数组类型[元素个数]`,例如,定义一个整型数组`整数数组 10`表示一个包含10个整数的数组。 2. **遍历数组**:为了判断某个数值是否在数组中,我们需要...
本文将深入探讨如何有效地复制数组以及如何从数组中抽取特定元素来组成新的数组,这将帮助我们更好地理解和掌握JavaScript中的数组操作技巧。 ### 复制数组 复制数组通常指的是创建一个与原数组具有相同元素的新...
华为OD正版题库,CD卷,2024原题库。超低价可下载包含多种代码和解析,不用购买高价的专栏,任何问题可私信
私信博主获取三天体验卡,免费看所有华为OD真题、考试报告、手撕代码、面试记录
下面将详细介绍如何在C++中操作数组以及如何在数组中插入元素。 一、数组的基本概念 数组是由相同类型的数据元素按特定顺序排列组成的一种数据结构。在C++中,数组声明时需要指定元素的类型和数组的大小。例如,...
本话题关注的是如何计算一个包含10个无符号整数的数组的中位数。中位数是一组数据集中间位置的数值,将数据分为相等的两部分,一半的值大于它,另一半小于或等于它。对于10个元素的数组,中位数是第5个元素,因为它...
1. 定义一个递归函数,接收当前组合的索引位置、当前组合数组、未处理的数组列表作为参数。 2. 如果所有元素都被选中(即组合完成),将当前组合添加到结果集合中。 3. 对于未处理数组中的每个元素,将其添加到当前...
### 数组中的数分别后移M位 #### 知识点概述 本篇文章将围绕一个特定的编程问题展开讨论:如何实现数组中的元素向右移动指定的位置数(M位),并详细解析这个问题的解决方法、涉及到的核心算法以及具体的代码实现...
在C语言中,找到数组中第二大的元素是一个常见的编程问题,尤其在数据结构和算法的学习中经常遇到。这个问题的关键在于如何有效地遍历数组并找出最大值和次大值。下面我们将详细讨论这个问题的解决方法。 首先,...
题目要求在给定的整型数组 `nums` 中找出仅出现一次的两个数字,并返回这两个数字组成的数组。数组中所有其他元素都会出现两次。题目强调了时间复杂度必须为 O(n),空间复杂度应为 O(1)。这里的 n 表示数组 `nums` ...
数组是有序的数据集合,它由相同类型的元素组成,这些元素共享一个共同的变量名(数组名)。在Java中,数组的声明通常包含数据类型和数组名,例如`int numbers[]`或`int[] numbers`,两者表示的含义相同,都是声明一...
二维数组是一种更加复杂的数组形式,它由多个一维数组组成。二维数组的说明形式如下: type-specifier var_name [row_size][column_size]; 例如,下面是一个二维整型数组的说明: ```c int a[3][4]; ``` 该数组有3...
二维数组是一种数据结构,它由多个一维数组组成,可以看作是表格或矩阵的形式。每个一维数组都是一行数据,而整个二维数组则构成了一个包含多行的数据集。在处理这样的数据集时,经常需要去除重复的记录,以确保数据...