【剑指offer】之整数中1出现的次数




有两种解法,时间复杂度不同。


java代码实现:

/** 解法一 (时间复杂度为o(n)*lgn)
	 * 
	 * 
	 * 最直观的方法,分别求得1到n中每个整数中1出现的次数。
	 * 
	 */
	private static int printNumbersOfOne(int start, int end) {
		int sumOfone = 0;
		for(int i=start;i<=end;i++) {
			sumOfone += getNumbersOfOne(i); 
		}
		
		return sumOfone;
	}
	
	private static int getNumbersOfOne(int num) {
		int result = 0;
		//int b = 0;
		while(num != 0) {
			
			if(num%10 == 1) {
				result ++;
			}
			num = num / 10;
		}
		
		return result ;
	}


	/**解法二 (时间复杂度为o(n))
	 * 
	 * 针对各位上出现的1的次数做统计,如30143:
                                  由于3>1,则个位上出现1的次数为(3014+1)*1
                                  由于4>1,则十位上出现1的次数为(301+1)*10
                                  由于1=1,则百位上出现1次数为(30+0)*100+(43+1)
                                  由于0<1,则千位上出现1次数为(3+0)*1000
	 *
	 */
	private static long CountNumberOne(long num) {
		
		if(num <=0)
			return 0;
		long count = 0; //1的个数
		long current ; //当前位
		long base = 1; //基数
		long remain = 0; //当前位等于1时,后面剩余的部分数目
		while(num > 0) {
			current = num % 10;
			num = num / 10;
			if(current > 1)
				count += (num + 1) * base;
			else if(current == 1)
				count += num * base + (remain+1) ;
			else 
				count += num * base ;
			remain += current *  base ;
			base = base * 10;
		}
		
		return count ;
	}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值