输入一个非负整数数组numbers,把数组里所有数字拼接起来排成一个数,打印能拼接出的所有数字中最小的一个。
例如输入数组[3,32,321],则打印出这三个数字能排成的最小数字为321323。
1.输出结果可能非常大,所以你需要返回一个字符串而不是整数
2.拼接起来的数字可能会有前导 0,最后结果不需要去掉前导 0
2.拼接起来的数字可能会有前导 0,最后结果不需要去掉前导 0
数据范围:
0<=len(numbers)<=100
[11,3]
"113"
[]
""
[3,32,321]
"321323"
# -*- coding:utf-8 -*-
class Solution:
def PrintMinNumber(self, numbers):
# write code here
res = []
#冒泡排序
n = len(numbers)
tmp = 0
numbers = sorted(numbers)
for i in range(n-1):
for j in range(i+1,n):
if str(numbers[i]) + str(numbers[j]) > str(numbers[j]) + str(numbers[i]):
numbers[j],numbers[i] = numbers[i],numbers[j]
a = list(map(str,numbers))
return "".join(a)
说白了就是排序,不管是是快排还是冒泡,只要str之后的两两对比,小的在前面就好了 # -*- coding:utf-8 -*- class Solution: def PrintMinNumber(self, numbers): # write code here if len(numbers) == 0: return '' # 填充位数 max_n = max(numbers) max_fi = len(str(max_n)) filled_numbers = [] indices = [] i = 0 for x in numbers: strx = str(x) while len(strx) < max_fi: strx += strx[-1] filled_numbers.append(strx) indices.append(i) i += 1 # 排序 for i in range(len(numbers)): for j in range(i): if filled_numbers[j] > filled_numbers[i]: tmp = filled_numbers[i] filled_numbers[i] = filled_numbers[j] filled_numbers[j] = tmp tmpi = indices[i] indices[i] = indices[j] indices[j] = tmpi # 最后拼接 new_numbers = [numbers[i] for i in indices] final = '' for x in new_numbers: strx = str(x) final += strx return final
# -*- coding:utf-8 -*- class Solution: def PrintMinNumber(self, numbers): # write code here if not numbers: return '' n=len(numbers) str_numbers=[] for i in range(n): s=str(numbers[i]) str_numbers.append(s) res='' while str_numbers: out=str_numbers[0] l=len(str_numbers) for i in range(1,l): out=self.compare(out,str_numbers[i]) out_index=str_numbers.index(out) str_numbers=str_numbers[:out_index]+str_numbers[out_index+1:] res+=out return res def compare(self,str1,str2): if str1+str2<str2+str1: return str1 else: return str2
# -*- coding:utf-8 -*- class Solution: def PrintAll(self,numbers): results = [] for i in range(len(numbers)): temp1 = str(numbers[i]) temp2 = numbers[:] temp2.pop(i) if len(temp2): temp3 = self.PrintAll(temp2) for num in temp3: results.append(int(temp1+str(num))) else: results.append(int(temp1)) return results # def PrintMinNumber(self, numbers): # write code here allnum = self.PrintAll(numbers) if len(allnum): output = str(min(allnum)) else: output = '' return output
python解法:
# -*- coding:utf-8 -*-
'''
解法1:选择数字最高位最小的放前面,转换成字符串好做一点,类似排序的做法;
排序是直接比较两者大小,这个是根据a+b>b+a判断;
s=list(map(str, numbers))可以把所有数字转换成字符串存入到s中;
'''
class Solution:
def PrintMinNumber(self, numbers):
res = []
for i in range(len(numbers)-1):
for j in range(i+1,len(numbers)):
# 每次选择数字最高位最小的放前面
if str(numbers[i]) + str(numbers[j]) > str(numbers[j]) + str(numbers[i]):
numbers[i],numbers[j] = numbers[j],numbers[i]
res = ''.join(str(i) for i in numbers)
return res
# -*- coding:utf-8 -*- class Solution: def PrintMinNumber(self, numbers): # write code here for i in range(1,len(numbers)): for j in range(0,len(numbers)-i): s1 = ''.join(str(x) for x in numbers[j:j+2]) s2 = ''.join(str(y) for y in numbers[j:j+2][::-1]) if s1 > s2: numbers[j], numbers[j+1] = numbers[j+1], numbers[j] return ''.join(str(x) for x in numbers)冒泡排序的变形 基本思路都不变,就是比较的东西变了
class Solution: def PrintMinNumber(self, numbers): # write code here for i in range(len(numbers)): for j in range(i+1,len(numbers)): a = int(str(numbers[i])+str(numbers[j])) b = int(str(numbers[j])+str(numbers[i])) if a > b: numbers[i], numbers[j] = numbers[j], numbers[i] return ''.join(list(map(str, numbers)))
# -*- coding:utf-8 -*- """ 输入一个正整数数组,把数组里所有数字拼接起来排成一个数, 打印能拼接出的所有数字中最小的一个 """ import itertools #使用模块产生可迭代对象 class Solution(object): def PrintMinNumber(self, numbers): # write code here assert len(numbers)>0 # lis = [] for l in list(itertools.permutations(numbers)):#全排列迭代成元组 str0 = [str(i) for i in l] #l为元组类型转换成字符列表str0 l = ''.join(str0) #将字符数字连接成整体字符串 lis.append(int(l))#将字符l转换成整型存入到lis列表中 return min(lis)#返回lis列表中的最小值
思路:
1:转化为字符串比较
2:比较函数重新写,mn < nm则m , n位置不变
3:如果不熟悉sort,就自己写一个快排就行
import functools
class Solution:
def PrintMinNumber(self, numbers):
# write code hereif not numbers: return ""
if not numbers: return ""
number = list(map(str, numbers))
number.sort(key=functools.cmp_to_key(self.compare))
return "".join(number).lstrip('0') or'0'
def compare(self,num1, num2):
m = str(num1) + str(num2)
n = str(num2) + str(num1)
if m > n:
return 1
elif m == n:
return 0
else:
return -1
# -*- coding:utf-8 -*- class Solution: def PrintMinNumber(self, numbers): if not numbers: return "" # write code here # 找到最大数,确定是几位数 m = max(numbers) k = 0 s = m/10 while s: k += 1 s = s / 10 door = 10**k def tr(n): # 将一个数按照从左到右转换成各个位阶上的数组 s = n ds = [] while s: k = s /10 r = s % 10 ds.append(r) s = k ds = ds[::-1] d = len(ds) # 循环重复自己,补齐到与最大的数的位数相同,返回补齐后的数,自己的位数 i = 0 while n < door: n = n * 10 + ds[i] i = (i+1) % d return n, d # 按照补齐以后的数进行排序,小的在前面 new = sorted(numbers, key=lambda x: tr(x)[0]) # 将排序好的数组组装成一个大的整数 degrees = map(lambda x: tr(x)[1], new) total = sum(degrees) re = 0 for e, d in zip(new, degrees): total -= d re += e * (10**total) return re
# -*- coding:utf-8 -*-
class Solution:
def PrintMinNumber(self, numbers):
# write code here
if len(numbers) == 1:
return numbers
res = {}
for i, v in enumerate(numbers):
res[i] = v
max_num = max(res.values())
ml = len(str(max_num))
result = {}
for k,v in res.items():
if len(str(v)) < ml:
result[k] = str(v) + "9"*(ml-len(str(v)))
else:
result[k] = str(v)
result = sorted(result.items(),key=lambda x:x[1])
minNum = ""
for i in result:
minNum += str(res[i[0]])
return int(minNum) 虽然我知道这种解法不对,但是挺好玩的贴上来。一会儿再贴
class Solution: def PrintMinNumber(self, numbers): numbers = self.quick(numbers) s = '' for i in numbers: s+=str(i) return s def quick(self, numbers, key=0): if not numbers: return [] if len(numbers)==1: return numbers n = len(numbers) left, right = [], [] for i in range(1,n): if str(numbers[i])+str(numbers[key])>str(numbers[key])+str(numbers[i]): right.append(numbers[i]) else: left.append(numbers[i]) return self.quick(left)+[numbers[key]]+self.quick(right)
# -*- coding:utf-8 -*- class Solution: def PrintMinNumber(self, numbers): (727)# write code here length=len(numbers) if length==0: return '' number=[str(i) for i in numbers] for i in range(length-1): for j in range(length-2,i-1,-1): #将数组内的数字进行两两比较进行排序,然后再拼接就是最小的含多数字的数 if int(number[j]+number[j+1])>int(number[j+1]+number[j]): number[j],number[j+1]=number[j+1],number[j] num=''.join(number) return num本题的重点就是获得最小的一个全排列,我们发现两两数字拼接的规则可以通过自反,对称,传递性传到n个数字的拼接。因此我们只需要两两比较,确定一个“最小的”排序数组就行了,此时将所有进行拼接,就能得到最小的
class Solution:
def PrintMinNumber(self,numbers):
if not numbers:
return ''
maxl = len(str(max(numbers)))
tmp = [str(x) for x in numbers]
for i in range(len(tmp)):
while len(tmp[i]) < maxl:
tmp[i] += tmp[i][-1]
tmp = [int(x) for x in tmp]
zlist = list(zip(tmp,numbers))
zlist = sorted(zlist, key = lambda x:x[0])
res = ''
for i in zlist:
res += str(i[1])
return res.lstrip('0')&nbs***bsp;0 # -*- coding:utf-8 -*- class Solution: def PrintMinNumber(self, numbers): # write code here def Perm(start_index): if start_index >= len(char_numbers): clone = "".join(char_numbers) result.append(clone) else: swap_index = start_index while swap_index < len(char_numbers): char_numbers[swap_index], char_numbers[start_index] = char_numbers[start_index], char_numbers[swap_index] Perm(start_index+1) char_numbers[swap_index], char_numbers[start_index] = char_numbers[start_index], char_numbers[swap_index] swap_index += 1 result = [] char_numbers = [str(num) for num in numbers] Perm(0) return min(result)全排序实现
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
public class Solution {
public String PrintMinNumber(int [] numbers) {
int n;
String s="";
ArrayList<Integer> list= new ArrayList<Integer>();
n=numbers.length;
for(int i=0;i<n;i++){
list.add(numbers[i]);
}
Collections.sort(list, new Comparator<Integer>(){
public int compare(Integer str1,Integer str2){
String s1=str1+""+str2;
String s2=str2+""+str1;
return s1.compareTo(s2);
}
});
for(int j:list){
s+=j;
}
return s;
}
}