首页 > 编程语言 >回溯算法:剑指 Offer 38. 字符串的排列

回溯算法:剑指 Offer 38. 字符串的排列

时间:2023-04-24 11:46:50浏览次数:42  
标签:38 String 递归 Offer StringBuilder 回溯 集合 new

题目描述:

输入一个字符串,打印出该字符串中字符的所有排列。

你可以以任意顺序返回这个字符串数组,但里面不能有重复元素。

 

限制:

  1 <= s 的长度 <= 8

 

 

class Solution{
    Set<String> res = new HashSet<>();
    public String[] permutation(String s){
        backTrack(s.toCharArray(),new StringBuilder(),new boolean[s.length()]);
        return res.toArray(new String[0]);
    }
    // 回溯函数
    public void backTrack(char[] ch,StringBuilder sb,boolean[] used){
        // 终止条件
        if(sb.length()==ch.length){
            res.add(sb.toString());
            return;
        }
        // 选择列表
        for(int i=0;i<ch.length;i++){
            // 剪枝,如果当前位置的元素已经使用过,则跳过进入下一个位置
            if(used[i]) continue;
            // 更新标记
            used[i]=true;
            // 做出选择
            sb.append(ch[i]);
            // 进入下层回溯
            backTrack(ch,sb,used);
            // 撤销选择
            sb.deleteCharAt(sb.length()-1);
            used[i]=false;
        }
    }
}

 

 

什么是回溯法

回溯法也可以叫做回溯搜索法,它是一种搜索的方式。回溯是递归的副产品,只要有递归就会有回溯。

 

回溯法解决的问题

回溯法,一般可以解决如下几种问题:

  • 组合问题:N个数里面按一定规则找出k个数的集合
  • 切割问题:一个字符串按一定规则有几种切割方式
  • 子集问题:一个N个数的集合里有多少符合条件的子集
  • 排列问题:N个数按一定规则全排列,有几种排列方式
  • 棋盘问题:N皇后,解数独等等

(组合无序,排列有序)

 

如何理解回溯法

回溯法解决的问题都可以抽象为树形结构,所有回溯法的问题都可以抽象为树形结构!

因为回溯法解决的都是在集合中递归查找子集,集合的大小就构成了树的宽度,递归的深度,都构成的树的深度。

递归就要有终止条件,所以必然是一棵高度有限的树(N叉树)。

 

 

回溯法模板

  • 回溯函数模板返回值以及参数

回溯算法中函数返回值一般为void。

再来看一下参数,因为回溯算法需要的参数可不像二叉树递归的时候那么容易一次性确定下来,所以一般是先写逻辑,然后需要什么参数,就填什么参数。

void backtracking(参数)

  

  • 回溯函数终止条件

什么时候达到了终止条件,树中就可以看出,一般来说搜到叶子节点了,也就找到了满足条件的一条答案,把这个答案存放起来,并结束本层递归。

if (终止条件) {
    存放结果;
    return;
}

  

  • 回溯搜索的遍历过程

回溯法一般是在集合中递归搜索,集合的大小构成了树的宽度,递归的深度构成的树的深度。

 

for (选择:本层集合中元素(树中节点孩子的数量就是集合的大小)) {
    处理节点;
    backtracking(路径,选择列表); // 递归
    回溯,撤销处理结果
}

  

for循环就是遍历集合区间,可以理解一个节点有多少个孩子,这个for循环就执行多少次。

backtracking这里自己调用自己,实现递归。

backtracking(递归)就是纵向遍历,这样就把这棵树全遍历完了,一般来说,搜索叶子节点就是找的其中一个结果了。

回溯算法模板框架如下:

 

void backtracking(参数) {
    if (终止条件) {
        存放结果;
        return;
    }

    for (选择:本层集合中元素(树中节点孩子的数量就是集合的大小)) {
        处理节点;
        backtracking(路径,选择列表); // 递归
        回溯,撤销处理结果
    }
}

 

  

toArray()

ArrayList提供了一个将List转为数组的一个非常方便的方法toArray,在使用toArray方法时,我们在参数列表中传入new String[0] 表示这个方法将返回一个String类型的字符串。

List<String> list = new ArrayList<>();
String[] strs = list.toArray(new String[0]);

  

toString()

StringBuilder类的toString()方法是一种内置方法,用于返回表示StringBuilder对象包含的数据的字符串。

创建并初始化一个新的String对象,以从该StringBuilder对象获取字符序列,然后由toString()返回String。 Object包含的对该序列的后续更改不会影响String的内容。

以下示例程序旨在说明StringBuilder.toString()方法:

 

s.toCharArray()

1.toCharArray()的用法:是将字符串对象中的字符转换为一个字符数组;

