最近恰好写了归并排序和快速排序的python实现,将剑指offer中的一道题目“数组排成最小数”实现,个人觉得比较简洁,在此做个记录,欢迎讨论,不喜勿喷。
代码第一部分的长注释对问题的逻辑进行了证明,代码是归并排序的实现,如下(代码我是直接copy到这里的编辑器(?不知道这里这个东西叫啥)):
"""
剑指offer题1,关于数组排成最小数
其实这是一个排序问题,相比大家都知道答案,根据AB和BA比较,谁小以谁的顺序为升序,
即[A,B,C,D]进行组合,若已知ABCD升序排列,即AB<BA,AC<CA,AD<DA,BC<CB,BD<DB,CD<DC,
则ABCD为最小数
证明:
假设ABCD不是最小的,设DCBA最小,那么一定有DCBA<CDBA ,可以得到DC<CD,与已知矛盾,证毕。
那接下来使用某种排序算法,将判断大小的方式修正即可。
此处使用mergesort,只需要将if l1[0]<l2[0]:这个判断进行修改。
ps:这里需要注意,用到join函数,所以l1[0],l2[0]得是str类型,
k1=str(l1[0]);k2=str(l2[0])
if int(''.join([k1,k2]))<int(''.join([k2,k1])):
l0.append(l1[0])
else:
l0.append(l2[0])
完整代码如下
"""
def mergesort(lis):#此处输入的list内为int,str均可
if len(lis)==1:
return lis
else:
mid=int(1/2*len(lis))
lis1=lis[:mid]
lis2=lis[mid:]
return merge(mergesort(lis1),mergesort(lis2))
def merge(l1,l2):
l0=[]
while(len(l1) or len(l2)):
if len(l1)==0:
l0=l0+l2
return l0
elif len(l2)==0:
l0=l0+l1
return l0
else:
k1=str(l1[0])
k2=str(l2[0])
if int(''.join([k1,k2]))<int(''.join([k2,k1])):
l0.append(l1.pop(0))
else:
l0.append(l2.pop(0))
return l0
a=int(input());#python 2.7的应该是raw_input
b=input().split();
c=mergesort(b);
print(int(''.join(c)))
本人在本地上手动运行了几个例子,貌似没有问题,若有人发现bug请联系,谢谢。
PS:顺便附上一开始写的归并排序和快速排序的python代码,两份代码在spyder上运行测试过,貌似都没问题,其中归并排序放在注释里了。
"""
归并排序,richard
"""
"""
def mergesort(lis):
if len(lis)==1:
return lis
else:
mid=int(1/2*len(lis))
lis1=lis[:mid]
lis2=lis[mid:]
return merge(mergesort(lis1),mergesort(lis2))
def merge(l1,l2):
l0=[]
while(len(l1) or len(l2)):
if len(l1)==0:
l0=l0+l2
return l0
elif len(l2)==0:
l0=l0+l1
return l0
else:
if l1[0]<l2[0]:
l0.append(l1.pop(0))
else:
l0.append(l2.pop(0))
return l0
"""
"""
快速排序
"""
def quick(lis,a,b):
key=lis[a]
while(a<b):
while(lis[b]>=key and a<b):
b=b-1
lis[a]=lis[b]
while(lis[a]<=key and a<b):
a=a+1
lis[b]=lis[a]
lis[a]=key
return a
def quicksort(lis,a,b):
if a<b:
t=quick(lis,a,b)
quicksort(lis,a,t-1)
quicksort(lis,t+1,b)
return lis
代码只写了核心的部分,要在在线测试上ac,还需要加一丢丢修改的,就不赘述了。