《剑指offer》面试题12 打印1到最大的n位数 Java版

书中方法:这道题的一个陷阱在于不能用int或者long去存储你要打印的数,然后用打印函数打印,因为这个数可能会很大。如果加1后超出了最大的n位数,就不打印了。用最高位是否进位判断是否结束,打印的时候注意不要打印出前面可能出现的0.

	public void print(int n){
		if(n<=0){
			return;
		}
		//必须要用字符数组防止大数
		char[] c = new char[n];
		for(int i=0; i<n; i++){
			c[i] = '0';
		}
		
		while(!increment(c)){
			digitsPrint(c);
			
		}
	}
	
	private boolean increment(char[] c){
		boolean overflow = false;
		//因为是加1,当作从小数进位了1.
		int carry = 1;
		//从个位开始计算
		for(int i=c.length-1; i>=0; i--){
			int sum = c[i] - '0' + carry;
			//如果进位了
			if(sum == 10){
				if(i == 0){
					overflow = true;
					break;
				}
				carry = 1;
				c[i] = '0';
			}else{//如果没进位
				c[i] = (char)('0' + sum);
				break;
			}
		}
		return overflow;
	}
	
	private void digitsPrint(char[] c){
		int index = 0;
		while(c[index] == '0'){
			index++;
		}
		for(int i=index; i<c.length; i++){
			System.out.print(c[i]);
		}
		System.out.println();
	}

我的方法:看到“所有”和“打印”这样的关键字,很容易想到用回溯的方法去做,因为实质是求出所有组合,上面的方法也是为了能遍历到所有组合。和求字符串的全排列以及组合不同(题目28),这里字符可以重复使用(又联想到了打印n位以内数字不重复整数...这里不展开,后面再说)。回想一下我们打印字符串的全排列时,因为每个字符只能使用一次,所以我们得想办法保证每个字符只被选取一次(利用额外的数组或者交换)。现在我们只需要简单地在每个位子上选取可能出现的值,然后递归下去就行了。外层是一个控制长度的循环,内层为每一位选取数字,每一位上都有‘0’-‘9’字符可以选择(第一位除外)。

	public void print2(int n){
		if(n <= 0)return;
		
		List<String> result = new ArrayList<String>();
		String line = "";
		
		//用n控制位数
		for(int i=1; i<=n; i++){
			find(result, line, 0, i);
		}
		
		for(String s : result){
			System.out.println(s);
		}
		
		
	}
	
	private void find(List<String> result, String line, int level, int border){
		//每一位添加完毕后保存
		if(level >= border){
			result.add(new String(line));
			return;
		}
                //用户保护原始的line,即保护现场(可百度这个关键词)
		String temp = new String(line);
		for(int i=0; i<=9; i++){
			//第一位不能为0
			if(level == 0 && i == 0){
				continue;
			}else{
                                //当前位添加
				line += i;
                                //继续添加下一位
				find(result, line, level+1, border);
				//让line恢复,进入下次for循环
                                line = temp;
			}
		}
	}
posted @ 2019-09-30 10:34  CrazyJack  阅读(213)  评论(0编辑  收藏  举报