给一个数组,数组里面哦都是代表非负整数的字符串,将数组里所有的数值排列组合拼接起来组成一个数字,输出拼接成的最小的数字。
一个数组,数组不为空,数组里面都是代表非负整数的字符串,可以是0开头,例如:["13", "045", "09", "56"]
。
数组的大小范围:[1, 50]
数组中每个元素的长度范围:[1, 30]
以字符串的格式输出一个数字,
20 1
120
08 10 2
10082
01 02
102
这道题目的关键在于找出一个适当的排序规则,使得所有数字按照这个规则排序后,按顺序连接得到的数字最小。观察可以发现,如果两个数字 x 和 y,连接成 xy 和 yx,如果 xy < yx,则在最终的结果中,x 应该在 y 前面。因此,我们可以定义这样的比较函数,并以此为规则对所有数字进行排序。
然后,按照排序结果依次将每个数字连接起来即可。
在具体的实现过程中,我们需要处理一些特殊情况。例如,当输入的所有数字都是 0 时,我们应该输出一个单独的 0,而不是一串 0。因此,在实现时,可以在输出结果前检查排序后的第一个数字是否为 0,如果是,则直接输出 0。
对于时间复杂度,假设输入的数字总位数为 n,我们需要 O(n log n) 的时间进行排序。由于我们只进行了一次遍历,所以连接所有数字的时间复杂度是 O(n)。因此,总的时间复杂度是 O(n log n)。
对于空间复杂度,我们只需要存储输入的所有数字,所以空间复杂度是 O(n)。
这个解法的优点是逻辑清晰,易于理解,且实现起来较为简单。但是,如果输入的数字总位数非常大,可能会导致排序时间较长。在实际使用时,可以根据具体需求和性能要求进行优化。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// 自定义排序比较函数
int compare(const void* a, const void* b) {
char ab[61], ba[61];
strcpy(ab, *(char**)a);
strcat(ab, *(char**)b);
strcpy(ba, *(char**)b);
strcat(ba, *(char**)a);
return strcmp(ab, ba);
}
int main() {
int n;
scanf("%d", &n);
// 动态分配字符串数组空间
char** arr = (char**)malloc(n * sizeof(char*));
for (int i = 0; i < n; ++i) {
// 动态分配每个字符串空间
arr[i] = (char*)malloc(31 * sizeof(char));
scanf("%s", arr[i]);
}
// 使用qsort对字符串数组进行排序,排序规则使用自定义的compare函数
qsort(arr, n, sizeof(char*), compare);
// 拼接排序后的字符串并输出
for (int i = 0; i < n; ++i) {
printf("%s", arr[i]);
}
// 释放动态分配的内存空间,防止内存泄露
for (int i = 0; i < n; ++i) {
free(arr[i]);
}
free(arr);
return 0;
}
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int main() {
int n;
cin >> n;
vector<string> arr(n);
for (int i = 0; i < n; ++i) {
cin >> arr[i];
}
// 使用 sort 进行排序,利用lambda表达式自定义排序规则
sort(arr.begin(), arr.end(), [](const string &a, const string &b) { return a + b < b + a; });
// 将排序后的数组进行拼接并输出
for (const auto &str : arr) {
cout << str;
}
return 0;
}
import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int n = scanner.nextInt();
String[] arr = new String[n];
for (int i = 0; i < n; i++) {
arr[i] = scanner.next();
}
scanner.close();
// 使用 Arrays.sort 进行排序,利用lambda表达式自定义排序规则
Arrays.sort(arr, (a, b) -> (a + b).compareTo(b + a));
// 将排序后的数组进行拼接并输出
StringBuilder sb = new StringBuilder();
for (String s : arr) {
sb.append(s);
}
System.out.println(sb.toString());
}
}
def min_number(arr):
from functools import cmp_to_key
arr.sort(key = cmp_to_key(lambda x, y: ((x+y) > (y+x)) - ((x+y) < (y+x)) ))
return ''.join(arr)
n = int(input().strip())
arr = list(map(str, input().strip().split()))
print(min_number(arr))
const readline = require('readline').createInterface({
input: process.stdin,
output: process.stdout
});
let input = [];
readline.on('line', function(line) {
input.push(line);
if(input.length === 2) {
let arr = input[1].split(' ');
// 使用 sort() 进行排序,使用匿名函数自定义排序规则
arr.sort((a, b) => (a + b) < (b + a) ? -1 : 1);
// 拼接排序后的数组并输出
console.log(arr.join(''));
readline.close();
}
});
package main
import (
"bufio"
"fmt"
"os"
"sort"
"strings"
)
func main() {
scanner := bufio.NewScanner(os.Stdin)
scanner.Scan()
scanner.Scan()
arr := strings.Fields(scanner.Text())
// 使用 sort.Slice 进行排序,自定义排序规则
sort.Slice(arr, func(i, j int) bool {
return arr[i]+arr[j] < arr[j]+arr[i]
})
// 拼接排序后的数组并输出
fmt.Println(strings.Join(arr, ""))
}