[英]Using permutations to find the next biggest number
创建一个函数,它接受一个正整数并返回可以通过重新排列其数字形成的下一个更大的数字。
为此,我使用了以下代码:
使用的逻辑:
代码块:
import itertools
def next_bigger(n):
# [int(x) for x in str(n)] ex: convert 123 to array [1,2,3]
# list(set(itertools.permutations... gives you a list of permutation e.g. [[1,3,2],[3,2,1],[2,3,1],...]
# [int(''.join(map(str,x))) for x in ... converts each permuted list into a number e.g. convert [2,3,1] -> 231
# for num in sorted(...if num>n: --> if 321 is bigger than 123, return it
for num in sorted([int(''.join(map(str,x))) for x in list(set(itertools.permutations([int(x) for x in str(n)])))]):
if num>n:
return num
else:
return -1
预期输出:
nextBigger(num: 12) // returns 21
nextBigger(num: 513) // returns 531
nextBigger(num: 2017) // returns 2071
nextBigger(num: 9) // returns nil
nextBigger(num: 111) // returns nil
nextBigger(num: 531) // returns nil
实际输出: Test results fail
解决方案尝试#2:
import itertools
def next_bigger(n):
# [int(x) for x in str(n)] ex: convert 123 to array [1,2,3]
# list(set(itertools.permutations... gives you a list of permutation e.g. [[1,3,2],[3,2,1],[2,3,1],...]
# [int(''.join(map(str,x))) for x in ... converts each permuted list into a number e.g. convert [2,3,1] -> 231
# for num in sorted(...if num>n: --> if 321 is bigger than 123, return it
a = []
results = 0
for num in sorted([int(''.join(map(str,x))) for x in list(set(itertools.permutations([int(x) for x in str(n)])))]):
if num>n:
a.append(num)
results = a[0]
return results
预期输出:通过除长数字以外的所有测试用例
我的代码有什么问题?
标题说“使用排列”,但您不需要为此使用排列。
定义了发出的元组itertools.permutations的顺序; 但不幸的是,它并不总是产生组合时按递增顺序排列的数字。 如果位数非常大,计算所有排列也将花费非常长的时间。
重新表述这个问题:对于任何给定的N
,最小的数字 ( N2
) 是多少,使得:
0 <= N < N2
,和N
和N2
中出现的次数相同 (如果N2
不存在,则返回None
)
我们可以从N
开始,做N+=1
直到满足条件 2,或者直到条件 2 不再满足,因为N
的总位数增加了。 (Python 3 中的int
没有定义它可以有多大的限制,所以我们不会发生溢出。)如果N
非常大,这仍然(平均而言)非常慢,但理论上它最终会返回。
这是我将如何解决这个问题:
def main(N):
n=list(map(int,str(N)))
for i_r in reversed(range(len(n))):
for i_l in reversed(range(i_r)):
if n[i_l]<n[i_r]:
t_l=n[i_l]
t_r=n[i_r]
n[i_l]=t_r
n[i_r]=t_l
return int(''.join(map(str,n)))
return None
首先将N
转换为数字列表(同时保留顺序)。 这将使N
更容易处理。
制作 2 个标记i_l
和i_r
。 i_l
和i_r
将始终分别位于左侧和右侧。 它们将从N
的最不重要(即右侧)一侧开始。
例如,他们将像这样通过N
:
4321 4321 4321 4321 4321 4321
lr l r l r lr l r lr
当i_l < i_r
,交换这些数字以形成一个更大的数字,满足条件 1。由于i_l
和i_r
从N
的最低有效侧开始,新数字是满足条件 2 的最小数字。如果该数字不满足存在,该函数返回None
。
( return None
实际上是不必要的,因为函数默认返回None
,但是明确说明它可以更清楚地表明这是预期的行为。)
使用此解决方案,即使N
是 10000 位数字,该函数也会在合理的时间内返回。
您需要下一个最大的数字,但目前您选择any
大于输入数字的排列数字。 You should be the picking the minimum among such numbers
还要注意,例如输入9
或111
; 没有其他排列; 所以你可能只想返回next biggest-permutation or None
。
您可以考虑修改为:
import itertools
def next_bigger(n):
# [int(x) for x in str(n)] ex: convert 123 to array [1,2,3]
# list(set(itertools.permutations... gives you a list of permutation e.g. [[1,3,2],[3,2,1],[2,3,1],...]
# [int(''.join(map(str,x))) for x in ... converts each permuted list into a number e.g. convert [2,3,1] -> 231
# for num in sorted(...if num>n: --> if 321 is bigger than 123, return it
minval = -1
for num in sorted([int(''.join(map(str,x))) for x in list(set(itertools.permutations([int(x) for x in str(n)])))]):
if num>n:
if minval == -1 or minval > num:
minval = n
return minval
适当的测试用例:
nextBigger(num: 1176) //should return 1617
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.