zoukankan      html  css  js  c++  java
  • 《剑指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;
    			}
    		}
    	}
    
  • 相关阅读:
    git stash和git stash pop
    Ethereum HD Wallet(虚拟货币钱包)-BIP32、BIP39、BIP44
    bip44
    bip39
    bip32
    ethjs-1-了解
    myEtherWallet在线钱包的使用
    MetaMask/provider-engine-2-代码
    MetaMask/provider-engine-1
    MetaMask/eth-block-tracker
  • 原文地址:https://www.cnblogs.com/czjk/p/11611395.html
Copyright © 2011-2022 走看看