每日一题 - 剑指 Offer 45. 把数组排成最小的数
题目信息
时间: 2019-07-01
题目链接:Leetcode
tag: 快速排序
难易程度:中等
题目描述:
输入一个非负整数数组,把数组里所有数字拼接起来排成一个数,打印能拼接出的所有数字中最小的一个。
示例1:
输入: [10,2]
输出: "102"
示例2:
输入: [3,30,34,5,9]
输出: "3033459"
提示
1. 0 < nums.length <= 100
解题思路
本题难点
此题求拼接起来的 “最小数字” ,本质上是一个排序问题。
具体思路
字符串 xy < yx , yz < zy ,需证明 xz < zx 一定成立。
代码
class Solution {
public String
minNumber(int[] nums
) {
String
[] strs
= new String[nums
.length
];
for(int i
= 0; i
< nums
.length
; i
++){
strs
[i
] = String
.valueOf(nums
[i
]);
}
quickSort(strs
,0,strs
.length
- 1);
StringBuilder res
= new StringBuilder();
for(String s
: strs
){
res
.append(s
);
}
return res
.toString();
}
public void quickSort(String
[] strs
,int l
,int r
){
if(l
>= r
){
return;
}
int i
= l
;
int j
= r
;
while(i
< j
){
while((strs
[j
] + strs
[l
]).compareTo(strs
[l
] + strs
[j
]) >= 0 && i
< j
){
j
--;
}
while((strs
[i
] + strs
[l
]).compareTo(strs
[l
] + strs
[i
]) <= 0 && i
< j
){
i
++;
}
swap(strs
,i
,j
);
}
swap(strs
,l
,i
);
quickSort(strs
,l
,j
-1);
quickSort(strs
,j
+1,r
);
}
public void swap(String
[] strs
,int i
,int j
){
String temp
= strs
[i
];
strs
[i
] = strs
[j
];
strs
[j
] = temp
;
}
}
复杂度分析:
时间复杂度 O(NlogN) :N 为最终返回值的字符数量( strs 列表的长度 ≤N );使用快排或内置函数的平均时间复杂度为 O(NlogN) ,最差为 O(N ^2 ) 。空间复杂度 O(N) : 字符串列表 strs占用线性大小的额外空间。
其他优秀解答
解题思路
Java 内置数组排序函数: (x, y) -> (x + y).compareTo(y + x)
代码
class Solution {
public String
minNumber(int[] nums
) {
String
[] strs
= new String[nums
.length
];
for(int i
= 0; i
< nums
.length
; i
++)
strs
[i
] = String
.valueOf(nums
[i
]);
Arrays
.sort(strs
, (x
, y
) -> (x
+ y
).compareTo(y
+ x
));
StringBuilder res
= new StringBuilder();
for(String s
: strs
)
res
.append(s
);
return res
.toString();
}
}