简体   繁体   English

使用来自代码战的相同数字集优化下一个更大的数字

[英]Optimization for next greater number with same set of digits from code wars

Link to kata on Сodewars 链接到 Сodewars 上的 kata

Task is to find the next greater number that has same digits.任务是找到具有相同数字的下一个更大的数字。

So, here are some samples:所以,这里有一些示例:

Input:  n = "218765"
Output: "251678"

Input:  n = "1234"
Output: "1243"

Input: n = "4321" 
Output: "Not Possible"

Input: n = "534976"
Output: "536479"

Samples were taken from geeks for geeks样本取自极客的极客

def next_bigger(n):
if len(str(n)) == 1:
    return -1
else:
    pass
k = math.factorial(len(str(n)))
lst2 = []
lst3 = []
lst4 = []
for num in str(n):
    lst2.append(num)
for num in lst2:
    if lst2.count(num) == len(lst2):
        return -1
    else:
        pass
for num in lst2:
    if lst2.count(num) > 1 and num not in lst4:
        k = k/math.factorial(lst2.count(num))
        lst4.append(num)
    else:
        pass

while True:
    shuffle(lst2)
    if int(''.join(lst2)) not in lst3:
        lst3.append(int(''.join(lst2)))
        print(len(lst3))
        pass
    if int(''.join(lst2)) in lst3:
        if len(lst3) == k:
            break
        else:
            pass
t = sorted(lst3)
for num in t:
    if num > n:
        return num
    else:
        pass
return -1

My code seems to work, but it runs into timeout.我的代码似乎可以工作,但它会超时。 First, code checks for corner solutions like n = 1111 or n = 3 Second, it uses combinatorics to determine how many combinations are available to get from the given number.首先,代码检查角解,例如n = 1111n = 3其次,它使用组合来确定可以从给定数字中获得多少组合。 Third, it shuffles numbers to get all available combinations and adds them to the list.第三,它会随机排列数字以获取所有可用的组合并将它们添加到列表中。 From there it just gets the next number from the given one or returns -1.从那里它只是从给定的数字中获取下一个数字或返回-1。

It seem to work with all samples.它似乎适用于所有样本。

Is it possible to somehow optimize this way of solving this problem ?是否有可能以某种方式优化这种解决这个问题的方式?

With Python everything is possible :)使用 Python 一切皆有可能:)

you can do something like this你可以做这样的事情

def next_greater_number(n):
    n_s = str(n)
    N = len(n_s)
    min_digit = int(n_s[-1])
    min_digit_idx = N-1

    left_side = n_s
    right_side = ''

    for i in range(len(n_s)-1, 0, -1):
        left_side = left_side[:i]
        right_side = n_s[i] + right_side
        # print(left_side, right_side)

        # keep record of minimum number  
        if int(n_s[i]) < min_digit:
            min_digit_idx = i
            min_digit = int(n_s[i])

        # get to the point where right digit is greater than left digit
        if int(n_s[i]) > int(n_s[i-1]):
            # exclude min digit, because we will append it on the left side
            right_side = n_s[i:min_digit_idx] + n_s[min_digit_idx+1:] + left_side[-1]        
            right_side = ''.join(sorted(right_side))
            output = left_side[:-1] + str(min_digit) + right_side
            break
    else:
        output = "Not Possible"
    return output

By traversing right to left looking for a pattern where right side digit is greater than the left digit.通过从右到左遍历寻找右侧数字大于左侧数字的模式。 We need to replace minimum of the right side with left side last digit.我们需要用左侧最后一位数字替换右侧的最小值。 After that sorting the right side makes number just greater than current number.之后,右侧的排序使数字刚好大于当前数字。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM