多个数排列形成最大值

数排列形成最大值

标签(空格分隔): 编程题


题目

已知有一些数(大小不限定,不一定为个位数),如何将这些数排列在一起构成的数值最大?

分析

针对这个题目,最简单的办法就是通过全排列来查找最大值,不过我们可以看到依次选择最大的字面数来从左到右构成数即可保证最大值(因为所有能够形成的数的位数都是一样的,从左到右依次比较肯定能够满足最大),由于在从左到右依次选择时可能出现多条路径,因此需要考虑多种可能。

解答

def get_max_num(numbers):
    """
    对一些数字寻找最大排列
    """
    str_numbers =[str(i) for i in numbers]
    digit_num = sum(len(i) for i in str_numbers)
    seqs = [NumChooseSeq('', '', str_numbers)]

    #每次选择添加一个数位,因此需要执行数字位数次数
    for _ in range(digit_num):
        new_seqs = []
        for seq in seqs:
            new_seqs += list(seq.choose_next())

        #比较小的结果去掉
        max_num = max(i.curr_num for i in new_seqs)
        new_seqs = [i for i in new_seqs if i.curr_num == max_num]

        seqs = new_seqs

    return int(seqs[0].curr_num)


class NumChooseSeq():
    """
    辅助类,用以记录各种不同的排列
    """
    def __init__(self, curr_num, follow, unused):
        self.curr_num = curr_num
        self.unused = unused
        self.follow = follow #用以记录多位数选取了部分,剩余的部分

    def choose_next(self):
        if self.follow:
            yield NumChooseSeq(self.curr_num+self.follow[0], self.follow[1:], self.unused)
        else:
            max_num = max(i[0] for i  in self.unused)
            for index,num_ in enumerate(self.unused):
                if num_[0] == max_num:
                    rest = self.unused[:index] + self.unused[index+1:]
                    yield NumChooseSeq(self.curr_num+num_[0], num_[1:], rest)

    def show(self):
        print('curr', self.curr_num, 'follow',self.follow, 'unused', self.unused)

def test():
    assert(get_max_num([1,2,3]) == 321)
    assert(get_max_num([1,10,1]) == 1110)
    assert(get_max_num([958,9,5,6]) == 995865)
    assert(get_max_num([30,31,3,2]) == 331302)

if __name__ == '__main__':
    test()
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值