Number of occurrences of 1 in a positive number from 1 to n

Source: Internet
Author: User

Question: enter an integerN, Seek from1ToNThisNIn decimal format1The number of occurrences.

For example, enter12, From1To12These integers contain1The numbers are:1,10,11And12,1A total5Times.

 

Analysis: This is a widely used Google interview question. Solving with the most intuitive method is not very difficult, but it is a pity that the efficiency is not very high.AlgorithmIt is not easy to use the analysis capability. Of course, there are only a few simple questions about Google.

First, let's look at the most intuitive method to obtain the number of occurrences of 1 in each integer from 1 to n. The number of times 1 appears in the decimal expression of an integer is very similar to the 22nd question in the series of this questions. Each time we judge whether the single digit of an integer is 1. If the number is greater than 10, divide it by 10 and then judge whether the single digit is 1. Based on this idea, it is not difficult to write the followingCode:

IntNumberof1 (UnsignedIntN );

////////////////////////////////////// /// //
// find the number of 1 in the integers between 1 and N
// input: n-an integer
// output: the number of 1 in the integers between 1 and N
////////////////////////////////////// /// //
int numberof1beforebetween1andn_solution1 ( unsigned int N)
{< br> int Number = 0;

// Find the number of 1 in each integer between 1 and N
For(UnsignedIntI = 1; I <= N; ++ I)
Number + = numberof1 (I );

ReturnNumber;
}

//////////////////////////////////////// /////////////////////////////////////
// Find the number of 1 in an integer with Radix 10
// Input: N-an integer
// Output: the number of 1 in N with Radix
//////////////////////////////////////// /////////////////////////////////////
Int Numberof1 ( Unsigned Int N)
{
Int Number = 0;
While (N)
{
If (N % 10 = 1)
Number ++;

N = N/10;
}

ReturnNumber;
}

One obvious drawback of this idea is that each number must calculate the number of times 1 appears in the number, so the time complexity is O (n ). When the input N is very large, a large amount of computing is required, and the computing efficiency is very low. We try to find out some rules to avoid unnecessary computation.

We use a slightly larger number 21345 as an example for analysis. We divide all numbers from 1 to 21345 into two segments: 1-1346 and 21345.

First, let's look at the number of times 1 appears in 1346-000045. The emergence of 1 is divided into two types: one is that 1 appears at the highest bits (tens of thousands of BITs ). In numbers from 1 to 21345, 1 appears in the 10000 bits of the 10000 numbers, a total of (104); The other case is that 1 appears in other bits except the highest bits. In this example, the value 1346-21345 indicates that the first occurrence of the last four digits is 20000 (2*10 ).3, Where the first value of 2 is 10.3The reason is that one of the last four digits is 1, and the other three digits can be randomly selected from the 10 digits 0 to 9. The total number of times can be 2*10 from the permutation and combination.3).

The number of occurrences of 1 in all numbers from 1 to 1345 can be obtained recursively. This is why we divide 1-000045 into 1-1235 and 1346-000045. Because we get 21345 by removing the highest bit of 1345, so that we can use recursive thinking.

There is also a special case after analysis: In the previous example, the highest digit is a number greater than 1, and the maximum digit 1 appears at 10 times.4(For five digits ). But what if the highest bit is 1? For example, if the input value is 12345, from 10000 to 12345, the number of occurrences of one digit is not 10.4Times, but 2346 times, that is, add 1 to the remaining number after removing the highest digit.

Based on the previous analysis, we can write the following code. In the reference code, I converted the number into a string for programming convenience.

 public class test_25 {public static void main (string [] ARGs) {int n = 21345; system. out. println ("1:" + numof1between1andn (n);} public static int numof1between1andn (integer N) {If (n <1) return 0; string STR = n. tostring (); Return numberof1 (STR);} public static int numberof1 (string Str) {// obtain the first digit of the input number, for example, input 21345, firstdig = 2int firstdig = integer. parseint (Str. charat (0) + ""); int length = Str. length (); If (length = 1 & firstdig = 0) return 0; If (length = 1 & firstdig> 0) return 1; // int firstnumdigit = 0; If (firstdig> 1) firstnumdigit = powerbase10 (length-1); If (firstdig = 1) firstnumdigit = integer. parseint (Str. substring (1) + 1; // The number of other bits is 1. Int othernumdigit = firstdig * (length-1) * powerbase10 (length-2 ); // Number of recursive bits of 1 int numrecursive = numberof1 (Str. substring (1); Return firstnumdigit + othernumdigit + numrecursive;} public static int powerbase10 (int n) {int result = 1; for (INT I = 0; I 
  

Output result: 1 is 18821

 

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.