📜  N位数的计数,相邻位数的绝对差不超过K |套装2

📅  最后修改于: 2021-05-06 07:57:49             🧑  作者: Mango

给定两个整数NK ,任务是找到N位数字的计数,以使数字中相邻数字的绝对差不大于K。
例子:

天真的方法和动态规划方法:最简单的解决方案和需要O(N)辅助空间的动态规划方法,是指相邻位数的绝对差不超过K的N位数字的计数。
节省空间的方法:
请按照以下步骤优化上述方法:

  • 在以上方法中,初始化了2D数组dp [] [] ,其中dp [i] [j]存储具有i个数字并以j结尾的数字的计数。
  • 可以看出,对于任何长度i的答案仅取决于为i – 1生成的计数。因此,代替2D数组,初始化大小为所有可能数字的数组dp [],对于每一个i,直到Ndp [j]存储以数字j结尾的长度为i的此类数字的计数。
  • 初始化另一个数组,该数组的所有可能位数的大小为next []
  • 由于以值j结束的一位数字的计数始终为1 ,因此最初在所有索引处用1填充dp []
  • 迭代范围[2,N] ,对于范围i中的每个值,检查最后一位是否为j ,则该位置允许的位数在(max(0,jk),min(9, j + k)) 。执行范围更新:
  • 对于特定的i值完成上述步骤后,计算next []的前缀总和,并用next []的值更新dp []

下面是上述方法的实现:

C
// C program to implement the above approach
#include 
  
// Function to find maximum between two numbers
int max(int num1, int num2)
{
    return (num1 > num2 ) ? num1 : num2;
}
  
// Function to find minimum between two numbers
int min(int num1, int num2) 
{
    return (num1 > num2 ) ? num2 : num1;
}
  
// Function to return the count
// of such numbers
int getCount(int n, int 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
    int dp[11] = {0};
  
    // Stores the results of length i
    int next[11] = {0};
          
    // Initialize count for
    // 1-digit numbers
    for(int i = 1; i <= 9; i++)
        dp[i] = 1;
  
    // Compute values for count of
    // digits greater than 1
    for(int i = 2; i <= n; i++)
    {
        for(int j = 0; j <= 9; j++) 
        {
  
            // Find the range of allowed
            // numbers if last digit is j
            int l = max(0, (j - k));
            int 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(int j = 1; j <= 9; j++)
            next[j] += next[j - 1];
  
        // Update dp[]
        for(int j = 0; j < 10; j++) 
        {
            dp[j] = next[j];
            next[j] = 0;
        }
    }
  
    // Stores the final answer
    int count = 0;
    for(int i = 0; i <= 9; i++)
        count += dp[i];
  
    // Return the final answer
    return count;
}
  
// Driver Code
int main()
{
    int n = 2, k = 1;
    printf("%d", getCount(n, k));
}
  
// This code is contributed by piyush3010.


Java
// Java Program to implement
// the above approach
import java.util.*;
class GFG {
  
    // Function to return the count
    // of such numbers
    public static long getCount(
        int n, int 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
        long dp[] = new long[11];
  
        // Stores the results of length i
        long next[] = new long[11];
  
        // Initialize count for
        // 1-digit numbers
        for (int i = 1; i <= 9; i++)
            dp[i] = 1;
  
        // Compute values for count of
        // digits greater than 1
        for (int i = 2; i <= n; i++) {
            for (int j = 0; j <= 9; j++) {
  
                // Find the range of allowed
                // numbers if last digit is j
                int l = Math.max(0, j - k);
                int r = Math.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 (int j = 1; j <= 9; j++)
                next[j] += next[j - 1];
  
            // Update dp[]
            for (int j = 0; j < 10; j++) {
                dp[j] = next[j];
                next[j] = 0;
            }
        }
  
        // Stores the final answer
        long count = 0;
        for (int i = 0; i <= 9; i++)
            count += dp[i];
  
        // Return the final answer
        return count;
    }
  
    // Driver Code
    public static void main(String[] args)
    {
        int n = 2, k = 1;
        System.out.println(getCount(n, k));
    }
}


Python3
# Python3 program to implement
# the above approach
  
# 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 the final answer
    return count
  
# Driver code
if __name__ == '__main__':
  
    n = 2
    k = 1
      
    print(getCount(n, k))
  
# This code is contributed by Shivam Singh


C#
// C# program to implement
// the above approach
using System;
  
class GFG{
  
// Function to return the count
// of such numbers
public static long getCount(int n, int 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
    long []dp = new long[11];
  
    // Stores the results of length i
    long []next = new long[11];
  
    // Initialize count for
    // 1-digit numbers
    for(int i = 1; i <= 9; i++)
        dp[i] = 1;
  
    // Compute values for count of
    // digits greater than 1
    for(int i = 2; i <= n; i++)
    {
        for(int j = 0; j <= 9; j++)
        {
              
            // Find the range of allowed
            // numbers if last digit is j
            int l = Math.Max(0, j - k);
            int r = Math.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(int j = 1; j <= 9; j++)
            next[j] += next[j - 1];
  
        // Update []dp
        for(int j = 0; j < 10; j++) 
        {
            dp[j] = next[j];
            next[j] = 0;
        }
    }
  
    // Stores the readonly answer
    long count = 0;
    for(int i = 0; i <= 9; i++)
        count += dp[i];
  
    // Return the readonly answer
    return count;
}
  
// Driver Code
public static void Main(String[] args)
{
    int n = 2, k = 1;
    Console.WriteLine(getCount(n, k));
}
}
  
// This code is contributed by amal kumar choubey


输出:
26

时间复杂度: O(N)
辅助空间: O(1)