面试题43: 1~N整数中1出现的次数

方法一:
/**
@algorithm description:
统计1~N中所有数中1出现的次数的算法:
step1: 遍历1~N中的所有数字
step2: 对每一个数字的每一位是否位1进行检查

@Time complexity of the algorithm:		O(nlogn)
@Spatial complexity of the algorithm:	NA
**/
#include <stdio.h>
#include <stdlib.h>

/**
@function:		Count the number of occurrences of 1 in a single number
@param[in]:		The number
@param[out]:	NA
@return:		1 number of occurrences
@author:		Cohen
@data:			2021/09/11
**/
int NumberOf1(int n)
{
	int number = 0;
	
	while (n)
	{
		if (n % 10 == 1)
		{
			number++;
		}
		n /= 10;
	}

	return number;
}

/**
@function:		The frequency of occurrence of 1 between 1 and N
@param[in]:		The range of numbers to be counted	
@param[out]:	NA	
@return:		1 number of occurrences
@author:		Cohen
@data:			2021/09/11
**/
int NumberOf1Between1AndN(int n)
{
	int number = 0;

	for (size_t i = 1; i <= n; i++)
	{
		number += NumberOf1(i);
	}

	return number;
}

/**
@function:		A test case
@param[in]:		NA
@param[out]:	NA
@return:		NA
@author:		Cohen
@data:			2021/09/11
**/
void test43()
{
	int n = 214;
	int number = 0;

	number = NumberOf1Between1AndN(n);

	printf("number = %d\n", number);

}

int main()
{
	test43();
	system("pause");

	return 0;
}



方法二:
/**
@algorithm description:
统计1~N中所有数中X出现的次数的算法:
step1: 取第i位左边的所有高位数,并将该数乘以10^(i - 1),得到基础数a;
step2: 根据第i位的数的大小对a进行修正,修正后的结果位ret
	   #1. 如果第i位数大于X, 则ret = a + 10^(i - 1)
	   #2. 如果第i位数小于X,则ret = a
	   #3. 如果第i位数等于X,则ret = a + b + 1 (其中b位第i位右边的数字)
step3: 依照step1、step2依次计算N的所有位上X出现的次数,累加即可得到最终结果

@Time complexity of the algorithm:		O(logn)
@Spatial complexity of the algorithm:	NA
**/
#include <stdio.h>
#include <stdlib.h>
#include <math.h>

/**
@function:		Count the number X in all numbers from 1 to N
@param[in]:		n: The maximum range of numbers N 
@param[in]:		The number X that needs to be counted
@param[out]:	NA
@return:		The number of occurrences of X
@author:		Cohen
@data:			2021/09/12
**/
int NumberOfxFrom1ToN(int n, int x)
{
	int number = 0;
	int copy = n;
	int power = 0;
	double i = 1;
	int cur_pos = 0;

	while (n)
	{
		cur_pos = n % 10;
		power = (int)pow(10, i - 1);

		if (cur_pos > x)
		{
			number += (n / 10 + 1) * power;
		}
		else if(cur_pos < x)
		{
			number += (n / 10) * power;
		}
		else
		{
			number += (n / 10) * power + (copy % power + 1);
		}

		n /= 10;
		i++;

	}

	return number;
}

/**
@function:		A test case
@param[in]:		NA
@param[out]:	NA
@return:		NA
@author:		Cohen
@data:			2021/09/12
**/
void test43_1()
{
	int n = 21345;
	int x = 1;
	printf("ret = %d\n", NumberOfxFrom1ToN(n, 1));
}

int main()
{
	test43_1();
	system("pause");
	return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值