暴力递归——全排列

简介: 暴力递归——全排列

 

打印一个字符串的全部排列

比如有字符串"abc",这个字符串的全排列有哪些呢,相信大家高中肯定有学过,如果忘了也不要紧,我来给大家回忆一下,很简单的😄,请看下图,记住一个原则,已经做过决策了的位置不用重复做决策!!!

image.png

// str[0...i-1] str数组0~i-1位置已经已经做好了决定,不用再做决定!!!
  // str[i...] str数组i位置及其以后的位置都有机会来到i位置
  // i来到终止位置后,str当前的样子就是一种结果,放入ans中
  public static void process1(char[] str,int i,ArrayList<String> ans) {
    if(i==str.length) {
      ans.add(String.valueOf(str[i]));
      return ;
    }
    // i没有来到终止位置,i及其往后的位置都可以来到i位置
    for(int j=i; j<str.length; j++) {
      swap(str, i, j);
      process1(str, i+1, ans);
      // 恢复现场
      swap(str, j, i);
    }
  }
  public static void swap(char[] chs,int i,int j) {
    char tmp=chs[i];
    chs[i]=chs[j];
    chs[j]=tmp;
  }
  public static List<String> printAllPermutations(String s){
    char[] str=s.toCharArray();
    ArrayList<String> ans=new ArrayList<>();
    if(s==null || s.length()==0) {
      return ans;
    }
    process1(str, 0, ans);
    return ans;
  }

现在题目升级,

打印一个字符串的全部排列,要求不要出现重复的排列

方法一:全部打印出来再去重,推荐看看上篇文章——暴力递归——打印一个字符串的全部子序列。因为方法很类似,就不具体说了。

方法二:分支限界,一种提前杀死支路的暴力递归,跟方法一相比优化了不少。

核心代码:

public static void process2(char[] str,int i,ArrayList<String> ans) {
    if(i==str.length) {
      ans.add(String.valueOf(str));
      return ;
    }
    boolean[] visited=new boolean[26];
    for(int j=i; j<str.length; j++) {
      if(!visited[str[j]-'a']) {
        visited[str[j]-'a']=true;
        swap(str, i, j);
        process2(str, i+1, ans);
        swap(str, j, i);
      }
    }
  }

完整代码:

package com.harrison.class12;
import java.util.ArrayList;
import java.util.List;
public class Code04_PrintAllPermutatioins {
  // str[0...i-1] str数组0~i-1位置已经已经做好了决定,不用再做决定!!!
  // str[i...] str数组i位置及其以后的位置都有机会来到i位置
  // i来到终止位置后,str当前的样子就是一种结果,放入ans中
  public static void process1(char[] str,int i,ArrayList<String> ans) {
    if(i==str.length) {
      ans.add(String.valueOf(str));
      return ;
    }
    // i没有来到终止位置,i及其往后的位置都可以来到i位置
    for(int j=i; j<str.length; j++) {
      swap(str, i, j);
      process1(str, i+1, ans);
      // 恢复现场
      swap(str, j, i);
    }
  }
  public static void swap(char[] chs,int i,int j) {
    char tmp=chs[i];
    chs[i]=chs[j];
    chs[j]=tmp;
  }
  public static List<String> printAllPermutations(String s){
    char[] str=s.toCharArray();
    ArrayList<String> ans=new ArrayList<>();
    if(s==null || s.length()==0) {
      return ans;
    }
    process1(str, 0, ans);
    return ans;
  }
  public static void process2(char[] str,int i,ArrayList<String> ans) {
    if(i==str.length) {
      ans.add(String.valueOf(str));
      return ;
    }
    boolean[] visited=new boolean[26];
    for(int j=i; j<str.length; j++) {
      if(!visited[str[j]-'a']) {
        visited[str[j]-'a']=true;
        swap(str, i, j);
        process2(str, i+1, ans);
        swap(str, j, i);
      }
    }
  }
  public static List<String> printNoRepeat(String s){
    char[] str=s.toCharArray();
    ArrayList<String> ans=new ArrayList<>();
    if(s==null || s.length()==0) {
      return ans;
    }
    process2(str, 0, ans);
    return ans;
  }
  public static void main(String[] args) {
    String test="acc";
    List<String> ans1=printAllPermutations(test);
    List<String> ans2=printNoRepeat(test);
    for(String cur: ans1) {
      System.out.println(cur);
    }
    System.out.println("===================");
    for(String cur: ans2) {
      System.out.println(cur);
    }
  }
}

image.png


相关文章
|
2天前
|
云安全 人工智能 自然语言处理
AI说的每一句话,都靠谱吗?
阿里云提供AI全栈安全能力,其中针对AI输入与输出环节的安全合规挑战,我们构建了“开箱即用”与“按需增强”相结合的多层次、可配置的内容安全机制。
|
6天前
|
存储 人工智能 安全
AI 越智能,数据越危险?
阿里云提供AI全栈安全能力,为客户构建全链路数据保护体系,让企业敢用、能用、放心用
|
9天前
|
域名解析 人工智能
【实操攻略】手把手教学,免费领取.CN域名
即日起至2025年12月31日,购买万小智AI建站或云·企业官网,每单可免费领1个.CN域名首年!跟我了解领取攻略吧~
|
3天前
|
消息中间件 安全 NoSQL
阿里云通过中国信通院首批安全可信中间件评估
近日,由中国信通院主办的 2025(第五届)数字化转型发展大会在京举行。会上,“阿里云应用服务器软件 AliEE”、“消息队列软件 RocketMQ”、“云数据库 Tair”三款产品成功通过中国信通院“安全可信中间件”系列评估,成为首批获此认证的中间件产品。此次评估覆盖安全可信要求、功能完备性、安全防护能力、性能表现、可靠性与可维护性等核心指标,标志着阿里云中间件产品在多架构适配与安全能力上达到行业领先水平。
303 192
|
3天前
|
安全 Java Android开发
深度解析 Android 崩溃捕获原理及从崩溃到归因的闭环实践
崩溃堆栈全是 a.b.c?Native 错误查不到行号?本文详解 Android 崩溃采集全链路原理,教你如何把“天书”变“说明书”。RUM SDK 已支持一键接入。
357 167
|
2天前
|
开发者
「玩透ESA」ESA启用和加速-ER在加速场景中的应用
本文介绍三种配置方法:通过“A鉴权”模板创建函数并设置触发器路由;在ESA上配置回源302跟随;以及自定义响应头。每步均配有详细截图指引,帮助开发者快速完成相关功能设置,提升服务安全性与灵活性。
303 2
|
8天前
|
数据采集 人工智能 自然语言处理
3分钟采集134篇AI文章!深度解析如何通过云无影AgentBay实现25倍并发 + LlamaIndex智能推荐
结合阿里云无影 AgentBay 云端并发采集与 LlamaIndex 智能分析,3分钟高效抓取134篇 AI Agent 文章,实现 AI 推荐、智能问答与知识沉淀,打造从数据获取到价值提炼的完整闭环。
458 93