- Data Structure
- Networking
- RDBMS
- Operating System
- Java
- MS Excel
- iOS
- HTML
- CSS
- Android
- Python
- C Programming
- C++
- C#
- MongoDB
- MySQL
- Javascript
- PHP
- Physics
- Chemistry
- Biology
- Mathematics
- English
- Economics
- Psychology
- Social Studies
- Fashion Studies
- Legal Studies
- Selected Reading
- UPSC IAS Exams Notes
- Developer's Best Practices
- Questions and Answers
- Effective Resume Writing
- HR Interview Questions
- Computer Glossary
- Who is Who
Total numbers with no repeated digits in a range
In this article, we will discuss different approaches to calculate the number of positive integers which have no repeated digits between a given range Low to high. The first approach is a brute force approach which iterates over all the numbers in the range and check if they contain repeated digits. In our second approach, we calculated the desired count using prefix array while in our last approach we used the concept of memorization in dynamic programming to get the desired result.
Problem Statement: We are given two numbers low and high and we have to find the count of all the numbers between low to high such that the number does not contain any repeated digits.
Approach 1
This is the brute force method where we are just iterating over all the numbers from low to high and checking if they contain any repeated digits. This is the easiest approach to solving our problem.
Example
The code solution for the same is given below:
#include <bits/stdc++.h> using namespace std; // function that checks whether or not the number contains any repeated digits int count(int number){ int arr[10] = {0}; while(number != 0) { int digit = number % 10; if(arr[digit]>=1) { return 0; } arr[digit]++; number = number / 10; } return 1; } // this function iterates over all the numbers in the range from low to high and adds the count of numbers having no repeated digits to the result int numberofnums(int l , int h) { int res = 0; for(int iterator = l; iterator < h + 1; ++iterator) { res = res + count(iterator); } return res ; } int main() { int low = 1, high = 90; cout << "The count of numbers with no repeated digits from " << low << " to "<< high << " is "<<numberofnums(low, high); return 0; }
Output
The count of numbers with no repeated digits from 1 to 90 is 82
Approach 2
This this approach, we will use a prefix array that stores the count of integers which have no repeated digits up to index “iterator”.
Steps involved in this approach are:
Define a function that checks if a number has repeated digits.
Initialize a prefix array with zeros. The prefix array will store the number of valid numbers up to a given index “iterator”.
Iterate from low to high for each number, check if it has repeated digits. If it does not have repeated digits, increment the prefix array at the corresponding index by 1.
Calculate the prefix sum of the prefix array. The prefix sum will give you the total number of valid numbers in the range.
Return the prefix sum.
Example
The code for this approach is given below-
#include <bits/stdc++.h> using namespace std; bool isvalid(int number) { int arr[10] = {0}; while(number != 0) { int digit = number % 10; if(arr[digit]>=1) { return false; } arr[digit]++; number = number / 10; } return true; } int count(int low, int high) { vector<int> prefarray(high+1, 0); for (int iterator = low; iterator <= high; iterator++) { if (isvalid(iterator)) { prefarray[iterator] = 1; } } for (int iterator = 1; iterator <= high; iterator++) { prefarray[iterator] += prefarray[iterator-1]; } return prefarray[high] - prefarray[low-1]; } int main() { int low = 21, high = 200; int c = count(low, high); cout << "The count of numbers with no repeated digits from " << low << " to "<< high << " is "<< c; return 0; }
Output
The count of numbers with no repeated digits from 21 to 200 is 143
Time complexity − O(nlogn) where n is (high - low).
Space complexity − O(n)
Approach 3 Dynamic programming approach
In this approach, we will break down the problem into subproblems and will store the result of the subproblems in a memoization table
The program calculates the total number of valid numbers in a given range, i.e., numbers with no repeated digits. It uses a dynamic programming approach where the function dp(“iterator”, used) returns the number of valid numbers that can be formed starting from position “iterator” with the digits in ”used”.
We have used a memoization table to store the results of the dp function and iterate through the range of numbers to call the dp function for each number. The sum of the results of the dp function for all starting positions “iterator” is the total number of valid numbers in the range.
Example
#include <bits/stdc++.h> using namespace std; int dp(int iterator, set<int>& used, unordered_map<string, int>& memo, const string& high_str) { if ( memo.count(to_string(iterator) + "|" + to_string(used.size() ))) { return memo[to_string(iterator) + "|" + to_string(used.size())]; } if (iterator == high_str.length()) { return 1; } int count = 0; for (int digit = 0; digit < 10; digit++) { if (digit == 0 && iterator == 0) { continue; } if (!used.count(digit)) { used.insert(digit); count += dp(iterator+1, used, memo, high_str); used.erase(digit); } } memo[to_string(iterator) + "|" + to_string(used.size())] = count; return count; } int count_valid_numbers(int low, int high) { unordered_map<string, int> memo; string high_str = to_string(high); int count = 0; for (int num = low; num <= high; num++) { set<int> used; count += dp(0, used, memo, high_str); } return count; } int main() { int low = 21, high = 200; int count = count_valid_numbers(low, high); cout << "The count of numbers with no repeated digits from " << low << " to " << high << " is "<< count; return 0; }
Output
The count of numbers with no repeated digits from 21 to 200 is 116640
Conclusion − In this code we discussed three approaches to count the total numbers with no repeated digits in a range from low to high.