📌  相关文章
📜  计算不超过N的数字,其中至少包含一个重复的数字

📅  最后修改于: 2021-06-25 12:21:40             🧑  作者: Mango

给定整数N ,任务是对小于或等于N的数字进行计数,以使每个数字至少包含一个重复的数字。

例子:

方法:请按照以下步骤解决问题:

  • 初始化一个变量,例如X ,以将数字的总计数存储在N中
  • 初始化一个变量,例如cntNumbers ,以存储小于或等于N的唯一数字组成的总数。
  • 计算包含唯一数字的X位数的总数,并更新cntNumbers 。以下是用于计算具有所有唯一数字的X位数总数的公式。
  • 计算X -数位号码的总数小于或等于n,其通过在多个的每个可能的数字检查所有可能的值包含唯一位数小于或等于N和更新cntNumbers。
  • 最后,打印(N – cntNumbers)的值。

下面是上述方法的实现:

C++
// C++ program to implement
// the above approach
#include 
using namespace std;
 
long factorial(int n)
{
    return (n == 1 || n == 0) ? 1 :
            n * factorial(n - 1); 
}
 
// Function to count arrangements to
// select K elements from N elements 
long NPR(int n, int k)
{
    return factorial(n) / factorial(n - k);
}
 
// Function to count numbers less than or equal 
// to N with at least one repeated digits
int cntNumLessThanEqualNRepeatedDigits(int N)
{
     
    // Stores the value of N
    int temp = N;
 
    // Stores count of
    // digits in N
    int X = 0;
 
    // Store all possible
    // digits of N
    vector nums;
 
    // Calculate digits in N
    while(temp)
    {
         
        // Update X
        X += 1;
 
        // Insert digits of N
        // into nums
        nums.push_back(temp % 10);
         
        // Update temp
        temp /= 10;
    }
    reverse(nums.begin(), nums.end());
     
    // Count numbers of (X)-digit
    // with no repeated digits
    int cntNumbers = 0;
 
    // Calculate count of numbers of less than
    // (X)-digit and no repeated digits
    for(int i = 1; i < X; i++)
    {
         
        // Update cntnumbers
        cntNumbers += 9 * (factorial(9) /
                           factorial(10 - i));
    }
     
    // Stores unique digits of
    // (X)-digit numbers
    unordered_set vis;
     
    // Calculate (X) digits
    // numbers with no repeated digits
    for(int i = 0; i < nums.size(); i++)
    {
         
        // Stores count of unique
        // value at i_th digit
        int k = 0;
 
        // Stores minimum possible value of
        // i_th digit of a number
        int Min = 0;
 
        // If current digit is the first
        // digit of a number
        if (i == 0)
        {
             
            // Update Min
            Min = 1;
        }
        else
        {
             
            // Update Min
            Min = 0;
        }
         
        // Stores maximum possible value of
        // i_th digit if a number   
        int Max = 0;
 
        // If current digit is the last
        // digit of a number
        if (i == X - 1)
        {
             
            // Update Max
            Max = nums[i];
        }
        else
        {
             
            // Update Max
            Max = nums[i] - 1;
        }
             
        // Iterate over all possible value
        // of current digit
        for(int j = Min; j <= Max; j++)
        {
             
            // If value of current digit
            // already occurred in vis
            if (vis.find(j) != vis.end())
            {
                continue;
            }
                 
            // Update k
            k += 1;
        }
         
        // Update cntNumbers
        cntNumbers += k * (NPR(9 - i,
                      X - i - 1));
 
        // If current value of i-th digit
        // already occurred in vis             
        if (vis.find(nums[i]) != vis.end())
        {
            break;
        }
         
        // Insert val in vis
        vis.insert(nums[i]);
    }
     
    // Return total count of numbers less
    // than or equal to N with repetition
    return (N - cntNumbers);
}
 
// Driver Code
int main()
{
    int N = 100;
 
    cout << cntNumLessThanEqualNRepeatedDigits(N);
     
    return 0;
}
 
// This code is contributed by Manu Pathria


Java
// Java program to implement
// the above approach
import java.io.*;
import java.util.*;
 
