BM58-字符串的排列

news2024/9/26 3:22:32

题目

输入一个长度为 n 字符串,打印出该字符串中字符的所有排列,你可以以任意顺序返回这个字符串数组。

例如输入字符串ABC,则输出由字符A,B,C所能排列出来的所有字符串ABC,ACB,BAC,BCA,CBA和CAB。

数据范围:n < 10。
要求:空间复杂度 O(n!),时间复杂度 O(n!)。

输入描述:输入一个字符串,长度不超过10,字符只包括大小写字母。

示例1

输入:"ab"

返回值:["ab","ba"]

说明:返回["ba","ab"]也是正确的

示例2

输入:"aab"

返回值:["aab","aba","baa"]

示例3

输入:"abc"

返回值:["abc","acb","bac","bca","cab","cba"]

示例4

输入:""

返回值:[""]


思路:递归+回溯

可参考:

字符串的排列icon-default.png?t=N3I4http://t.csdn.cn/aOxb2

  • 递归是一个过程或函数在其定义或说明中有直接或间接调用自身的一种方法,它通常把一个大型复杂的问题层层转化为一个与原问题相似的规模较小的问题来求解。因此递归过程,最重要的就是查看能不能讲原本的问题分解为更小的子问题,这是使用递归的关键。
  • 如果是线型递归,子问题直接回到父问题不需要回溯,但是如果是树型递归,父问题有很多分支,我需要从子问题回到父问题,进入另一个子问题。因此回溯是指在递归过程中,从某一分支的子问题回到父问题进入父问题的另一子问题分支,因为有时候进入第一个子问题的时候修改过一些变量,因此回溯的时候会要求改回父问题时的样子才能进入第二子问题分支。

都是求元素的全排列,字符串与数组没有区别,一个是数字全排列,一个是字符全排列,因此大致思路与有重复项的数字的全排列类似,只是这道题输出顺序没有要求。但是为了便于去掉重复情况,我们还是应该参照数组全排列,优先按照字典序排序,因为排序后重复的字符就会相邻,后续递归找起来也很方便。

使用临时变量去组装一个排列的情况:每当我们选取一个字符以后,就确定了其位置,相当于对字符串中剩下的元素进行全排列添加在该元素后面,给剩余部分进行全排列就是一个子问题,因此可以使用递归

  • 终止条件: 临时字符串中选取了n个元素,已经形成了一种排列情况了,可以将其加入输出数组中。
  • 返回值: 每一层给上一层返回的就是本层级在临时字符串中添加的元素,递归到末尾的时候就能添加全部元素。
  • 本级任务: 每一级都需要选择一个元素加入到临时字符串末尾(遍历原字符串选择)。

递归过程也需要回溯,比如说对于字符串“abbc”,如果事先在临时字符串中加入了a,后续子问题只能是"bbc"的全排列接在a后面,对于b开头的分支达不到,因此也需要回溯:将临时字符串刚刚加入的字符去掉,同时vis修改为没有加入,这样才能正常进入别的分支。

具体做法:

  • step 1:先对字符串按照字典序排序,获取第一个排列情况。
  • step 2:准备一个空串暂存递归过程中组装的排列情况。使用额外的vis数组用于记录哪些位置的字符被加入了。
  • step 3:每次递归从头遍历字符串,获取字符加入:首先根据vis数组,已经加入的元素不能再次加入了;同时,如果当前的元素str[i]与同一层的前一个元素str[i-1]相同且str[i-1]已经用过,也不需要将其纳入。
  • step 4:进入下一层递归前将vis数组当前位置标记为使用过。
  • step 5:回溯的时候需要修改vis数组当前位置标记,同时去掉刚刚加入字符串的元素。
  • step 6:临时字符串长度到达原串长度就是一种排列情况。

代码

import java.util.*;

public class Solution {
    public ArrayList<String> Permutation(String str) {
        ArrayList<String> res = new ArrayList<String>();
        if (str == null || str.length() == 0) {
            return res;
        }
        //转字符数组
        char[] charStr = str.toCharArray();
        // 按字典序排序
        Arrays.sort(charStr);
        boolean[] vis = new boolean[str.length()];
        //标记每个位置的字符是否被使用过
        Arrays.fill(vis, false);
        StringBuffer temp = new StringBuffer();
        //递归获取
        recursion(res, charStr, temp, vis);
        return res;
    }

