输入一个非负整数数组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;
}
}