DFS模拟全排列

前言

对于全排列问题,先将问题与转换为全排列问题,然后用DFS来模拟全排列。

一、Case

1、原题

A.题目

输入数字 n,按顺序打印出从 1 到最大的 n 位十进制数。比如输入 3,则打印出 1、2、3 一直到最大的 3 位数 999。

B.实例

示例 1:
输入: n = 1
输出: [1,2,3,4,5,6,7,8,9]

2、题解

该题的第一个问题就是,最大n位十进制数存储可能超过数值型的字节数,所以要用字符串来记录这些数值,所以可以使用全排列去组合所有可能的数值。

A.思想

在这里插入图片描述

B.Code and Annotation

package com.xhu.offer;

import java.util.Arrays;

/**
 * 剑指offer第30天,分治算法
 */
public class DivideAlg {
    /**
     * leetcode不需要考虑大数问题。
     * @param n
     * @return
     */
    public int[] printNumbers(int n) {
        n = (int) Math.pow(10, n);
        int[] res = new int[n - 1];
        for (int i = 1; i < n; i++) {
            res[i - 1] = i;
        }
        return res;
    }

    //每一次排列,用stringBuilder来组合一个字符串。
    private StringBuilder sb = new StringBuilder();
    //每一个排列好了,都用该字符串数据记录
    private String[] res = null;
    //关联上面的数组,用count来做下标,让数组正确将字符串记录
    private int count = 0;

    /**
     * 考虑大数问题,即数越界
     * Core:若要考虑大数问题,则需要字符串存储,所以可以使用全排列。即使用到递归去全排列。
     *
     * @param n
     * @return
     */
    public String[] printNumbers2(int n) {
        //1.初始化记录数组,它的长度应为10的n次方 - 1
        res = new String[(int) Math.pow(10, n) - 1];
        //2.递归来完成全排列的过程。
        dfs(n);
        //3.返回记录满字符串的数组。
        return res;
    }

    /**
     * 递归来模拟全排列
     *
     * @param n n个数来进行全排列
     */
    private void dfs(int n) {
        //递归出口,当没有数来进行全排列时,则将字符串记录并结束此次递归。
        if (n == 0) {
            //因为0没有记录,所以全是0的情况就不考虑把其记录下来。
            if (sb.length() > 0) res[count++] = sb.toString();
            return;
        }
        //递归体,0-9来进行全排列
        for (int i = 0; i <= 9; i++) {
            //只有不是0开头的才append到后面。
            if (i != 0 || sb.length() != 0) {
                sb.append(i);
                dfs(n - 1);
                //每次回来都要去除上一次添加的。
                sb.delete(sb.length() - 1, sb.length());
            } else dfs(n - 1);//本身就没记录,所以不用考虑delete上一次的字符
        }

    }

    /**
     * 主函数验证算法
     * @param args
     */
    public static void main(String[] args) {
        System.out.println(Arrays.toString(new DivideAlg().printNumbers2(2)));
    }
}

总结

1)全排列问题 -> 全排列 -> dfs递归实现。

参考文献

[1] Leetcode原题
[2] 以上图片来自Leetcode用户的评论

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值