题目:

输入一个字符串,按字典序打印出该字符串中字符的所有排列。例如输入字符串abc,则打印出由字符a,b,c所能排列出来的所有字符串abc,acb,bac,bca,cab和cba。

输入描述:

输入一个字符串,长度不超过9(可能有字符重复),字符只包括大小写字母。

分析:

可以采用递归和非递归两种方法实现。

递归方法使用交换的的思路,我们可以将字符串看成两部分,第一个字符和后面的字串,将第一个字符和后面的每一元素互换,这样就会产生新的排列,然后再递归执行后面的字串,具体流程如图:

出自:https://blog.csdn.net/zxzxzx0119/article/details/81452269

第二种方法可以先取一个元素到结果集,然后遍历字串剩余的元素将每一个元素插入到结果集中字符串的每一个位置,删掉取出的结果,再讲新结果存进结果集用{a,b,c}举例。

结果集中是{a}

取结果集字符串{a},并在结果集中删掉{a},将剩余元素b插入串{a}的每一个位置得到{b,a},{a,b}。

取{b,a},结果集还剩{a,b}

将c插入{b,a}得到{c,b,a},{b,c,a},{b,a,c},将三个结果添加进结果集,此时{a,b},{c,b,a},{b,c,a},{b,a,c}

再取出{a,b}将c插入得,{c,a,b},{a,c,b},{a,b,c},添加进结果集,此时{c,b,a},{b,c,a},{b,a,c},{c,a,b},{a,c,b},{a,b,c}

小技巧就是每次从结果集的后面取出元素,在前面插入新的结果。

不过这道题要求是有重复元素的,可以使用set来去重,不过牛客网的判题很迷,顺序不同也会判错。可以排个序再输出。

程序:

C++

class Solution {
public:
vector<string> Permutation(string str) {
if(str.size() == )
return res;
helper(str, );
for(auto i:tempRes)
res.push_back(i);
return res;
}
void helper(string str, int index){
if(index == str.size()-)
//res.push_back(str);
tempRes.insert(str);
for(int i = index; i < str.size(); ++i){
swap(str[index], str[i]);
helper(str, index+);
}
}
vector<string> res;
set<string> tempRes;
};
class Solution {
public:
vector<string> Permutation(string str) {
if(str.size() == )
return res;
res.push_back(str.substr(, ));
strSet.insert(str.substr(, ));
for(int i = ; i < str.size(); ++i){
int m = res.size();
for(int j = ; j < m; ++j){
string tempStr = res.back();
res.pop_back();
for(int k = ; k <= tempStr.size(); ++k){
string ttempStr = tempStr;
ttempStr.insert(k, str.substr(i,));
set<string>::iterator iter;
if((iter = strSet.find(ttempStr)) == strSet.end()){
res.insert(res.begin(), ttempStr);
strSet.insert(ttempStr);
}
}
}
}
sort(res.begin(), res.end());
return res;
}
private:
set<string> strSet;
vector<string> res;
};

Java

import java.util.ArrayList;
import java.util.Collections;
//import java.util.HashSet;
public class Solution {
public ArrayList<String> Permutation(String str) {
if(str.length() == 0)
return res;
StringBuilder s = new StringBuilder(str);
Helper(s, 0);
Collections.sort(res);
return res;
}
public void Helper(StringBuilder s, int index){
if(index == s.length()-1)
res.add(s.toString());
for(int i = index; i < s.length(); ++i){
if(s.charAt(index) != s.charAt(i) || index == i){
Swap(s, index, i);
Helper(s, index+1);
Swap(s, index, i);
}
}
}
public static void Swap(StringBuilder s, int i, int j) {
char temp = s.charAt(i);
s.setCharAt(i, s.charAt(j));
s.setCharAt(j, temp);
}
private ArrayList<String> res = new ArrayList<>();
//private HashSet<String> set = new HashSet<>();
}