class GFG{
     
public static int factorial(int n)
{
    return (n == 1 || n == 0) ? 1 :
            n * factorial(n - 1); 
}
 
// Function to count arrangements to
// select K elements from N elements 
public static int NPR(int n, int k)
{
    return factorial(n) / factorial(n - k);
}
 
// Function to count numbers less than or equal 
// to N with at least one repeated digits
public static int cntNumLessThanEqualNRepeatedDigits(int N)
{
     
    // Stores the value of N
    int temp = N;
 
    // Stores count of
    // digits in N
    int X = 0;
 
    // Store all possible
    // digits of N
    List nums = new ArrayList<>();
     
    // Calculate digits in N
    while (temp > 0)
    {
         
        // Update X
        X += 1;
 
        // Insert digits of N
        // into nums
        nums.add(temp % 10);
         
        // Update temp
        temp /= 10;
    }
    Collections.reverse(nums);
     
    // Count numbers of (X)-digit
    // with no repeated digits
    int cntNumbers = 0;
 
    // Calculate count of numbers of less than
    // (X)-digit and no repeated digits
    for(int i = 1; i < X; i++)
    {
         
        // Update cntnumbers
        cntNumbers += 9 * (factorial(9) /
                           factorial(10 - i));
    }
     
    // Stores unique digits of
    // (X)-digit numbers
    Set vis=new HashSet<>();
     
    // Calculate (X) digits
    // numbers with no repeated digits
    for(int i = 0; i < nums.size(); i++)
    {
         
        // Stores count of unique
        // value at i_th digit
        int k = 0;
 
        // Stores minimum possible value of
        // i_th digit of a number
        int Min = 0;
 
        // If current digit is the first
        // digit of a number
        if (i == 0)
        {
             
            // Update Min
            Min = 1;
        }
        else
        {
             
            // Update Min
            Min = 0;
        }
 
        // Stores maximum possible value of
        // i_th digit if a number   
        int Max = 0;
 
        // If current digit is the last
        // digit of a number
        if (i == X - 1)
        {
             
            // Update Max
            Max = nums.get(i);
        }
        else
        {
             
            // Update Max
            Max = nums.get(i) - 1;
        }
             
        // Iterate over all possible value
        // of current digit
        for(int j = Min; j <= Max; j++)
        {
             
            // If value of current digit
            // already occurred in vis
            if (vis.contains(j))
            {
                continue;
            }
                 
            // Update k
            k += 1;
        }
         
        // Update cntNumbers
        cntNumbers += k * (NPR(9 - i,
                      X - i - 1));
 
        // If current value of i-th digit
        // already occurred in vis             
        if (vis.contains(nums.get(i)))
        {
            break;
        }
         
        // Insert val in vis
        vis.add(nums.get(i));
    }
     
    // Return total count of numbers less
    // than or equal to N with repetition
    return (N - cntNumbers);
}
 
// Driver Code
public static void main(String[] args)
{
    int N = 100;
 
    System.out.print(
        cntNumLessThanEqualNRepeatedDigits(N));
}
}
 
// This code is contributed by Manu Pathria


Python3
# Python3 program to implement
# the above approach
 
import math
 
# Function to count arrangements to
# select K elements from N elements
def NPR(n, k):
        return (math.factorial(n) //
                math.factorial(n-k))
 
# Function to count numbers less than or equal
# to N with at least one repeated digits
def cntNumLessThanEqualNRepeatedDigits(N):
 
    # Stores the value of N
    temp = N
 
    # Stores count of
    # digits in N
    X = 0;
 
    # Store all possible
    # digits of N
    nums = []
 
    # Calculate digits in N
    while(temp):
 
        # Update X
        X += 1
 
        # Insert digits of N
        # into nums
        nums.append(temp % 10)
         
 
        # Update temp
        temp //= 10
         
 
    # Reverse nums
    nums.reverse()
 
    # Count numbers of (X)-digit
    # with no repeated digits
    cntNumbers = 0
 
    # Calculate count of numbers of less than
    # (X)-digit and no repeated digits
    for i in range(1, X):
 
        # Update cntnumbers
        cntNumbers += 9 * (math.factorial(9) //
                        math.factorial(10 - i))
 
    # Stores unique digits of
    # (X)-digit numbers
    vis = set()
 
    # Calculate (X) digits
    # numbers with no repeated digits
    for i, val in enumerate(nums):
 
        # Stores count of unique
        # value at i_th digit
        k = 0
 
        # Stores minimum possible value of
        # i_th digit of a number
        Min = 0;
 
        # If current digit is the first
        # digit of a number
        if i == 0:
 
            #Update Min
            Min = 1
        else:
 
            # Update Min
            Min = 0
 
        # Stores maximum possible value of
        # i_th digit if a number   
        Max = 0;
 
        # If current digit is the last
        # digit of a number
        if i == X - 1:
 
            # Update Max
            Max = val
        else:
             
 
            # Update Max
            Max = val - 1;
             
 
        # Iterate over all possible value
        # of current digit
        for j in range(Min, Max + 1):
 
            # If value of current digit
            # already occurred in vis
            if (j in vis):
                continue
                 
            # Update k
            k += 1
 
        # Update cntNumbers
        cntNumbers += k * (NPR(9 - i,
                      X - i - 1))
 
        # If current value of i-th digit
        # already occurred in vis             
        if val in vis:
            break
 
        # Insert val in vis
        vis.add(val)
 
    # Return total count of numbers less
    # than or equal to N with repetition
    return (N - cntNumbers)
 
