题目:输入一个正整数数组,把数组里所有数字拼接起来排成一个数,打印能拼接出的所有数字中的最小的一个。例如输入数组{3, 32, 321},则打印出这三个数字能排出的最小数字321323.
这个题目的最直接的做法是求出这三个数字的全排列,然后把每个排列拼接起来,最后求出其中的最大值。关于求全排列的算法可以参考这里:http://blog.csdn.net/qq_33724710/article/details/51407274 大体上思路就是这样,这里就不在赘述。今天要来介绍的是另一种方法。
比如还是上边这个数组,我们依次比较,试图找出规律。由3和32,我们可以得到拼接后的两个数,332和323,发现323 < 332,我们定义这种情况下32 ‘小于’ 3。于是可以按照这种定义大小关系的方法对数组进行排序,得到{321, 32, 3},这时候,我们已经得到了最小数的序列,即为321323.
考虑到这种比较方式,以及题目中隐藏的大数问题,我们将数组中的数字转换为字符串进行处理。
掌握了这种思路后,我们可以很容易的写出如下代码:
#define NUM_MAX_LEN 10 int cmp(const void* e1, const void *e2) { char *a = *(char **)e1, *b = *(char **)e2; char ab[NUM_MAX_LEN * 2 + 1]= {0}; char ba[NUM_MAX_LEN * 2 + 1]= {0}; strcpy(ab, a); strcat(ab, b); strcpy(ba, b); strcat(ba, a); return strcmp(ab, ba); } void PrintMinNumber(int arr[], int n) { int i = 0; char **str = (char **)malloc(n * sizeof(char *)); if (NULL == arr || n <= 0) return; for (i = 0; i < n; i++) { str[i] = (char *)malloc(NUM_MAX_LEN + 1); sprintf(str[i], "%d", arr[i]); } qsort(str, n, sizeof(char *), cmp); for (i = 0; i < n; i++) { printf("%s", str[i]); } printf("\n"); for (i = 0; i < n; i++) { free(str[i]); } free(str); }
是不是不难呢?程序末尾要记得释放动态开辟的内存哟!最后不要忘了输入几个典型的测试用例来测试下。
把数组排成最小的数
最新推荐文章于 2020-11-26 12:29:12 发布