String s="I am niuandidog";

char  arr[ ]=s.toCharArray( );

System.out.println(arr);

//output:

I am niuandidog

 

Stringbuilder 用法

StringBuilder 类在 Java 5 中被提出,它和 StringBuffer 之间的最大不同在于 StringBuilder 的方法不是线程安全的(不能同步访问)。

由于 StringBuilder 相较于 StringBuffer 有速度优势,所以多数情况下建议使用 StringBuilder 类。

 

 

标签:38,String,递归,Offer,StringBuilder,回溯,集合,new
From: https://www.cnblogs.com/zhz123567/p/17348946.html

相关文章

  • 剑指 Offer 33. 二叉搜索树的后序遍历序列(java解题)
    (剑指Offer33.二叉搜索树的后序遍历序列(java解题))1.题目输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历结果。如果是则返回 true,否则返回 false。假设输入的数组的任意两个数字都互不相同。 参考以下这颗二叉搜索树:5/\26/\13示......
  • 剑指 Offer 33. 二叉搜索树的后序遍历序列(java解题)
    目录1.题目2.解题思路3.数据类型功能函数总结4.java代码5.踩坑小记递归调用,显示StackOverflowError1.题目输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历结果。如果是则返回 true,否则返回 false。假设输入的数组的任意两个数字都互不相同。参考以下这颗二叉......
  • 力扣---238. 除自身以外数组的乘积
    给你一个整数数组 nums,返回数组 answer ,其中 answer[i] 等于 nums 中除 nums[i] 之外其余各元素的乘积 。题目数据保证数组 nums之中任意元素的全部前缀元素和后缀的乘积都在 32位整数范围内。请不要使用除法,且在 O(n)时间复杂度内完成此题。 示例1:输......
  • Oracle:fedora-server-38:安装oracle12c:注意点
    首先,必须的准备!其次,需要注意,fedora-server默认安装时,临时目录/tmp是tempfs系统,其空间大小(默认最大为内存的一半)可能不足!建议将其卸载,重新在根目录创建或连接到一个足够大的磁盘空间上! ......
  • 从功能到外企测开,工作1年半拿下年薪30万的测开 offer,未来可期
    说一下我的大致情况,女,2018年毕业于末流211计算机本科。后来待业两年,完全没有从事互联网方面的工作。去年来到北京,在小公司做了一年多功能测试。今年11月底跳槽到外企,开始了我钱多事少离家近,每周965的快乐生活,现在年薪30万左右。降大任于斯人也,必先苦其心志2014年,高考没有考好,为......
  • 剑指Offer——59-I.滑动窗口的最大值(c语言)
    title:剑指Offer59-I.滑动窗口的最大值(c语言)给定一个数组nums和滑动窗口的大小k,请找出所有滑动窗口里的最大值。示例:输入:nums=[1,3,-1,-3,5,3,6,7],和k=3输出:[3,3,5,5,6,7]解释:滑动窗口的位置最大值-----------------......
  • 剑指Offer——10-I.斐波那契数列(c语言)
    title:剑指Offer10-I.斐波那契数列(c语言)写一个函数,输入n,求斐波那契(Fibonacci)数列的第n项。斐波那契数列的定义如下:F(0)=0,F(1)=1F(N)=F(N-1)+F(N-2),其中N>1.斐波那契数列由0和1开始,之后的斐波那契数就是由之前的两数相加而得出。答案需要取......
  • 剑指Offer——57.和为s的两个数字(c语言)
    title:剑指Offer57.和为s的两个数字(c语言)输入一个递增排序的数组和一个数字s,在数组中查找两个数,使得它们的和正好是s。如果有多对数字的和等于s,则输出任意一对即可。示例1:输入:nums=[2,7,11,15],target=9输出:[2,7]或者[7,2]示例2:输入:nums=[10,26,30,31,47,60],......
  • 剑指Offer——03.数组中重复的数字(c语言)
    title:剑指Offer03.数组中重复的数字(c语言)找出数组中重复的数字。在一个长度为n的数组nums里的所有数字都在0~n-1的范围内。数组中某些数字是重复的,但不知道有几个数字重复了,也不知道每个数字重复了几次。请找出数组中任意一个重复的数字。示例1:输入:[2,3,1,0,2,......
  • 剑指Offer——05.替换空格(c语言)
    title:剑指Offer05.替换空格(c语言)请实现一个函数,把字符串s中的每个空格替换成"%20"。示例1:输入:s="Wearehappy."输出:"We%20are%20happy."限制:$$0\leqslants的长度\leqslant10000$$代码如下:char*replaceSpace(char*s){if(NULL==s){return......