问题:计算从1到N的整数中包含0的数字。
例子:
Input: n = 9
Output: 0
Input: n = 107
Output: 17
The numbers having 0 are 10, 20,..90, 100, 101..107
Input: n = 155
Output: 24
The numbers having 0 are 10, 20,..90, 100, 101..110,
120, ..150.
天真的解决方案在上一篇文章中进行了讨论
在这篇文章中,讨论了一种优化的解决方案。让我们仔细分析问题。
让给定数字为d位数字。
可以通过计算以下两个值来计算所需的答案:
- 具有最大d-1位数字的0位整数的计数。
- 精确地具有d位的0位整数的计数(小于/等于给定的课程数!)
因此,解决方案将是上述两项的总和。
第一部分已经在这里进行了讨论。
如何找到第二部分?
我们可以找到具有d位数字(小于等于给定数字)的整数总数,其中不包含任何零。
为了找到这个,我们遍历数字,一次一位。
我们发现非负整数的计数如下:
- 如果该位置的数字为零,则将计数器递减1并中断(因为我们不能再移动了,因此请递减以确保数字本身包含零)
- 否则,将(number-1)乘以power(9,右边的数字位数)
让我们用一个例子来说明。
Let the number be n = 123. non_zero = 0
We encounter 1 first,
add (1-1)*92 to non_zero (= 0+0)
We encounter 2,
add (2-1)*91 to non_zero (= 0+9 = 9)
We encounter 3,
add (3-1)*90 to non_zero (=9+3 = 12)
我们可以观察到non_zero表示由3个数字组成的整数(不大于123),并且不包含任何零。即(111,112,…..,119,121,122,123)(建议进行一次验证)
现在,您可能会问,计算没有零的数字的计数有什么意义?
正确的!我们有兴趣找到具有零的整数的计数。
但是,我们现在可以通过忽略最重要的位置后从n中减去non_zero来轻松地找到它。即,在我们之前的示例中,zero = 23 – non_zero = 23-12 = 11,最后我们将这两个部分相加以获得所需的结果!!
以下是上述想法的实现。
C++
//Modified C++ program to count number from 1 to n with
// 0 as a digit.
#include
using namespace std;
// Returns count of integers having zero upto given digits
int zeroUpto(int digits)
{
// Refer below article for details
// https://www.geeksforgeeks.org/count-positive-integers-0-digit/
int first = (pow(10,digits)-1)/9;
int second = (pow(9,digits)-1)/8;
return 9 * (first - second);
}
// utility function to convert character representation
// to integer
int toInt(char c)
{
return int(c)-48;
}
// counts numbers having zero as digits upto a given
// number 'num'
int countZero(string num)
{
// k denoted the number of digits in the number
int k = num.length();
// Calculating the total number having zeros,
// which upto k-1 digits
int total = zeroUpto(k-1);
// Now let us calculate the numbers which don't have
// any zeros. In that k digits upto the given number
int non_zero = 0;
for (int i=0; i
Java
//Modified Java program to count number from 1 to n with
// 0 as a digit.
public class GFG {
// Returns count of integers having zero upto given digits
static int zeroUpto(int digits)
{
// Refer below article for details
// https://www.geeksforgeeks.org/count-positive-integers-0-digit/
int first = (int) ((Math.pow(10,digits)-1)/9);
int second = (int) ((Math.pow(9,digits)-1)/8);
return 9 * (first - second);
}
// utility function to convert character representation
// to integer
static int toInt(char c)
{
return (int)(c)-48;
}
// counts numbers having zero as digits upto a given
// number 'num'
static int countZero(String num)
{
// k denoted the number of digits in the number
int k = num.length();
// Calculating the total number having zeros,
// which upto k-1 digits
int total = zeroUpto(k-1);
// Now let us calculate the numbers which don't have
// any zeros. In that k digits upto the given number
int non_zero = 0;
for (int i=0; i
Python3
# Python3 program to count number from 1 to n
# with 0 as a digit.
# Returns count of integers having zero
# upto given digits
def zeroUpto(digits):
first = int((pow(10, digits) - 1) / 9);
second = int((pow(9, digits) - 1) / 8);
return 9 * (first - second);
# counts numbers having zero as digits
# upto a given number 'num'
def countZero(num):
# k denoted the number of digits
# in the number
k = len(num);
# Calculating the total number having
# zeros, which upto k-1 digits
total = zeroUpto(k - 1);
# Now let us calculate the numbers which
# don't have any zeros. In that k digits
# upto the given number
non_zero = 0;
for i in range(len(num)):
# If the number itself contains a zero
# then decrement the counter
if (num[i] == '0'):
non_zero -= 1;
break;
# Adding the number of non zero numbers
# that can be formed
non_zero += (((ord(num[i]) - ord('0')) - 1) *
(pow(9, k - 1 - i)));
no = 0;
remaining = 0;
calculatedUpto = 0;
# Calculate the number and the remaining
# after ignoring the most significant digit
for i in range(len(num)):
no = no * 10 + (ord(num[i]) - ord('0'));
if (i != 0):
calculatedUpto = calculatedUpto * 10 + 9;
remaining = no - calculatedUpto;
# Final answer is calculated. It is calculated
# by subtracting 9....9 (d-1) times from no.
ans = zeroUpto(k - 1) + (remaining - non_zero - 1);
return ans;
# Driver Code
num = "107";
print("Count of numbers from 1 to",
num, "is", countZero(num));
num = "1264";
print("Count of numbers from 1 to",
num, "is", countZero(num));
# This code is contributed by mits
C#
// Modified C# program to count number from 1 to n with
// 0 as a digit.
using System;
public class GFG{
// Returns count of integers having zero upto given digits
static int zeroUpto(int digits)
{
// Refer below article for details
// https://www.geeksforgeeks.org/count-positive-integers-0-digit/
int first = (int) ((Math.Pow(10,digits)-1)/9);
int second = (int) ((Math.Pow(9,digits)-1)/8);
return 9 * (first - second);
}
// utility function to convert character representation
// to integer
static int toInt(char c)
{
return (int)(c)-48;
}
// counts numbers having zero as digits upto a given
// number 'num'
static int countZero(String num)
{
// k denoted the number of digits in the number
int k = num.Length;
// Calculating the total number having zeros,
// which upto k-1 digits
int total = zeroUpto(k-1);
// Now let us calculate the numbers which don't have
// any zeros. In that k digits upto the given number
int non_zero = 0;
for (int i=0; i
PHP
Javascript
输出:
Count of numbers from 1 to 107 is 17
Count of numbers from 1 to 1264 is 315
复杂度分析:
时间复杂度: O(d),其中d为否。的数字,即O(log(n)
辅助空间:O(1)