繁体   English   中英

详细解释“相邻位数绝对差不超过K的N位数字的计数”的逻辑

[英]Explain the logic of 'Count of N-digit numbers with absolute difference of adjacent digits not exceeding K' in Detail

有人可以帮我理解以下动态编程问题的逻辑在 geeksforgeeks.com 找到这个问题。 即使经过提供的答案,我也无法理解。

问题:

相邻位数绝对差不超过K的N位数个数| 设置 2

给定两个整数 N 和 K,任务是找到 N 位数字的计数,使得该数字中相邻数字的绝对差不大于 K。

例子:

输入:N = 2,K = 1

Output:26

解释: 数字是 10, 11, 12, 21, 22, 23, 32, 33, 34, 43, 44, 45, 54, 55, 56, 65, 66, 67, 76, 77, 78, 87, 88 , 89, 98, 99

输入:N = 3,K = 2

Output:188

Python3解决方案:

# Function to return the count of such numbers 
def getCount(n, K): 
    # For 1-digit numbers, the count is 10 irrespective of K 
    if(n == 1): 
        return 10

    # dp[j] stores the number of such i-digit numbers ending with j 
    dp = [0] * 11

    # Stores the results of length i 
    next = [0] * 11

    # Initialize count for 1-digit numbers 
    for i in range(1, 9 + 1): 
        dp[i] = 1

    # Compute values for count of digits greater than 1 
    for i in range(2, n + 1): 
        for j in range(9 + 1): 
            # Find the range of allowed numbers if last digit is j 
            l = max(0, j - k) 
            r = min(9, j + k) 

            # Perform Range update 
            next[l] += dp[j] 
            next[r + 1] -= dp[j] 

        # Prefix sum to find actual count of i-digit numbers ending with j 
        for j in range(1, 9 + 1): 
            next[j] += next[j - 1] 

        # Update dp[] 
        for j in range(10): 
            dp[j] = next[j] 
            next[j] = 0

    # Stores the final answer 
    count = 0
    for i in range(9 + 1): 
        count += dp[i] 

    return count 


if __name__ == '__main__': 
    n = 2
    k = 1
    print(getCount(n, k)) 

此代码由 Shivam Singh 提供

链接: https://www.google.com/amp/s/www.geeksforgeeks.org/count-of-n-digit-numbers-with-absolute-difference-of-adjacent-digits-not-exceeding-k-设置 2/amp/

我无法理解以下几行的逻辑

# Compute values for count of 

# digits greater than 1 

for i in range(2, n + 1): 

    for j in range(9 + 1): 



        # Find the range of allowed 

        # numbers if last digit is j 

        l = max(0, j - k) 

        r = min(9, j + k) 



        # Perform Range update 

        next[l] += dp[j] 

        next[r + 1] -= dp[j] 



    # Prefix sum to find actual count 

    # of i-digit numbers ending with j 

    for j in range(1, 9 + 1): 

        next[j] += next[j - 1] 



    # Update dp[] 

    for j in range(10): 

        dp[j] = next[j] 

        next[j] = 0

N=2所以我们正在处理严格的 2 位数字

K=1 ,因此当前数字中的每个数字应比其相邻数字大或小不超过 1 个数字

虽然答案是26 (这些数字的计数),但让我们看看为什么答案包括101112而不是13

10是好的,因为1 - 010的数字)的绝对值小于或等于1K的值)

13不好,因为1 - 3的绝对值为22大于K

请注意,随着N的增加,所需的成对数字比较的数量也会增加。

我将跳过用无意义的变量名解析别人的代码。 以下是我可能尝试解决的方法:

def is_valid_number(number_to_test, allowed_digit_spread):
    if number_to_test < 10:
        # apparently all 1 digit numbers pass
        return True

    # get the individual digits as a list
    digits = [int(digit) for digit in str(number_to_test)]

    for i in range(1, len(digits)):
        current_digit = digits[i]
        prior_digit = digits[i-1]
        if abs(current_digit - prior_digit) > allowed_digit_spread:
            # bad pairwise compare so reject
            return False

    return True

def get_numbers_to_test(allowed_digits):
    start = pow(10, allowed_digits -1)
    end = pow(10, allowed_digits)
    return range(start, end)

def getCount(allowed_digits, allowed_digit_spread):
    count = 0
    for n in get_numbers_to_test(allowed_digits):
        if is_valid_number(n, allowed_digit_spread):
            count += 1
    return count

if __name__ == '__main__':
    n = 2
    k = 1
    print(getCount(n, k))

暂无
暂无

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

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