📌  相关文章
📜  相邻数字绝对差不超过K的N位数字的计数| 2套

📅  最后修改于: 2021-09-22 10:39:51             🧑  作者: Mango

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

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

  • 在上述方法中,二维数组dp[][]被初始化,其中dp[i][j]存储具有i位数字并以j结尾的数字的计数。
  • 可以观察到,任何长度i的答案仅取决于为i – 1生成的计数。因此,不是二维数组,而是初始化所有可能数字大小的数组 dp[] ,并且对于每个iNdp[j]存储长度i以数字j结尾的此类数字的计数。
  • 初始化另一个数组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.


C++
// C++ Program to implement
// the above approach
#include 
using namespace std;
 
// 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;
    cout <<  getCount(n, k);
 
    return 0;
}


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


Javascript


输出:
26

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

如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程学生竞争性编程现场课程