《剑指offer》---把数组排成最小的数

本文算法使用python3实现


1 题目描述:

  输入一个正整数数组,把数组里所有数字拼接起来排成一个数,打印能拼接出的所有数字中最小的一个。例如输入数组 $ [3,32,321] $ ,则打印出这三个数字能排成的最小数字为 $ 321323 $ 。
  时间限制:1s;空间限制:32768K


2 思路描述:

  大致思路
  (1)我们可以先思考只有两个数字的情况: $ [3,32] $ ,可以看出来 $ 332 > 323 $ 因此需要把数组改变为 $ [32,3] $ ;
  (2)对于有三个数字的情况: $ [3,32,321] $ 我们两两进行比较, $ 332 > 323 $ 于是,将 $ 3 $ 与 $ 32 $ 交换位置变成 $ [32,3,321] $ 而 $ 3321 > 3213 $ 于是将 $ 3 $ 与 $ 321 $ 继续交换位置到 $ [32,321,3] $ ;接着我们继续使用 $ 32 $ 进行比较,由于 $ 32321 > 32132 $ 将 $ 32 与 321 $ 进行位置交换为 $ [321,32,3] $ 此时,将数组链接起来变成 $ 321323 $ 即为最小的数。
  具体思路
  (1)先将数字列表转化成字符串链表,这样便于在一个字符串后面直接加上另外一个字符串。也就是 $ "3" + "321" = "3321" $ 。
  (2)构造一个比较函数,当 $ str1 + str2 > str2 + str1 $ 时我们认为字符串 $ str1 > str2 $ 。
  (3)将字符串列表按照比较函数的规定进行冒泡排序(或其它方法排序),将定义为”大”的字符串放到最后。而”小”的字符串放在前面。最后将字符串列表链接起来,便是所求。
  注意:在python2.x中可直接对 sort() 函数进行比较函数cmp的传参,可以利用sort()函数直接对字符串列表进行排序。但是,对于python3.x取消了sort()函数中的cmp参数


3 程序代码:

(1)方法一:

class Solution:
	def theMax(self, str1, str2):
		'''定义字符串比较函数'''
		return str1 if str1+str2 > str2+str1 else str2

	def PrintMinNumber(self, numbers):
		"""使用冒泡进行排序(把最大的放最后)"""
		string = [str(num) for num in numbers]
		res = []
		flag = True
		count = len(string) - 1
		while flag and  count > 0:
			flag = False
			for i in range(len(string)-1):
				if self.theMax(string[i], string[i+1]) == string[i]:
					temp = string[i]
					del string[i]
					string.insert(i+1, temp)
					flag = True
			count -= 1
		string = ''.join(string)
		return string

(3)方法二(仅python2.x可用):

class Solution:
	def cmp(self, a, b):
		'''定义比较函数'''
		ab = int(a+b)
		ba = int(b+a)
		return 1 if ab > ba else -1

	def PrintMinNumber(self, numbers):
		string = [str(num) for num in numbers]
		string.sort(self.cmp, reverse=True)
		return ''.join(string)

posted @ 2018-06-09 13:16  EEEEEcho  阅读(5374)  评论(0编辑  收藏  举报