剑指Offer-27.字符串的排列(C++/Java)的更多相关文章

  1. 剑指Offer 27. 字符串的排列 (字符串)

    题目描述 输入一个字符串,按字典序打印出该字符串中字符的所有排列.例如输入字符串abc,则打印出由字符a,b,c所能排列出来的所有字符串abc,acb,bac,bca,cab和cba. 输入描述: 输 ...

  2. [剑指Offer] 27.字符串的排列

    [思路]从第一位开始,判断每一位字符的所有可能性,依此递归. class Solution { public: void PermutationHelp(vector<string> &a ...

  3. 剑指 Offer 38. 字符串的排列 + 无重复元素的全排列

    剑指 Offer 38. 字符串的排列 Offer_38 题目描述 解题思路 可以使用递归实现全排列,每次都确定一个数的位置,当所有位置的数都确定后即表示一个排列. 但是考虑到本题需要排除重复的排列, ...

  4. 剑指 Offer 38. 字符串的排列

    剑指 Offer 38. 字符串的排列 输入一个字符串,打印出该字符串中字符的所有排列. 你可以以任意顺序返回这个字符串数组,但里面不能有重复元素. 示例: 输入:s = "abc" ...

  5. 【剑指Offer】字符串的排列 解题报告(Python)

    [剑指Offer]字符串的排列 解题报告(Python) 标签(空格分隔): LeetCode 题目地址:https://www.nowcoder.com/ta/coding-interviews 题 ...

  6. 【Java】 剑指offer(38) 字符串的排列

    本文参考自<剑指offer>一书,代码采用Java语言. 更多:<剑指Offer>Java实现合集   题目 输入一个字符串,打印出该字符串中字符的所有排列.例如输入字符串ab ...

  7. Go语言实现:【剑指offer】字符串的排列

    该题目来源于牛客网<剑指offer>专题. 输入一个字符串,按字典序打印出该字符串中字符的所有排列.例如输入字符串abc,则打印出由字符a,b,c所能排列出来的所有字符串abc,acb,b ...

  8. 《剑指offer》字符串的排列

    本题来自<剑指offer> 反转链表 题目: 思路: C++ Code: Python Code: 总结:

  9. 剑指offer:字符串的排列

    题目描述: 输入一个字符串,按字典序打印出该字符串中字符的所有排列.例如输入字符串abc,则打印出由字符a,b,c所能排列出来的所有字符串abc,acb,bac,bca,cab和cba. 输入描述: ...

  10. 剑指OFFER之字符串的排列(九度OJ1369)

    题目描述: 输入一个字符串,按字典序打印出该字符串中字符的所有排列.例如输入字符串abc,则打印出由字符a,b,c所能排列出来的所有字符串abc,acb,bac,bca,cab和cba. 输入: 每个 ...

随机推荐

  1. [Tarjan系列] Tarjan算法与有向图的SCC

    前面的文章介绍了如何用Tarjan算法计算无向图中的e-DCC和v-DCC以及如何缩点. 本篇文章资料参考:李煜东<算法竞赛进阶指南> 这一篇我们讲如何用Tarjan算法求有向图的SCC( ...

  2. SpringBoot整合SSM(代码实现Demo)

    SpringBoot整合SSM 如图所示: 一.数据准备: 数据库文件:数据库名:saas-export,表名:ss_company 创建表语句: DROP TABLE IF EXISTS ss_co ...

  3. 开源.Net Standard版华为物联网北向接口SDK

    最近用到了华为的物联网平台API,但是官方没有.Net版的SDK,所以就自己封装了一个,开源出来给有需要的朋友,同时也算是为.Net Core的发展做点小贡献~ 源码地址:https://github ...

  4. Mybaits 源码解析 (九)----- 全网最详细,没有之一:一级缓存和二级缓存源码分析

    像Mybatis.Hibernate这样的ORM框架,封装了JDBC的大部分操作,极大的简化了我们对数据库的操作. 在实际项目中,我们发现在一个事务中查询同样的语句两次的时候,第二次没有进行数据库查询 ...

  5. os模块操作文件

    os模块: path=os.path.join(os.path.dirname(os.path.dirname(__file__)),'images') path:运行脚本的当前文件下的上一个文件的地 ...

  6. 【RocketMQ源码学习】- 3. Client 发送同步消息

    本文较长,代码后面给了方法简图,希望给你帮助 发送的方式 同步发送 异步发送 消息的类型 普通消息 顺序消息 事务消息 发送同步消息的时序图 为了防止读者朋友嫌烦,可以看下时序图,后面我也会给出方法的 ...

  7. 《JS高程》-教你如何写出可维护的代码

    1.前言   在平时工作开发中,大部分开发人员都花费大量的时间在维护其他人员的代码.很难从头开始开发新代码,很多情况下都是以他人成果为基础的,或者新增修改需求,自己写的代码也会被其他开发人员调用,所以 ...

  8. 802.11n速率集

  9. Python OpenCV4趣味应用系列(四)---颜色物体实时检测

    今天,我们来实现一个视频实时检测颜色物体的小实例,视频中主要有三个颜色物体,我们只检测红色和绿色的球状物体,如下图所示: 第一步需要打开视频(或者摄像头): cap = cv2.VideoCaptur ...

  10. linux中dd相关命令骚操作

    一.dd如何快速将磁盘写满 方法一: dd if=/dev/zero of=/tmp/file bs=1G count=10 # 参数解释 1. if=文件名:输入文件名,缺省为标准输入.即指定源文件 ...