📜  手机数字键盘问题|套装2

📅  最后修改于: 2021-04-22 02:21:28             🧑  作者: Mango

给定移动数字小键盘。您只能按向上,向左,向右或向下按当前按钮的按钮,也可以选择再次按同一按钮。圆角按钮(即*和#)是无效的动作。

手机键盘

给定一个数字N ,您必须找到一个可以拨打的长度为N的不同数字,方法是从0-9范围内的任何数字开始,在只能按所按的最后一个数字向上,向左,向右或向下移动的限制下,或者您可以选择再次按下相同的按钮。

例子:

方法:我们在这里看到了许多解决此问题的解决方案。

X n i为以i结尾的n个数字的计数。
因此,通过这种表示法,

中心思想是,如果您知道X n i ,则可以获得有关X n + 1 j的哪些信息。

让我们看一个例子:

我们可以看到,进行任何可能的移动,每次移动都会得到相同大小的集合。即,在两位数字的集合中有3个以1结尾的元素,我们从1开始的每一个可能移动都具有相同大小(3)的集合。

因此,可以看出X 2 1贡献了3位数字,如下所示:

因此,通常,如果我们知道X n i ,我们就知道它对X n + 1 j的贡献,其中j是从i开始的每一个可能的移动。

      \[{X_{n+1}}^{i} = \sum {X_{n}}^{j}\]

其中0 <= j <= 9并且从j我们可以得到一个有效的到i

这个想法是首先枚举每个给定键的所有可能方向,并维护一个由10个元素组成的数组,其中每个索引处的元素都存储以该索引结尾的数字的计数。

例如,数组的初始值为:

n = 1的初始结果是数组中所有元素的总和,即1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 = 10,可以拨打10个1位数。

如何更新n> 1的数组?

让我们首先列举所有给定数字的所有方向:

上面所列表格的第一行表示,如果数字的最后一位为零,我们可以移至0或8。

让我们详细看一下N = 2的方法

下面是上述方法的实现:

C++
// C++ implementation of the approach
#include 
#include 
using namespace std;
#define MAX 10
  
// Function to return the count of numbers possible
int getCount(int n)
{
    // Array of list storing possible direction
    // for each number from 0 to 9
    // mylist[i] stores possible moves from index i
    list mylist[MAX];
  
    // Initializing list
    mylist[0].assign({ 0, 8 });
    mylist[1].assign({ 1, 2, 4 });
    mylist[2].assign({ 2, 1, 3, 5 });
    mylist[3].assign({ 3, 6, 2 });
    mylist[4].assign({ 4, 1, 7, 5 });
    mylist[5].assign({ 5, 4, 6, 2, 8 });
    mylist[6].assign({ 6, 3, 5, 9 });
    mylist[7].assign({ 7, 4, 8 });
    mylist[8].assign({ 8, 5, 0, 7, 9 });
    mylist[9].assign({ 9, 6, 8 });
  
    // Storing values for n = 1
    int Arr[MAX] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 };
  
    for (int i = 2; i <= n; i++) {
  
        // To store the values for n = i
        int Arr2[MAX] = { 0 };
  
        // Loop to iterate throuh each index
        for (int j = 0; j < MAX; j++) {
  
            // For each move possible from j
            // Increment the value of possible
            // move positions by Arr[j]
            for (int x : mylist[j]) {
                Arr2[x] += Arr[j];
            }
        }
  
        // Update Arr[] for next iteration
        for (int j = 0; j < MAX; j++)
            Arr[j] = Arr2[j];
    }
  
    // Find the count of numbers possible
    int sum = 0;
    for (int i = 0; i < MAX; i++)
        sum += Arr[i];
  
    return sum;
}
  
// Driver code
int main()
{
    int n = 2;
  
    cout << getCount(n);
  
    return 0;
}


Java
// Java implementation of the approach
class GFG
{
    static int MAX = 10;
  
    // Function to return the count of numbers possible
    static int getCount(int n)
    {
        // Array of list storing possible direction
        // for each number from 0 to 9
        // list[i] stores possible moves from index i
          
        int [][] list = new int[MAX][];
          
        // Initializing list
        list[0] = new int [] { 0, 8 };
        list[1] = new int [] { 1, 2, 4 };
        list[2] = new int [] { 2, 1, 3, 5 };
        list[3] = new int [] { 3, 6, 2 };
        list[4] = new int [] { 4, 1, 7, 5 };
        list[5] = new int [] { 5, 4, 6, 2, 8 };
        list[6] = new int [] { 6, 3, 5, 9 };
        list[7] = new int [] { 7, 4, 8 };
        list[8] = new int [] { 8, 5, 0, 7, 9 };
        list[9] = new int [] { 9, 6, 8 };
      
        // Storing values for n = 1
        int Arr[] = new int [] { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 };
      
        for (int i = 2; i <= n; i++) 
        {
      
            // To store the values for n = i
            int Arr2[] = new int [MAX];
      
            // Loop to iterate throuh each index
            for (int j = 0; j < MAX; j++)
            {
      
                // For each move possible from j
                // Increment the value of possible
                // move positions by Arr[j]
                for (int x = 0; x < list[j].length; x++)
                {
                    Arr2[list[j][x]] += Arr[j];
                }
            }
      
            // Update Arr[] for next iteration
            for (int j = 0; j < MAX; j++)
                Arr[j] = Arr2[j];
        }
      
        // Find the count of numbers possible
        int sum = 0;
        for (int i = 0; i < MAX; i++)
            sum += Arr[i];
      
        return sum;
    }
      
    // Driver code
    public static void main (String[] args) 
    {
      
        int n = 2;
      
        System.out.println(getCount(n));
    }
}
  
// This code is contributed by ihritik


C#
// C# implementation of the approach
using System;
  
class GFG
{
    static int MAX = 10;
  
    // Function to return the count of numbers possible
    static int getCount(int n)
    {
        // Array of list storing possible direction
        // for each number from 0 to 9
        // list[i] stores possible moves from index i
        int [][] list = new int[MAX][];
          
        // Initializing list
        list[0] = new int [] { 0, 8 };
        list[1] = new int [] { 1, 2, 4 };
        list[2] = new int [] { 2, 1, 3, 5 };
        list[3] = new int [] { 3, 6, 2 };
        list[4] = new int [] { 4, 1, 7, 5 };
        list[5] = new int [] { 5, 4, 6, 2, 8 };
        list[6] = new int [] { 6, 3, 5, 9 };
        list[7] = new int [] { 7, 4, 8 };
        list[8] = new int [] { 8, 5, 0, 7, 9 };
        list[9] = new int [] { 9, 6, 8 };
      
        // Storing values for n = 1
        int [] Arr = new int [] { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 };
      
        for (int i = 2; i <= n; i++) 
        {
      
            // To store the values for n = i
            int [] Arr2 = new int [MAX];
      
            // Loop to iterate throuh each index
            for (int j = 0; j < MAX; j++)
            {
      
                // For each move possible from j
                // Increment the value of possible
                // move positions by Arr[j]
                for (int x = 0; x < list[j].Length; x++)
                {
                    Arr2[list[j][x]] += Arr[j];
                }
            }
      
            // Update Arr[] for next iteration
            for (int j = 0; j < MAX; j++)
                Arr[j] = Arr2[j];
        }
      
        // Find the count of numbers possible
        int sum = 0;
        for (int i = 0; i < MAX; i++)
            sum += Arr[i];
      
        return sum;
    }
      
    // Driver code
    public static void Main () 
    {
      
        int n = 2;
      
        Console.WriteLine(getCount(n));
    }
}
  
// This code is contributed by ihritik


输出:
36

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