This is the 13th day of my participation in the August More Text Challenge
233. Number of 1s
Given an integer n, count the number of occurrences of the number 1 in all non-negative integers less than or equal to n.
Example 1:
Input: n = 13 Output: 6Copy the code
Example 2:
Input: n = 0 Output: 0Copy the code
Methods a
Counting problems:
All we need to do is figure out how many occurrences of 1’s in each digit, and then add up the number of occurrences of 1’s in each digit, and that’s the number of occurrences of 1’s in each digit from 1 to n;
For convenience, we subtract the digits from each digit and place them in an array. When iterating over each digit, we have the following calculation rules:
Suppose the given number is abcdefg
-
When I enumerate to C,
-
If c = 0
- Before c, the range we can choose is 1, 2
0~ab-1
C is the range of choices0 ~ 9999
- Before c, the range we can choose is 1, 2
-
If c = 1
- Before c, the range you can choose is
0~ab-1
C is the range of choices0 ~ 9999
; Cab
, the following selected range is0~defg
- Before c, the range you can choose is
-
If c is greater than 1, the value ranges from 0 to AB and from 0 to 9999
According to the above rules, enumerate each digit, and finally add;
class Solution {
public int countDigitOne(int n) {
ArrayList<Integer> nums = new ArrayList<>();
while(n != 0) {
nums.add(n % 10);
n /= 10;
}
int res = 0;
Collections.reverse(nums);
for (int i = 0; i < nums.size(); i ++ ) {
int left = 0, right = 0, j = i + 1;
while(j < nums.size()) right = right * 10 + nums.get(j ++);
j = 0;
while(j < i) left = left * 10 + nums.get(j ++);
if (nums.get(i) == 0) {
res += left * (int)Math.pow(10, nums.size() - i - 1);
}
else if (nums.get(i) > 1) {
res += (left + 1) * (int)Math.pow(10, nums.size() - i - 1);
}else {
res += left * (int)Math.pow(10, nums.size() - i - 1) + right + 1;
}
}
return res;
}
}
Copy the code
Note: left and right in the loop refer to the number before and after the current digit of the enumeration; Of course, there is no need to calculate the left every time. We only need to maintain an external left and calculate it iteratively each time. But right still has to be computed through the history, so the complexity of time is not reduced; -_- Similar to this number law related can be classified into digital DP this kind of problem, first pull out each digit, and then for specific problems, to specific analysis;