剑指offer 45 - 把数组排成最小的数 - python

434 阅读1分钟

题目描述:

输入一个正整数数组,把数组里所有数字拼接起来排成一个数,打印能拼接出的所有数字中最小的一个。例如输入数组{3,32,321},则打印出这三个数字能排成的最小数字为321323。

思路:

将数组中的排列成一个最小(大)的数的基本思路是:首先将数组中的元素转换为字符串,然后看字符串拼接后的结果的大小关系。如3和32,转换成字符拼接后有两种结果: ′ 3 ’ + ′ 3 2 ′ '3’+'32' ′3’+′32′ 和 ′ 3 2 ′ + ′ 3 ′ '32' + '3' ′32′+′3′,因为 323 < 332 323 < 332 323<332,所以32必然在3前面,依次类推,最后返回数组中元素拼接后的结果。

为了保证结果不溢出,可将数组中元素拼接后的结果转换为int后再转换为str输出。

  • 法1: 创建数组r存放排列后的结果,首先将原数组首元素放入,然后遍历数组中剩下的元素 n u m num num与 r i r_{i} ri​中元素进行比较

    • 如果 n u m < r i num < r_{i} num<ri​,将其插入到 r i r_{i} ri​前面,更新 r r r;否则继续往后比较
    • 如果必到最后没有在 r r r中找到满足的要求的元素,则将其添加到 r r r后面
  • 法2: 利用python中内置list的排序函数sort(),它需要定义比较规则,然后利用sort函数对字符串进行排序。


AC代码

法1

# -*- coding:utf-8 -*-
class Solution:
    def PrintMinNumber(self, numbers):
        # write code here
        if numbers == []:
            return ""
        
        r = [numbers[0]]
        for i in numbers[1:]: 
            for id in range(len(r)):
                if int(str(i) + str(r[id])) < int(str(r[id]) + str(i)):
                    r.insert(r.index(r[id]), i)
                    break
                elif id == len(r) - 1:
                    r.append(i)

        return int(''.join(str(x) for x in r))
    

法2

class Solution:
    def minNumber(self, nums: List[int]) -> str:
        def sort_rule(x, y):
            a, b = x + y, y + x
            if a > b: return 1
            elif a < b: return -1
            else: return 0
        
        strs = [str(num) for num in nums]
        strs.sort(key = functools.cmp_to_key(sort_rule))
        return ''.join(strs)
   

回溯法在LeetCode上会超出时间限制 -_-

# -*- coding:utf-8 -*-
class Solution:
    def minNumber(self, nums: List[int]) -> str:
        if not nums: return ''
        res = []
        l = len(nums)
        def find(nums, path, index = 0):
            if index == l:
                t = path[:]
                res.append(''.join(t))
                return

            for i in range(len(nums)):
                path.append(str(nums[i]))
                find(nums[:i] + nums[i + 1:], path, index + 1)
                path.pop()

        find(nums, [], 0)
        res.sort()
        return res[0]