# Driver Code
if __name__ == '__main__':
    N = 100
 
    # Function call
    print(cntNumLessThanEqualNRepeatedDigits(N))


C#
// C# program to implement
// the above approach
using System;
using System.Collections.Generic;
class GFG {
     
    static int factorial(int n)
    {
        return (n == 1 || n == 0) ? 1 :
                n * factorial(n - 1); 
    }
      
    // Function to count arrangements to
    // select K elements from N elements 
    static int NPR(int n, int k)
    {
        return factorial(n) / factorial(n - k);
    }
      
    // Function to count numbers less than or equal 
    // to N with at least one repeated digits
    static int cntNumLessThanEqualNRepeatedDigits(int N)
    {
          
        // Stores the value of N
        int temp = N;
      
        // Stores count of
        // digits in N
        int X = 0;
      
        // Store all possible
        // digits of N
        List nums = new List();
          
        // Calculate digits in N
        while (temp > 0)
        {
              
            // Update X
            X += 1;
      
            // Insert digits of N
            // into nums
            nums.Add(temp % 10);
              
            // Update temp
            temp /= 10;
        }
        nums.Reverse();
          
        // Count numbers of (X)-digit
        // with no repeated digits
        int cntNumbers = 0;
      
        // Calculate count of numbers of less than
        // (X)-digit and no repeated digits
        for(int i = 1; i < X; i++)
        {
              
            // Update cntnumbers
            cntNumbers += 9 * (factorial(9) /
                               factorial(10 - i));
        }
          
        // Stores unique digits of
        // (X)-digit numbers
        HashSet vis = new HashSet();
          
        // Calculate (X) digits
        // numbers with no repeated digits
        for(int i = 0; i < nums.Count; i++)
        {
              
            // Stores count of unique
            // value at i_th digit
            int k = 0;
      
            // Stores minimum possible value of
            // i_th digit of a number
            int Min = 0;
      
            // If current digit is the first
            // digit of a number
            if (i == 0)
            {
                  
                // Update Min
                Min = 1;
            }
            else
            {
                  
                // Update Min
                Min = 0;
            }
      
            // Stores maximum possible value of
            // i_th digit if a number   
            int Max = 0;
      
            // If current digit is the last
            // digit of a number
            if (i == X - 1)
            {
                  
                // Update Max
                Max = nums[i];
            }
            else
            {
                  
                // Update Max
                Max = nums[i] - 1;
            }
                  
            // Iterate over all possible value
            // of current digit
            for(int j = Min; j <= Max; j++)
            {
                  
                // If value of current digit
                // already occurred in vis
                if (vis.Contains(j))
                {
                    continue;
                }
                      
                // Update k
                k += 1;
            }
              
            // Update cntNumbers
            cntNumbers += k * (NPR(9 - i,
                          X - i - 1));
      
            // If current value of i-th digit
            // already occurred in vis             
            if (vis.Contains(nums[i]))
            {
                break;
            }
              
            // Insert val in vis
            vis.Add(nums[i]);
        }
          
        // Return total count of numbers less
        // than or equal to N with repetition
        return (N - cntNumbers);
    }
 
  static void Main()
  {
        int N = 100;
  
        Console.WriteLine(cntNumLessThanEqualNRepeatedDigits(N));
  }
}
 
// This code is contributed by divyeshrabadiya07


输出:
10

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