字符串的排列
1:题目描述
输入一个字符串,打印出该字符串中字符的所有排列。
你可以以任意顺序返回这个字符串数组,但里面不能有重复元素。
示例:
输入:s = "abc"
输出:["abc","acb","bac","bca","cab","cba"]
限制:
1 <= s 的长度 <= 8
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/zi-fu-chuan-de-pai-lie-lcof
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
2:题目分析
首先这是一道全排序的问题,同时要求使用不能重复,所以我们采用dfs深度搜索和set集合去重的方法来解决这个问题。关键点在于dfs深度搜索如何设计?
我们直到在图中使用dfs时,是对所有顶点都遍历一遍才能结束,然后这里的dfs是针对每次路径都要不重复的,与图的深度搜索是由很大差异的。为了简单期间我们先手工推算出如果是3个字符的字符串应该如何处理?然后从特殊到一般的来进行迭代算法的分析:
假设字符串为:a,b,c三个字符串,我们通过以下方法可以判断出来如何获得其排序的结果。
第一次循环:在a,b,c中选择某一个没有标记的字符,标记为选择状态,然后加入StringBuilder中。然后进入
第二次循环:选择某一个没有标记的字符,标记为选择状态,然后加入StringBuilder中。然后进入
第三次循环:选择某一个没有标记的字符,标记为选择状态,然后加入StringBuilder中,然后将StringBulider记过保存在输出Stirng[]。然后同时将本轮标记的字符清除标记,同时StringBuilder也取出本次的获取的字符。退出第三次循环,计入上次循环即为第二次循环,然后依然清除当前标记,退出当前字符,在第二次进行下一次找的的字符。重读本次操作,依然在找到下一次字符后会进去第三次循环,直到第二和第三次循环结束,再进行第一次循环中,遍历处理。
3:代码示例
package JianZhiOffer38; import java.lang.reflect.Array; import java.util.ArrayList; import java.util.HashSet; /** * @author :dazhu * @date :Created in 2020/3/24 8:04 * @description:剑指offer38 * @modified By: * @version: $ */ public class Main { public static void main(String[]args){ Solution solution = new Solution(); String s ="aab"; solution.permutation(s); } } class Solution { StringBuilder sResult ; String s; int[] mark; int sum=0; int lastIndex=0; //使用HashSet可以去重 HashSet<String> hs = new HashSet<>(); int slength=0; //做法从特殊到一般的思想,慢慢解决。 public String[] permutation(String s) { this.s = s; this.sResult =new StringBuilder(s.length()); this.mark = new int[s.length()]; this.slength = s.length(); recur(); return hs.toArray(new String[hs.size()]);//集合转数组 } //把上面的从特殊到一般的算法,用迭代的方法计算即可 //迭代终止条件:迭代到了最后一个字符,则终止迭代,将该字符加入字符串然后将获得取得完整字符串往ArratList中存。 //迭代逻辑:标记当前选取的字符,然后再次迭代判断下次选择的字符,当退出迭代时,将本次标记清零 //返回值:void void recur(){ //**********迭代终止条件和处理************** //判断是不是只有剩下一个字符了? sum = 0; for(int i=0;i<slength;i++){ sum = sum + mark[i]; //将最后一个为0的字符位置保存起来。 if(mark[i] == 0){ lastIndex = i; } } //如果mark之和为length-1,则只有一个字符没有被选择了。 //则将此时的字符串放入ArrayList中来。 if(sum == slength-1){ //把最后一个字符加入。 sResult.append(s.charAt(lastIndex)); //String temp = new String(""+sResult); hs.add(""+sResult); //在取出最后一个字符。 sResult.deleteCharAt(sResult.length()-1); return ; } //************迭代逻辑************** for(int i=0;i<slength;i++){ //只有当该字符没有被标记,才能选择。 if(mark[i]==0) { //将当字符标记为1,意味着选择该字符。 mark[i] = 1; //将该字符加入指定字符串,供输出使用。 sResult.append(s.charAt(i)); //再继续迭代下去 recur(); //递归回来时,将本次加入的字符取出,供后序使用, sResult.deleteCharAt(sResult.length()-1); //该字符选择后,当递归回来时,应该将该字符重新标记0,为本次循环向后执行时 //能够继续选取本字符。 mark[i] = 0; } } } }

浙公网安备 33010602011771号