LeetCode: Number of Digit One
1,2,3,4,5,6,7,8,9,10,
11,12,........
20,..,29,
30,...32,39,..
..42,.
..52,..
.92,.
..102, ,
120,129..
.192,...
200,...299...
>2 => first digit, with 2X, at least power 52 = 20~29[power =10], 513=200~299[power = 100]
==2 => first, digit, with 2x, at lest remainder+1 25=[20-25][remainder +1=6], 279=[200-279][reminder +1=80]
all other digit power-1 + reminder
Recursive MSB->LSB, maximum power you got200~299, first digit and remainder, first digit >2 power or ==2 remainder +1 AND first*f(power-1)20~29,22-92 + f(reminder)
513 = 100,5,13
32 = 10,3,2
f(513) = 100 + 5*f(99) + f(13)
= 100 + 5* 20 + 2
= 202
Iterative LSB->MSB, LSB as first digit power or remainder, remainder for next digit,= 202
digit*pos*power/10[like 5*f(99)] digit*previous count
f(513) = f(3) 3*0*1/10 + [3>2, count+=1] = 0 + 1
f(1) 1*1*10/10 + [1<2, count+=0] = 1 + 0
f(5) 5*2*100/10 + [5>2, count+=100] = 100 +100
= 202
// NOTE: accumulate from previous
count+= digit*pos*power/10;
remainder = digit * power + remainder;
f(2) = 1st digit 1 [2]
// NOTE: accumulate from previous
count+= digit*pos*power/10;
remainder = digit * power + remainder;
f(2) = 1st digit 1 [2]
al other digit 0
2 = 2* 1 + 0
f(52) = 1st digit 10 [20,..29]
al other digit f(2)
52 = 5* 10 + 2
f(513) = 1st digit 100 [200-299]
all other digit 5*f(99) + f(13)
513 = 5 *100 + 13
f(279) = 1st digit 80 [200-279]
all other digit 2*f(99) + f(79)
279 = 2*100 + 79
int nTwoFirst = 0;
2 = 2* 1 + 0
f(52) = 1st digit 10 [20,..29]
al other digit f(2)
52 = 5* 10 + 2
f(513) = 1st digit 100 [200-299]
all other digit 5*f(99) + f(13)
513 = 5 *100 + 13
f(279) = 1st digit 80 [200-279]
all other digit 2*f(99) + f(79)
279 = 2*100 + 79
int nTwoFirst = 0;
if (first > 2 )
nTwoFrist += power;
else if (first == 2)
nTwoFirst += reminder + 1;
// Count 2s from all other digits
int nTwoOther = first*count2s(power -1) + count2s(remainder);
f(279) = 2*f(99) + f(79) + 79+1[200-279]
2 in the first digit ,in the second digit, in the third digit[the last digit]
There are X2 between 0 and 99 [2,12,32,43,52,62,72,82,92] = > 10 Twos
2X between 0 and 99 [ 20, 21,... 29] = > 10 Twos
There are 2X between 0 and 199 [ 20, 21,... 29
120, 121, ..129] => 20 Twos
There are 2XX between 0 and 299 [ 200,201,.....299 ] => 100 Twos
[ 20,21,,,,29,
120, .....129,
220, ... ...229] => 30 Twos
0 1 2 .... 9
10 11 12 19
20
30....
...
110 111 119
The last digit repeat every 10 numbers, 0,10,20,30..
The last two digit repeated every 10^2 numbers, 10, 110, 210,..
The last three digit repeated every 10^3 numbers, 110, 1110,..
0 1 2 .... 9 => one 2
10 11 12 19 => one 2
20 => one 2 from 2'2'+ ten 2 from 2X
30....
...
110 111 119 => one 2
210.................219 => one 2 from 12 + ten 2 from 2XX
f(513) = the last digit 2 [2,12,22,32,...512] + the last 2 digit 2X[2x, 12x,22x, ..42x] + the last three digit 2xx[2xx]
= (512-2)/10+1 + (420-20)/100+1 + 1
= 52 + 5 + 1
2. Implementation
f(279) = 2*f(99) + f(79) + 79+1[200-279]
2 in the first digit ,in the second digit, in the third digit[the last digit]
There are X2 between 0 and 99 [2,12,32,43,52,62,72,82,92] = > 10 Twos
2X between 0 and 99 [ 20, 21,... 29] = > 10 Twos
There are 2X between 0 and 199 [ 20, 21,... 29
120, 121, ..129] => 20 Twos
There are 2XX between 0 and 299 [ 200,201,.....299 ] => 100 Twos
[ 20,21,,,,29,
120, .....129,
220, ... ...229] => 30 Twos
0 1 2 .... 9
10 11 12 19
20
30....
...
110 111 119
The last digit repeat every 10 numbers, 0,10,20,30..
The last two digit repeated every 10^2 numbers, 10, 110, 210,..
The last three digit repeated every 10^3 numbers, 110, 1110,..
0 1 2 .... 9 => one 2
10 11 12 19 => one 2
20 => one 2 from 2'2'+ ten 2 from 2X
30....
...
110 111 119 => one 2
210.................219 => one 2 from 12 + ten 2 from 2XX
f(513) = the last digit 2 [2,12,22,32,...512] + the last 2 digit 2X[2x, 12x,22x, ..42x] + the last three digit 2xx[2xx]
= (512-2)/10+1 + (420-20)/100+1 + 1
= 52 + 5 + 1
2. Implementation
public static int count2s(int n) { //validate the input // Base Case if ( n == 0 ) return 0; int power =1; while ( 10 * power < n ) power*=10; // power =100 int first = n / power ; // first = 5 int remainder = n % power; // remainder = 13 // Count 2s from the first digit int nTwoFirst = 0; if (first > 2 ) nTwoFrist += power; else if (first == 2) nTwoFirst += reminder + 1; // Count 2s from all other digits int nTwoOther = first*count2s(power -1) + count2s(remainder); return nTwoFirst + nTwoOther; }
public static int count2s(int n) { int count =0; int digit = 0; int j = num; int power = 1; int remainder = 0; int pos = 0; // maintaining this value instead of calling pow() is an 6x // perfgain // 513 = 51*10 + 3 // 51 = 5*10 + 1 // 5 = 0*10 + 5 while ( j > 0 ) { digit = j % 10; // NOTE: accumulate from previous count+= digit*pos*power/10; // NOTE: Seen it as First digit if (digit ==2 ) { // NOTE: First digit count = reminder +1 // 250 = 2*100 +50 = [200,..250] => 50+1 // 25 = 2*10 + 5= [20,..25] => 5+1 // 2 = 2*1 + 0 = [2] => 0+1 count += remainder +1; } else if ( digit > 2) { // NOTE: First digit count = power // 500 = 5*100 = [200,..299] // 50 = 5*10= [20,..29] // 5 = 5*1 = [2] count += power; } j = j / 10; remainder = digit * power + remainder; power *= 10; pos ++; } return countOf2s; }3. Similar Ones
No comments:
Post a Comment