    public void recursion(ArrayList<String> res, char[] str, StringBuffer temp, boolean[] vis) {
        //临时字符串满了加入输出
        if (temp.length() == str.length) {
            res.add(new String(temp));
            return;
        }
        //遍历所有元素选取一个加入
        for (int i = 0; i < str.length; i++) {
            //如果该元素已经被加入了则不需要再加入了
            if (vis[i]) {
                 continue;
            }
            if (i > 0 && str[i - 1] == str[i] && !vis[i - 1]) {
                //当前的元素str[i]与同一层的前一个元素str[i-1]相同且str[i-1]已经用过了
                continue;
            }
            //标记为使用过
            vis[i] = true;
            //加入临时字符串
            temp.append(str[i]);
            recursion(res, str, temp, vis);
            //回溯
            vis[i] = false;
            temp.deleteCharAt(temp.length() - 1);
        }
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/497750.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

[架构之路-191]-《软考-系统分析师》-8-软件工程 - 解答什么是面向功能的结构化程序设计:算法+数据结构 = 程序

目录 1. 什么是结构化程序设计 2. 结构化程序设计的局限性 3.程序设计的三种基本结构 (1) 顺序结构 (2) 选择结构 (3) 循环结构 1. 什么是结构化程序设计 功能 》 Function 》 函数 》 算法 数据流Data Flow 》 数据结构Data Strucuture 程序 算法 数据结构 》 数…

36. Kubernetes 网络原理——CNI 网络插件

本章讲解知识点 Flannel 原理概述直接路由的原理和部署示例Calico 插件原理概述1. Flannel 原理概述 Flannel 是一个用于容器网络的开源解决方案,它使用了虚拟网络接口技术(如 VXLAN)和 etcd 存储来提供网络服务。它的原理概述如下: Flannel 协助 Kubernetes,给每一个 No…

界面交互篇:答题页的答题逻辑交互开发

微信小程序云开发实战-答题积分赛小程序 界面交互篇:答题页的答题逻辑交互开发 前面的那一篇文章,我们已经完成了使用云开发的聚合能力实现从题库中随机抽取题目功能。 在页面加载时,实现从题库中随机抽取题目功能。那么,拿到数据后要干什么?如何做? 动态数据绑定 实…

c++练习题

1、默认参数练习 创建默认参数函数 void stars(int cols ,int rows ) 该函数默认缺省值cols是10 rows是1。该函数完成功能是根据行和列数显示一个由星号组成的矩形。在main函数仲按照默认值调用该函数。按照cols是5调用该函数。按照列数和行数是7&#xff0c;3 调用该函数 #…

【MMdetection训练及使用脚本系列】MMdetection训练1——如何保存最优的checkpoint文件

MMdetection如何保存最优的checkpoint文件 以目标检测为例&#xff0c;进入到 configs/_base_/datasets/coco_detection.py将evaluation dict(interval1, metricbbox)改为evaluation dict(interval1, metricbbox, save_bestauto)即可。 但是不建议这样做&#xff0c;防止以…

软件设计师笔记--数据结构

文章目录 前言学习资料数据结构大 O 表示法时间复杂度线性结构和线性表线性表的顺序存储线性表的链式存储栈的顺序存储栈的链式存储队列的顺序存储与循环队列 串KMP 数组矩阵树二叉树二叉树的顺序存储结构二叉树的链式存储结构二叉树的遍历平衡二叉树二叉排序树最优二叉树(哈夫…

C/C++每日一练(20230507) 数列第n项值I/II、简化路径

目录 1. 求数列的第n项的值 ※ 2. 求数列的第n项的值 II ※ 3. 简化路径 &#x1f31f;&#x1f31f; &#x1f31f; 每日一练刷题专栏 &#x1f31f; Golang每日一练 专栏 Python每日一练 专栏 C/C每日一练 专栏 Java每日一练 专栏 1. 求数列的第n项的值 已知数列…

摘要:PostgreSQL开发技术基础:过程与函数

原文地址 6.0 Language SQL与PL/pgSQL PL / PgSQL是基于SQL的特定于PostgreSQL的过程语言 。它有循环&#xff0c;variables&#xff0c;错误/exception处理等等。并不是所有的SQL都是有效的PL / PgSQL&#xff0c;正如你发现的那样&#xff0c;例如&#xff0c;你不能在没有…

Nature:时松海课题组揭示调控大脑新皮层神经元空间精细结构排布和环路组装的新机制

2022年12月7日&#xff0c;清华大学生命科学学院、清华-IDG/麦戈文脑科学研究院、生命科学联合中心、生物结构前沿研究中心时松海教授课题组在Nature杂志以长文的形式在线发表了题为“Patterned cPCDH expression regulates the fine organization of the neocortex”&#xff…

Python心经(2)

有关数字类型&#xff0c;字符串&#xff0c;函数 目录 有关数字类型&#xff0c;字符串&#xff0c;函数 数字 字符串 索引操作 切片操作 单个字符编码 运算符 还有一些常用的内置函数 Python输入函数 输出函数print()语法 python的函数也能给默认值 Python是个脚…

什么是事件驱动的微服务架构?

对于许多关键应用程序功能&#xff0c;包括流媒体和电子商务&#xff0c;单体架构已不再足够。随着实时事件数据和云服务使用的需求增加&#xff0c;许多现代应用程序&#xff0c;如Netflix和Lyft&#xff0c;已经转向了事件驱动的微服务方法。分离的微服务可以独立运行&#x…

体外诊断(IVD)高速发展

体外诊断&#xff08;IVD&#xff09;实际一直是临床的重要组成部分。体外诊断&#xff0c;是指通过对人体样本(血液、体液、组织等)进行检测而获取临床诊断信息&#xff0c;进而判断疾病或机体功能的产品和服务&#xff0c;其检测原理和方法涉及免疫学、微生物学、分子生物学等…

Cursor设置中文版 以及简单实用教程集成 GPT4 的代码神器 Cursor

官网&#xff1a;cursor.so 快捷键 ctrl K&#xff0c; 中英文提交需求&#xff0c;&#xff08;刚开始我整蹩脚的英语&#xff0c;后来发现支持中文&#xff09; 自动写代码 自动补充代码 自己修改代码 自动检查、完善代码 自己本地测试 然后再重复上面操作直到能用 最后让它…

ZooKeeper知识回顾(分布式协调框架,本质是分布式小文件存储系统,以分布式集群部署)

Apache ZooKeeperhttps://zookeeper.apache.org/官网为: 名字.apache.org 1.zookeep概念 一个团队里面&#xff0c;需要一个leader&#xff0c;leader是干嘛用的&#xff1f; &#xff08;分布式协调框架&#xff09; 1.管理什么的咱不说。 2.外面的人&#xff0c;想…

AI大神吴恩达与OpenAI官方合作推出的ChatGPT提示工程课,到底在讲什么?

ChatGPT提示工程课程&#xff0c;吴恩达&OpenAI 概述 本课程将着重介绍指令调优LM的开发最佳实践&#xff0c;以帮助开发人员利用LM技术构建聊天机器人等应用程序。 亮点 &#x1f4da; LM可用于快速构建软件应用程序&#xff0c;API可以使开发人员非常快速地构建。&#x…

怎么压缩照片到20k?

怎么压缩照片到20k&#xff1f;如今&#xff0c;手机摄影已经成为我们生活的一部分&#xff0c;我们经常使用手机拍照记录美好瞬间。但是&#xff0c;随着手机拍照像素的不断提高&#xff0c;照片的文件大小也越来越大&#xff0c;这使得手机的存储空间不够用&#xff0c;甚至在…

Vue核心 收集表单数据 过滤器

1.14. 收集表单数据 收集表单数据: 若: &#xff0c;则v-model收集的是value值&#xff0c;用户输入的就是value值。若: &#xff0c;则v-model收集的是value值&#xff0c;且要给标签配置value值。若: 没有配置input的value属性&#xff0c;那么收集的就是checked(勾选 or 未…

weblogic ssrf 漏洞复现

一.前言 Weblogic中存在一个SSRF漏洞&#xff0c;利用该漏洞可以发送任意HTTP请求&#xff0c;进而攻击内网中redis、fastcgi等脆弱组件。 二.环境搭建 在docker中开启环境 sudo docker-compose up -d sudo docker-compose ps #查看状态访问http://your-ip:7001/uddiexpl…

【C++】虚函数表 多态的原理 动态绑定和静态绑定

梳理虚函数表、多态原理、动静态绑定的知识 目录 一、虚函数表 二、多态的原理 三、动态绑定和静态绑定 一、虚函数表 在学习多态原理之前&#xff0c;我们需要了解一下虚函数表的概念 我们先一起来看下下面这段代码 // 这里常考一道笔试题&#xff1a;sizeof(Base)是多…

Centos7设置yum源

为什么要修改yum源呢&#xff1f; 因为默认的yum源下载速度很慢&#xff0c;所以我们需要修改yum源。我是用的阿里云的yum源 环境 虚拟机&#xff1a;VirtualBox 7.0.4 操作系统&#xff1a;CentOS 7 x86_64 查看默认的yum源 cd /etc/yum.repos.d将列出的所有默认yum源复…