Given two integers L and R, the task is to count numbers from the range [L, R] having odd digits at odd positions and even digits at even positions respectively.
Examples:
Input: L = 3, R = 25
Output: 9
Explanation: The numbers satisfying the conditions are 3, 5, 7, 9, 10, 12, 14, 16 and 18.Input: L = 128, R = 162
Output: 7
Explanation: The numbers satisfying the conditions are 129, 141, 143, 145, 147, 149 and 161.
Approach: The given problem can be solved based on the following observations:
It can be observed that every even position has 5 choices {0, 2, 4, 6, 8} and every odd position also has 5 choices {1, 3, 5, 7, 9}. Therefore, there are 5 possibilities for every position. Considering d to be the number of digits in any number satisfying the condition and D to be the number of digits in N, following observations can be made:
- Case 1: If d < D, then the count of total numbers consisting of d digits satisfying the condition is 5d as every number has 5 choices and numbers made will all be less than N.
- Case 2: If D = d, then the count of total numbers satisfying the condition of length d is 5d . But the numbers exceeding N needs to be discarded, which is determined by the following:
- For even places, if the digit in pth place is x, then (5 — (x / 2 + 1)) * 5(D — p) numbers are greater than N.
- For odd places, if the digit in pth place is x, then (5 — (x + 1) / 2) * 5(D — p) numbers will be greater than N.
Follow the steps below to solve the problem:
- Define a function countNumberUtill() for count the numbers from the range [1, N], satisfying the condition, where N is a natural number.
- Initialize an integer variable, count and vector digits to store the digits of the integer N.
- Traverse over all the digits of given number, i.e. from 1 to D, and perform the following:
- Store the 5i in variable, say res.
- Traverse from p = 1 to p = D and perform the following:
- Initialize a variable x and store x = digits[p] in it.
- If p is even, then subtract (5 — (x / 2 + 1)) * 5(D— p) from res.
- Otherwise, subtract (5 — (x + 1) / 2) * 5(D — p) from res.
- Add res to the count.
- Return the count.
- Print countNumberUtill(R) — countNumberUtill(L – 1) as the required answer.
Below is the implementation of the above approach:
C++
// C++ program to implement // the above approach #include <bits/stdc++.h> using namespace std; #define ll long long // Function to calculate 5^p ll getPower( int p) { // Stores the result ll res = 1; // Multiply 5 p times while (p--) { res *= 5; } // Return the result return res; } // Function to count all numbers upto N // having odd digits at odd places and // even digits at even places ll countNumbersUtil(ll N) { // Stores the count ll count = 0; // Stores the digits of N vector< int > digits; // Insert the digits of N while (N) { digits.push_back(N % 10); N /= 10; } // Reverse the vector to arrange // the digits from first to last reverse(digits.begin(), digits.end()); // Stores count of digits of n int D = digits.size(); for ( int i = 1; i <= D; i++) { // Stores the count of numbers // with i digits ll res = getPower(i); // If the last digit is reached, // subtract numbers eceeding range if (i == D) { // Iterate over all the places for ( int p = 1; p <= D; p++) { // Stores the digit in the pth place int x = digits[p - 1]; // Stores the count of numbers // having a digit greater than x // in the p-th position ll tmp = 0; // Calculate the count of numbers // exceeding the range if p is even if (p % 2 == 0) { tmp = (5 - (x / 2 + 1)) * getPower(D - p); } // Calculate the count of numbers // exceeding the range if p is odd else { tmp = (5 - (x + 1) / 2) * getPower(D - p); } // Subtract the count of numbers // exceeding the range from total count res -= tmp; // If the parity of p and the // parity of x are not same if (p % 2 != x % 2) { break ; } } } // Add count of numbers having i digits // and satisfies the given conditions count += res; } // Return the total count of numbers till n return count; } // Function to calculate the count of numbers // from given range having odd digits places // and even digits at even places void countNumbers(ll L, ll R) { // Count of numbers in range [L, R] = // Count of numbers till R - cout << (countNumbersUtil(R) // Count of numbers till (L-1) - countNumbersUtil(L - 1)) << endl; } // Driver Code int main() { ll L = 128, R = 162; countNumbers(L, R); return 0; } |
Java
// Java program to implement // the above approach import java.util.*; import java.util.Vector; import java.util.Collections; class GFG{ // Function to calculate 5^p static int getPower( int p) { // Stores the result int res = 1 ; // Multiply 5 p times while (p > 0 ) { res *= 5 ; p--; } // Return the result return res; } // Function to count all numbers upto N // having odd digits at odd places and // even digits at even places static int countNumbersUtil( int N) { // Stores the count int count = 0 ; // Stores the digits of N Vector<Integer> digits = new Vector<Integer>(); // Insert the digits of N while (N > 0 ) { digits.add(N % 10 ); N /= 10 ; } // Reverse the vector to arrange // the digits from first to last Collections.reverse(digits); // Stores count of digits of n int D = digits.size(); for ( int i = 1 ; i <= D; i++) { // Stores the count of numbers // with i digits int res = getPower(i); // If the last digit is reached, // subtract numbers eceeding range if (i == D) { // Iterate over all the places for ( int p = 1 ; p <= D; p++) { // Stores the digit in the pth place int x = digits.get(p - 1 ); // Stores the count of numbers // having a digit greater than x // in the p-th position int tmp = 0 ; // Calculate the count of numbers // exceeding the range if p is even if (p % 2 == 0 ) { tmp = ( 5 - (x / 2 + 1 )) * getPower(D - p); } // Calculate the count of numbers // exceeding the range if p is odd else { tmp = ( 5 - (x + 1 ) / 2 ) * getPower(D - p); } // Subtract the count of numbers // exceeding the range from total count res -= tmp; // If the parity of p and the // parity of x are not same if (p % 2 != x % 2 ) { break ; } } } // Add count of numbers having i digits // and satisfies the given conditions count += res; } // Return the total count of numbers till n return count; } // Function to calculate the count of numbers // from given range having odd digits places // and even digits at even places static void countNumbers( int L, int R) { // Count of numbers in range [L, R] = // Count of numbers till R - System.out.println(countNumbersUtil(R) - // Count of numbers till (L-1) countNumbersUtil(L - 1 )); } // Driver Code public static void main(String args[]) { int L = 128 , R = 162 ; countNumbers(L, R); } } // This code is contributed by ipg2016107 |
Python3
# Python3 program to implement # the above approach # Function to calculate 5^p def getPower(p) : # Stores the result res = 1 # Multiply 5 p times while (p) : res * = 5 p - = 1 # Return the result return res # Function to count anumbers upto N # having odd digits at odd places and # even digits at even places def countNumbersUtil(N) : # Stores the count count = 0 # Stores the digits of N digits = [] # Insert the digits of N while (N) : digits.append(N % 10 ) N / / = 10 # Reverse the vector to arrange # the digits from first to last digits.reverse() # Stores count of digits of n D = len (digits) for i in range ( 1 , D + 1 , 1 ) : # Stores the count of numbers # with i digits res = getPower(i) # If the last digit is reached, # subtract numbers eceeding range if (i = = D) : # Iterate over all the places for p in range ( 1 , D + 1 , 1 ) : # Stores the digit in the pth place x = digits[p - 1 ] # Stores the count of numbers # having a digit greater than x # in the p-th position tmp = 0 # Calculate the count of numbers # exceeding the range if p is even if (p % 2 = = 0 ) : tmp = (( 5 - (x / / 2 + 1 )) * getPower(D - p)) # Calculate the count of numbers # exceeding the range if p is odd else : tmp = (( 5 - (x + 1 ) / / 2 ) * getPower(D - p)) # Subtract the count of numbers # exceeding the range from total count res - = tmp # If the parity of p and the # parity of x are not same if (p % 2 ! = x % 2 ) : break # Add count of numbers having i digits # and satisfies the given conditions count + = res # Return the total count of numbers tin return count # Function to calculate the count of numbers # from given range having odd digits places # and even digits at even places def countNumbers(L, R) : # Count of numbers in range [L, R] = # Count of numbers tiR - print (countNumbersUtil(R) # Count of numbers ti(L-1) - countNumbersUtil(L - 1 )) # Driver Code L = 128 R = 162 countNumbers(L, R) # This code is contributed by code_hunt |
C#
// C# program for // the above approach using System; using System.Collections.Generic; class GFG{ // Function to calculate 5^p static int getPower( int p) { // Stores the result int res = 1; // Multiply 5 p times while (p > 0) { res *= 5; p--; } // Return the result return res; } // Function to count all numbers upto N // having odd digits at odd places and // even digits at even places static int countNumbersUtil( int N) { // Stores the count int count = 0; // Stores the digits of N List< int > digits = new List< int >(); // Insert the digits of N while (N > 0) { digits.Add(N % 10); N /= 10; } // Reverse the vector to arrange // the digits from first to last digits.Reverse(); // Stores count of digits of n int D = digits.Count; for ( int i = 1; i <= D; i++) { // Stores the count of numbers // with i digits int res = getPower(i); // If the last digit is reached, // subtract numbers eceeding range if (i == D) { // Iterate over all the places for ( int p = 1; p <= D; p++) { // Stores the digit in the pth place int x = digits[p - 1]; // Stores the count of numbers // having a digit greater than x // in the p-th position int tmp = 0; // Calculate the count of numbers // exceeding the range if p is even if (p % 2 == 0) { tmp = (5 - (x / 2 + 1)) * getPower(D - p); } // Calculate the count of numbers // exceeding the range if p is odd else { tmp = (5 - (x + 1) / 2) * getPower(D - p); } // Subtract the count of numbers // exceeding the range from total count res -= tmp; // If the parity of p and the // parity of x are not same if (p % 2 != x % 2) { break ; } } } // Add count of numbers having i digits // and satisfies the given conditions count += res; } // Return the total count of numbers till n return count; } // Function to calculate the count of numbers // from given range having odd digits places // and even digits at even places static void countNumbers( int L, int R) { // Count of numbers in range [L, R] = // Count of numbers till R - Console.WriteLine(countNumbersUtil(R) - // Count of numbers till (L-1) countNumbersUtil(L - 1)); } // Driver Code public static void Main(String[] args) { int L = 128, R = 162; countNumbers(L, R); } } // This code is contributed by jana_sayantan |
Javascript
<script> // JavaScript Program for the above approach // Function to calculate 5^p function getPower(p) { // Stores the result var res = 1; // Multiply 5 p times while (p--) { res *= 5; } // Return the result return res; } // Function to count all numbers upto N // having odd digits at odd places and // even digits at even places function countNumbersUtil( N) { // Stores the count var count = 0; // Stores the digits of N var digits= []; // Insert the digits of N while (N) { digits.push(N % 10); N = parseInt(N / 10); } // Reverse the vector to arrange // the digits from first to last digits.reverse(); // Stores count of digits of n var D = digits.length; for ( var i = 1; i <= D; i++) { // Stores the count of numbers // with i digits var res = getPower(i); // If the last digit is reached, // subtract numbers eceeding range if (i == D) { // Iterate over all the places for ( var p = 1; p <= D; p++) { // Stores the digit in the pth place var x = digits[p - 1]; // Stores the count of numbers // having a digit greater than x // in the p-th position var tmp = 0; // Calculate the count of numbers // exceeding the range if p is even if (p % 2 == 0) { tmp = (5 - parseInt(x / (2 + 1))) * getPower(D - p); } // Calculate the count of numbers // exceeding the range if p is odd else { tmp = (5 - parseInt( (x + 1) / 2)) * getPower(D - p); } // Subtract the count of numbers // exceeding the range from total count res -= tmp; // If the parity of p and the // parity of x are not same if (p % 2 != x % 2) { break ; } } } // Add count of numbers having i digits // and satisfies the given conditions count += res; } // Return the total count of numbers till n return count; } // Function to calculate the count of numbers // from given range having odd digits places // and even digits at even places function countNumbers(L, R) { // Count of numbers in range [L, R] = // Count of numbers till R - document.write( (countNumbersUtil(R) // Count of numbers till (L-1) - countNumbersUtil(L - 1)) + "<br>" ); } var L = 128, R = 162; countNumbers(L, R); // This code is contributed by SoumikMondal </script> |
7
Time Complexity: O(N2), where N is the number of digits in R
Auxiliary Space: O(1)
Efficient Digit DP Approach:
The main idea of the code is to use a recursive function f to count the valid numbers based on the given conditions. The function takes several parameters: nums (the string representation of the current number), idx (the current index being considered), even (a flag indicating whether the current position is even or odd), leadingZero (a flag indicating whether the number has leading zeros), and tight (a flag indicating whether the current digit is at its tightest limit based on the range).
- The function f uses memoization to store the results of subproblems in the 4-dimensional DP array dp. The dimensions of dp represent: the number of digits, the even/odd flag, the leading zero flag, and the tight flag.
- The base case is when idx reaches 0, which means all the digits have been considered. In this case, the function returns 1, indicating that a valid number has been found.
- The function f then proceeds to calculate the count by considering two cases:
- If the current position is even (even = 0), the function checks whether leading zeros are allowed (leadingZero == 1). If so, it recursively calls f for the next position (idx – 1) with even = 0, leadingZero = 1, and tight as 0 (since a non-zero digit will be used as the leading digit). This is because leading zeros are not allowed in this case.
- After that, the function iterates over the valid odd digits (1, 3, 5, 7, 9) and checks if each digit is less than or equal to the upper bound (ub) based on the tight flag. If it is, the function recursively calls f for the next position (idx – 1) with even = 1, leadingZero = 0, and tight as the logical AND between the current tight flag and whether the current digit (i) is equal to the upper bound (ub). This ensures that the tightness constraint is maintained as we move to the next position.
- If the current position is odd (even = 1), the function follows a similar approach but considers even digits (0, 2, 4, 6, 8) instead. It iterates over the valid even digits, checks the upper bound, and makes the recursive call with even = 0.
- Finally, in the main function, the code reads the range L and R, converts them to strings l and r, and initializes the DP array dp with -1. It then calls the function f twice, once with l and once with r, and subtracts the results to get the count of valid numbers within the range. The result is then printed.
- Overall, the code uses the concept of digit DP to break down the problem into smaller subproblems and compute the final count efficiently by leveraging memoization.
Explanation of DP States:
dp[idx][even][leadingZero][tight]: This 4-dimensional DP array stores the intermediate results of the recursive function f. It represents the number of valid numbers that can be formed from the remaining digits, given the current state of the computation.
- idx: Represents the index of the current digit being considered. It ranges from 1 to the number of digits in the input number.
- even: Indicates whether the current position is even or odd. It can have two possible values: 0 for even position and 1 for odd position.
- leadingZero: Represents whether leading zeros are allowed (1) or not (0).
- tight: Indicates whether the current number being formed is still within the range and needs to satisfy the tightness constraint. It can have two possible values: 1 for tight and 0 for non-tight
The DP array is used to avoid recomputing the same subproblem multiple times and improve the efficiency of the solution.
Implementation:
C++
#include <bits/stdc++.h> using namespace std; long long int dp[20][2][2][2]; long long int f(string& nums, long long int idx, long long int even, int leadingZero, int tight) { if (idx == 0) { return 1; // Base case: All digits have been // considered, return 1 indicating a valid // number } if (dp[idx][even][leadingZero][tight] != -1) { return dp[idx][even][leadingZero] [tight]; // If the subproblem has already // been solved, return the cached // result } long long int cnt = 0; if (even == 0) { // If the current position is even if (leadingZero == 1) { cnt += f(nums, idx - 1, 0, 1, 0); // If leading zeros are allowed, // make a recursive call for the // next position with even = 0, // leadingZero = 1, and tight = 0 } vector< int > digs = { 1, 3, 5, 7, 9 }; int ub = (tight == 1) ? (nums[nums.size() - idx] - '0' ) : 9; // Calculate the upper bound based // on the tight flag and the // current digit for ( auto i : digs) { if (i <= ub) { cnt += f( nums, idx - 1, 1, 0, tight & (ub == i)); // Make a recursive call // for the next position // with even = 1, // leadingZero = 0, and // tight = tight & (ub == // i) to maintain the // tightness constraint } } } else { // If the current position is odd vector< int > digs = { 0, 2, 4, 6, 8 }; int ub = (tight == 1) ? (nums[nums.size() - idx] - '0' ) : 9; // Calculate the upper bound based // on the tight flag and the // current digit for ( auto i : digs) { if (i <= ub) { cnt += f( nums, idx - 1, 0, 0, tight & (i == ub)); // Make a recursive call // for the next position // with even = 0, // leadingZero = 0, and // tight = tight & (i == // ub) to maintain the // tightness constraint } } } return dp[idx][even][leadingZero][tight] = cnt; // Cache the computed result in the DP // array and return it } int main() { long long int L = 128, R = 162; L--; string l, r; l = to_string(L); r = to_string(R); memset (dp, -1, sizeof (dp)); // Initialize the DP array with -1 // indicating that no subproblem has // been solved yet long long int ans1 = f(l, l.size(), 0, 1, 1); // Calculate the count for the lower range L memset (dp, -1, sizeof (dp)); // Reset the DP array long long int ans2 = f(r, r.size(), 0, 1, 1); // Calculate the count for the upper range R cout << ans2 - ans1; // Print the difference between the // counts to get the final result return 0; } |
Java
import java.util.Arrays; public class Main { static long [][][][] dp; public static long f(String nums, int idx, int even, int leadingZero, int tight) { if (idx == 0 ) { return 1 ; // Base case: All digits have been considered, return 1 indicating a valid number } if (dp[idx][even][leadingZero][tight] != - 1 ) { return dp[idx][even][leadingZero][tight]; // If the subproblem has already been solved, return the cached result } long cnt = 0 ; if (even == 0 ) { // If the current position is even if (leadingZero == 1 ) { cnt += f(nums, idx - 1 , 0 , 1 , 0 ); // If leading zeros are allowed, make a recursive call for the next position with even = 0, leadingZero = 1, and tight = 0 } int [] digs = { 1 , 3 , 5 , 7 , 9 }; int ub = (tight == 1 ) ? Character.getNumericValue(nums.charAt(nums.length() - idx)) : 9 ; // Calculate the upper bound based on the tight flag and the current digit for ( int i : digs) { if (i <= ub) { cnt += f(nums, idx - 1 , 1 , 0 , tight & ((ub == i) ? 1 : 0 )); // Make a recursive call for the next position with even = 1, leadingZero = 0, and tight = tight & ((ub == i) ? 1 : 0) to maintain the tightness constraint } } } else { // If the current position is odd int [] digs = { 0 , 2 , 4 , 6 , 8 }; int ub = (tight == 1 ) ? Character.getNumericValue(nums.charAt(nums.length() - idx)) : 9 ; // Calculate the upper bound based on the tight flag and the current digit for ( int i : digs) { if (i <= ub) { cnt += f(nums, idx - 1 , 0 , 0 , tight & ((i == ub) ? 1 : 0 )); // Make a recursive call for the next position with even = 0, leadingZero = 0, and tight = tight & ((i == ub) ? 1 : 0) to maintain the tightness constraint } } } dp[idx][even][leadingZero][tight] = cnt; // Cache the computed result in the DP array return cnt; } public static void main(String[] args) { long L = 128 , R = 162 ; L--; String l = Long.toString(L); String r = Long.toString(R); dp = new long [ 20 ][ 2 ][ 2 ][ 2 ]; for ( long [][][] arr3D : dp) { for ( long [][] arr2D : arr3D) { for ( long [] arr1D : arr2D) { Arrays.fill(arr1D, - 1 ); } } } long ans1 = f(l, l.length(), 0 , 1 , 1 ); // Calculate the count for the lower range L dp = new long [ 20 ][ 2 ][ 2 ][ 2 ]; for ( long [][][] arr3D : dp) { for ( long [][] arr2D : arr3D) { for ( long [] arr1D : arr2D) { Arrays.fill(arr1D, - 1 ); } } } long ans2 = f(r, r.length(), 0 , 1 , 1 ); // Calculate the count for the upper range R System.out.println(ans2 - ans1); // Print the difference between the counts to get the final result } } |
Python3
dp = [[[[ - 1 for _ in range ( 2 )] for _ in range ( 2 )] for _ in range ( 2 )] for _ in range ( 20 )] def f(nums, idx, even, leadingZero, tight): if idx = = 0 : return 1 # Base case: All digits have been considered, return 1 indicating a valid number if dp[idx][even][leadingZero][tight] ! = - 1 : return dp[idx][even][leadingZero][tight] # If the subproblem has already been solved, return the cached result cnt = 0 if even = = 0 : # If the current position is even if leadingZero = = 1 : cnt + = f(nums, idx - 1 , 0 , 1 , 0 ) # If leading zeros are allowed, make a recursive call for the next position with even = 0, leadingZero = 1, and tight = 0 digs = [ 1 , 3 , 5 , 7 , 9 ] ub = int (nums[ len (nums) - idx]) if tight = = 1 else 9 # Calculate the upper bound based on the tight flag and the current digit for i in digs: if i < = ub: cnt + = f(nums, idx - 1 , 1 , 0 , tight & (ub = = i)) # Make a recursive call for the next position with even = 1, leadingZero = 0, and tight = tight & (ub == i) to maintain the tightness constraint else : # If the current position is odd digs = [ 0 , 2 , 4 , 6 , 8 ] ub = int (nums[ len (nums) - idx]) if tight = = 1 else 9 # Calculate the upper bound based on the tight flag and the current digit for i in digs: if i < = ub: cnt + = f(nums, idx - 1 , 0 , 0 , tight & (i = = ub)) # Make a recursive call for the next position with even = 0, leadingZero = 0, and tight = tight & (i == ub) to maintain the tightness constraint dp[idx][even][leadingZero][tight] = cnt # Cache the computed result in the DP array return cnt L, R = 128 , 162 l = str (L - 1 ) r = str (R) dp = [[[[ - 1 for _ in range ( 2 )] for _ in range ( 2 )] for _ in range ( 2 )] for _ in range ( 20 )] # Initialize the DP array with -1 indicating that no subproblem has been solved yet ans1 = f(l, len (l), 0 , 1 , 1 ) # Calculate the count for the lower range L dp = [[[[ - 1 for _ in range ( 2 )] for _ in range ( 2 )] for _ in range ( 2 )] for _ in range ( 20 )] # Reset the DP array ans2 = f(r, len (r), 0 , 1 , 1 ) # Calculate the count for the upper range R print (ans2 - ans1) # Print the difference between the counts to get the final result |
C#
// C# code for above approach : using System; using System.Collections.Generic; public class Program { static long [,,,] dp = new long [20, 2, 2, 2]; static long f( string nums, int idx, int even, int leadingZero, int tight) { if (idx == 0) { return 1; // Base case: All digits have been considered, return 1 indicating a valid number } if (dp[idx, even, leadingZero, tight] != -1) { return dp[idx, even, leadingZero, tight]; // If the subproblem has already been solved, return the cached result } long cnt = 0; if (even == 0) { // If the current position is even if (leadingZero == 1) { cnt += f(nums, idx - 1, 0, 1, 0); // If leading zeros are allowed, make a recursive call for the next position with even = 0, leadingZero = 1, and tight = 0 } List< int > digs = new List< int > { 1, 3, 5, 7, 9 }; int ub = (tight == 1) ? (nums[nums.Length - idx] - '0' ) : 9; // Calculate the upper bound based on the tight flag and the current digit foreach ( var i in digs) { if (i <= ub) { cnt += f(nums, idx - 1, 1, 0, tight & (ub == i ? 1 : 0)); // Make a recursive call for the next position with even = 1, leadingZero = 0, and tight = tight & (ub == i) to maintain the tightness constraint } } } else { // If the current position is odd List< int > digs = new List< int > { 0, 2, 4, 6, 8 }; int ub = (tight == 1) ? (nums[nums.Length - idx] - '0' ) : 9; // Calculate the upper bound based on the tight flag and the current digit foreach ( var i in digs) { if (i <= ub) { cnt += f(nums, idx - 1, 0, 0, tight & (i == ub ? 1 : 0)); // Make a recursive call for the next position with even = 0, leadingZero = 0, and tight = tight & (i == ub) to maintain the tightness constraint } } } return dp[idx, even, leadingZero, tight] = cnt; // Cache the computed result in the DP array and return it } public static void Main( string [] args) { long L = 128, R = 162; L--; string l = L.ToString(); string r = R.ToString(); for ( int i = 0; i < 20; i++) { for ( int j = 0; j < 2; j++) { for ( int k = 0; k < 2; k++) { for ( int m = 0; m < 2; m++) { dp[i, j, k, m] = -1; // Initialize the DP array with -1 indicating that no subproblem has been solved yet } } } } long ans1 = f(l, l.Length, 0, 1, 1); // Calculate the count for the lower range L for ( int i = 0; i < 20; i++) { for ( int j = 0; j < 2; j++) { for ( int k = 0; k < 2; k++) { for ( int m = 0; m < 2; m++) { dp[i, j, k, m] = -1; // Reset the DP array } } } } long ans2 = f(r, r.Length, 0, 1, 1); // Calculate the count for the upper range R Console.WriteLine(ans2 - ans1); // Print the difference between the counts to get the final result } } //this code is contributed by uttamdp_10 |
Javascript
let dp = [...Array(20)].map(() => [...Array(2)].map(() => [...Array(2)].map(() => Array(2).fill(-1)))); function f(nums, idx, even, leadingZero, tight) { if (idx === 0) { return 1; // Base case: All digits have been considered, return 1 indicating a valid number } if (dp[idx][even][leadingZero][tight] !== -1) { return dp[idx][even][leadingZero][tight]; // If the subproblem has already been solved, return the cached result } let cnt = 0; if (even === 0) { // If the current position is even if (leadingZero === 1) { cnt += f(nums, idx - 1, 0, 1, 0); // If leading zeros are allowed, make a recursive call for the next position with even = 0, leadingZero = 1, and tight = 0 } let digs = [1, 3, 5, 7, 9]; let ub = (tight === 1) ? parseInt(nums[nums.length - idx]) : 9; // Calculate the upper bound based on the tight flag and the current digit for (let i of digs) { if (i <= ub) { cnt += f(nums, idx - 1, 1, 0, tight & (ub === i)); // Make a recursive call for the next position with even = 1, leadingZero = 0, and tight = tight & (ub === i) to maintain the tightness constraint } } } else { // If the current position is odd let digs = [0, 2, 4, 6, 8]; let ub = (tight === 1) ? parseInt(nums[nums.length - idx]) : 9; // Calculate the upper bound based on the tight flag and the current digit for (let i of digs) { if (i <= ub) { cnt += f(nums, idx - 1, 0, 0, tight & (i === ub)); // Make a recursive call for the next position with even = 0, leadingZero = 0, and tight = tight & (i === ub) to maintain the tightness constraint } } } dp[idx][even][leadingZero][tight] = cnt; // Cache the computed result in the DP array return cnt; } let L = 128, R = 162; let l = (L - 1).toString(); let r = R.toString(); dp = [...Array(20)].map(() => [...Array(2)].map(() => [...Array(2)].map(() => Array(2).fill(-1)))); // Initialize the DP array with -1 indicating that no subproblem has been solved yet let ans1 = f(l, l.length, 0, 1, 1); // Calculate the count for the lower range L dp = [...Array(20)].map(() => [...Array(2)].map(() => [...Array(2)].map(() => Array(2).fill(-1)))); // Reset the DP array let ans2 = f(r, r.length, 0, 1, 1); // Calculate the count for the upper range R console.log(ans2 - ans1); // Print the difference between the counts to get the final result |
7
Time Complexity: O(log(R) * 2 * 2 * 2) = O(log(R)), where R is the value of the upper range.
Auxiliary Space: O(log(R) * 2 * 2 * 2) = O(log(R)), where R is the value of the upper range.
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 neveropen!