剑指offer第12题 最优解

public class Print1ToMaxOfNDigits_1 {

	/**
	 * print1ToMax把每一位赋值为零字符;
	 * 
	 * 
	 * @param n
	 */
	void print1ToMax(int n)
	{
		if(n<0)
		{
			return;
		}
		char[] number = new char[n];
		for (int i = 0; i < number.length; i++) {
			number[i]='0';
		}
//		number[n]='\0'不用了,因为Java的字符串最后没有\0
		while(!increment(number))
		{
			printNumber(number);
		}
	}

	
	/**
	 * 其中,isBeginning0设置为true;从不为零的位置开始输出。
	 * @param number
	 */
	private void printNumber(char[] number) {

		boolean isBeginning0=true;
		int length = number.length;
		for (int j = 0; j < length; j++) {
			if(isBeginning0&&number[j]!='0')
				isBeginning0=false;
			if(!isBeginning0)
			{
				System.out.printf("%c", number[j]);
			}
		}
		System.out.printf("\t");
		
	}
	/**
	 * 其中,isOverflow是溢出标志;nTakeOver是进1的符号;length是字符数组的长度。
	 * 这里的逻辑大概是:(这里的技巧是,比较的是最高位是否进位,若进位则已经到了最大值)
	 *1.每次都是从末位开始加1,如果加1后,跳到步骤2;
	 *2.如果数值和小于10,直接赋给本位置,number[i]=(char) ('0'+nSum);然后break;
	 *3.如果数值和不小于10,则进位 nTakeOver设为1;并把nSum-=10;number[i]=(char) ('0'+nSum);
	 *4.如果已经进位到number[0],则isOverflow设置为true。return isOverflow;
	 * @param number
	 */
	private boolean increment(char[] number) {
		boolean isOverflow= false;
		int nTakeOver=0;
		int length= number.length;
		
		for (int i = length-1; i>=0; i--) {
			int nSum=number[i]-'0'+nTakeOver;
			if(i==length-1)
				nSum++;
			if(nSum>=10)
			{
				if(i==0)
					isOverflow=true;
				else {
					nSum-=10;
					nTakeOver=1;
					number[i]=(char) ('0'+nSum);
				}
			}else {
				number[i]=(char) ('0'+nSum);
				break;
			}
		}
		
		return isOverflow;
	}
	public static void main(String[] args) {
		Print1ToMaxOfNDigits_1 pp=new Print1ToMaxOfNDigits_1();
//		pp.print1ToMax(3);
		//最优解的方法
		pp.print1ToMaxOfNDigits(3);
		
//		//利用循环解
//		pp.print1ToMaxOfNDigitsRecycle(3);
		
		
	}
	
	
	/**
	 * 
	 * 最优化的解
	 */
	void print1ToMaxOfNDigits(int n){
		if(n<=0)
			return;
		char[] number= new char[n];
		for (int i = 0; i < 10; ++i) {
			number[0]=(char)(i+'0');
			print1ToMaxOfNDigitsRecursively(number,n,0);
		}
		
	}


	private void print1ToMaxOfNDigitsRecursively(char[] number, int length, int index) {
		if(index==length-1)
		{
			printNumber(number);
			return;
		}
		for (int i = 0; i < 10; ++i)
		{
			number[index+1]=(char) (i+'0');
			print1ToMaxOfNDigitsRecursively(number,length,index+1);
		}
	}
	//错误的,循环的方法没有写出来。。。呜呜
//	private void print1ToMaxOfNDigitsRecycle(int length) {
//		char[] number=new char[length];
//		for (int i = 0; i < number.length; i++) {
//			number[i]='0';
//		}
//		for (int i = length-1; i >=0; i--) {
//			
//			for (int j = length-1; j >=i; j--) {
//				for (int j2 = 0; j2 >j; j2--) {
//					for (int k = 0; k <= 9; k++) {
//						
//						number[j2]=(char) (k+'0');
//						printNumber(number);
//					}
//				}
//				
//			}
//			
//		}
//	}
	
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值