输入一个非负整数数组,把数组里所有数字拼接起来排成一个数,打印能拼接出的所有数字中最小的一个。
示例 1:
输入: [10,2]
输出: “102”
示例 2:
输入: [3,30,34,5,9]
输出: “3033459”
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/ba-shu-zu-pai-cheng-zui-xiao-de-shu-lcof
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
初看题目,最直接的想法是,使用排列组合的方法,暴力枚举所有情况,取其最小值。
题目可以视为:将数组中的数,按照字典顺序排序,从小到大排列,其对应数值即为,最小值。
关键在于如何定义偏序关系。本题规律在于定义为字典顺序
比如:
x < = y 等 价 于 ( x + y ) − ( y + x ) < = 0 x<=y等价于(x+y)-(y+x)<=0 x<=y等价于(x+y)−(y+x)<=0 x > y 等 价 于 ( x + y ) − ( y + x ) > 0 x>y等价于(x+y)-(y+x)>0 x>y等价于(x+y)−(y+x)>0
class Solution {
public String minNumber(int[] nums) {
String[] strings = new String[nums.length];
for(int i=0; i<nums.length; i++){
strings[i] = String.valueOf(nums[i]);
}
quitSort(strings, 0, strings.length-1);
StringBuilder res = new StringBuilder();
for(String s: strings){
res.append(s);
}
return res.toString();
}
public static void quitSort(String[] strings, int low, int high){
if(low>=high)
return;
int pivot_index = partion(strings, low, high);
quitSort(strings, low, pivot_index-1);
quitSort(strings, pivot_index+1, high);
}
public static int partion(String[] strings, int low, int high){
var pivot = strings[low];
int i=low, j=high;
while(i<j){
while(i<j&&((pivot+strings[j]).compareTo(strings[j]+pivot)<=0))
j--;
strings[i] = strings[j];
while(i<j&&((strings[i]+pivot).compareTo(pivot+strings[i])<=0))
i++;
strings[j] = strings[i];
}
strings[i] = pivot;
return i;
}
}
使用dfs方法,搜索全部组合情况,使用全局变量min_value,保存所有组合中最小值。
// 保持最小值
private String min_value = "999999999999999999999999999999";
public static void main(String[] args){
int[] nums = new int[]{3,30,34,5,9};
var t = new tmp();
System.out.println(t.minNumber(nums));
}
public String minNumber(int[] nums) {
int len = nums.length;
List path = new ArrayList<>();
boolean[] used = new boolean[len];
Arrays.sort(nums);
dfs(nums, len, 0, path, used);
return min_value;
}
public void dfs(int[] n, int len, int depth, List path, boolean[] used){
// 返回条件
if(depth>len){
return;
}
if(depth==len){
StringBuilder s = new StringBuilder();
for(String p:path){
s.append(p);
}
if(s.toString().compareTo(min_value)<0)
min_value = s.toString();
}
// 深度优先搜索
for(int i=0; i0&&n[i]==n[i-1]&&used[i-1]==false)
continue;
path.add(String.valueOf(n[i]));
used[i] = true;
dfs(n, len, depth+1, path, used);
used[i] = false;
path.remove(path.size()-1);
}
}
}