剑指 Offer 17. 打印从1到最大的n位数

剑指 Offer 17. 打印从1到最大的n位数

Offer 17

  • 题目解析:
  • 暴力解法
package com.walegarrett.offer;

/**
 * @Author WaleGarrett
 * @Date 2021/1/25 16:16
 */
public class Offer_17 {
    public int[] printNumbers(int n) {
        int maxlen = (int) Math.pow(10.0, n * 1.0);
        maxlen -= 1;
        int []result = new int[maxlen];
        for(int i = 0; i< maxlen; i++){
            result[i] = i+1;
        }
        return result;
    }
}
  • 字符串模拟大数解法:
class Solution {
    int [] result;
    int index = 0;
    public int[] printNumbers(int n) {
        StringBuilder num = new StringBuilder();
        result = new int[ (int) (Math.pow(10.0, n * 1.0) - 1)];
        for(int i=0; i<n; i++)
            num.append('0');
        while(!isOverFlow(num)){
            printNums(num);
        }
        return result;
    }

    /**
     * 用以判断是否溢出:例如3位数999,1000即表示溢出
     * @param now
     * @return
     */
    boolean isOverFlow(StringBuilder now){
        boolean isoverflow = false;
        int carry = 0;
        for(int i = now.length()-1; i >= 0; i--){
            int current = Integer.parseInt("" + now.charAt(i)) + carry;
            if(i == now.length() -1)
                current += 1;
            //将产生进位
            if(current >= 10){
                if(i == 0)
                    isoverflow = true;//产生溢出,到达首位
                else{
                    carry = 1;
                    now.setCharAt(i, String.valueOf(current - 10).charAt(0));
                }
            }else{//没有产生进位
                now.setCharAt(i, String.valueOf(current).charAt(0));
                break;//没有进位则表示不用继续模拟加法了
            }
        }
        return isoverflow;
    }

    void printNums(StringBuilder now){
        boolean isZero = false;
        String temp = "";
        for(int i =0; i< now.length(); i++){
            if(isZero && now.charAt(i) != '0')
                isZero = false;
            if(!isZero)
                temp += now.charAt(i);
        }
        result[index++] = Integer.parseInt(temp);
    }
}
  • 全排列递归解法:
    • 解题思路:

    • 复杂度分析:

package com.walegarrett.offer;

/**
 * @Author WaleGarrett
 * @Date 2021/1/25 21:24
 */
public class Offer_17_2 {
    int [] result;
    int index = 0;
    int n, start, nineNum;
    char []chars;
    public int[] printNumbers(int n) {
        this.n = n;
        start = n - 1;
        chars = new char[n];
        result = new int[ (int) (Math.pow(10.0, n * 1.0) - 1)];
        nineNum = 0;
        dfs(0);
        return result;
    }
    void dfs(int cnt){
        if(cnt == n){
            //start表示起始数字,排除0开始的子串
            String ans = String.valueOf(chars).substring(start);
            if(!ans.equals("0"))
                result[index++] = Integer.parseInt(ans);
            if(n - start == nineNum)
                start--;//需要进位
            return;
        }
        for(int i=0; i<10; i++){
            char now = String.valueOf(i).charAt(0);
            if(i == 9)
                nineNum++;//
            //固定一个位数
            chars[cnt] = now;
            dfs(cnt + 1);
        }
        //结束循环,9的个数减一
        nineNum--;
    }
}

posted @ 2021-01-25 21:41  Garrett_Wale  阅读(60)  评论(0编辑  收藏  举报