LeetCode Largest Number
Posted gavinfish
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了LeetCode Largest Number相关的知识,希望对你有一定的参考价值。
LeetCode解题之Largest Number
原题
给定一组非负整数,将这些整数拼接成最大的数字。由于返回的数字可能非常大,直接返回字符串。
注意点:
- 无
例子:
输入: nums = [3, 30, 34, 5, 9]
输出: ‘9534330’
解题思路
要将这些数字拼接起来,其实就是要规定好这些数字出现的先后顺序,所以我们要对这些数字进行排序。直接比较数字的大小是行不通的,如12和121,虽然121>12,但是12121>12112。应有的排序规则应该是如果AB>BA,那么我们规定A>B,也就是最后拼接时A放在B之前。这个方案看着有点道理,而且也是正确的,但要证明按照这种排序得到的数字是最大的比较困难。
以下证明参考自@19thhell。主要要说名两点,一是这种比较关系具有传递性,第二是按照这样的拼接顺序得到的数是最大的。
首先,通过证明传递性可以帮我得到所有数的大小关系:
为了方便表示,定义f(X) = 10^(lgX + 1), (lgX + 1)表示X有多少位,所以AB = f(B)A + B
假设 A <· B, B <· C (<·是为了与一般的小于号区分)
即 AB < BA, BC < CB
因为 AB < BA
f(B)A + B < f(A)B + A
(f(B) - 1)A < (f(A) - 1)B
A < B·(f(A) - 1) / (f(B) - 1) (1)
因为 BC < CB
f(C)B + C < f(B)C + B
(f(C) - 1)B < (f(B) - 1)C
B < C·(f(B) - 1) / (f(C) - 1) (2)
结合 (1), (2),
A < C·(f(A) - 1) / (f(C) - 1)
(f(C) - 1)A < (f(A) - 1)C
f(C)A + C < f(A)C + A
AC < CA
即得到了A <· C
根据传递性可以得到按照上面的比较规则排序后的数字满足A1 ·> A2·> ... ·> A(n-1)
下面证明A1A2…A(n-1)是这些数能够拼接成的最大的数字。
如果A < B,那么我们容易得到CAD < CBD(这里是一般的大小关系) (3)
因为 A1 ·> A2·> ... ·> A(n-1)
所以 A1Aj > AjA1, 再根据(3)有以下的大小关系
(A1B)C...N > (BA1)C...N
B(A1C)...N > B(CA1)...N -> A1BC...N > BCA1...N
...
... -> A1BC...N > BCA...NA1
也就是说A1放在第一个位置相对于把它放在其他的位置时,拼接出来的数字大。同理我们也可以推断出A2应该放在第二位......
综上所述,我们通过将数字按照上述方法排序后再拼接就可以得到最大的数字。还有需要注意的是可能参数是多个0,此时字符串拼接的结果是一串0,不符合常规的表达方法,要将其改为0。
AC源码
from functools import cmp_to_key
class Solution:
# @param {integer[]} nums
# @return {string}
def largestNumber(self, nums):
sorted_nums = sorted(map(str, nums), key=cmp_to_key(lambda x, y: int(y + x) - int(x + y)))
result = ‘‘.join(sorted_nums).lstrip(‘0‘)
return result or ‘0‘
if __name__ == "__main__":
assert Solution().largestNumber([3, 30, 34, 5, 9]) == ‘9534330‘
assert Solution().largestNumber([0, 0]) == ‘0‘
欢迎查看我的Github (https://github.com/gavinfish/LeetCode-Python) 来获得相关源码。
以上是关于LeetCode Largest Number的主要内容,如果未能解决你的问题,请参考以下文章