题目描述

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

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

这里尤其需要注意2点:1.所有组合不能重复,比如输入"aa",  那么输出的结果应当是“aa” ; 2. 输出结果按字典序排序

如果用《剑指offer》上的方法,显然这两点都不能满足,比如输入"abc",输出结果为:"abc" "acb" "bac" "bca"  "cba" "cab" ,如果输入"aa",输出解过为"aa" "aa" 。显然,这两种结果都是有问题的。

下面是《剑指offer》版本的代码:

 import java.util.ArrayList;
import java.util.List;
public class Solution {
private List<String> list = new ArrayList<>();
private StringBuffer buffer;
public ArrayList<String> Permutation(String str) {
if(str==null||str.length()==0) return (ArrayList<String>) list;
buffer = new StringBuffer(str);
PermutationCore(0);
return (ArrayList<String>) list;
}
public void PermutationCore(int begin) {
if(begin==buffer.length()-1){
list.add(buffer.toString());
}
for(int i = begin;i<buffer.length();i++){
swap(begin,i);
PermutationCore(begin+1);
swap(begin,i);
}
}
public void swap(int i,int j){
char a = buffer.charAt(i);
char b = buffer.charAt(j);
buffer.setCharAt(i, b);
buffer.setCharAt(j, a);
}
}

那么如何解决上面两点存在的问题呢?这里给推荐一种数据结构,TreeSet。 这个在C++中我不知道有没有,应该是没有,但是作为Java程序员,这是比较幸福的地方。

TreeSet这个数据结构本身采用红黑树实现,能够自动将字符串按照字典序排序,同时因为其实现了Set接口,所以又能同时保证所有的结果是一个集合。而学过离散数学的朋友都知道,集合中的元素是不会重复的,所以如果我们采用TreeSet对排列的结果进行存储,那么就能轻易的达到上述要求。下面是本人实现的代码:

 import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.TreeSet;
public class Solution {
private List<String> list = new ArrayList<>();
private Set<String> set = new TreeSet<>();
private StringBuffer buffer;
public ArrayList<String> Permutation(String str) {
if(str==null||str.length()==0) return (ArrayList<String>) list;
buffer = new StringBuffer(str);
PermutationCore(0);
Iterator<String> iterator = set.iterator();
while(iterator.hasNext()){
list.add(iterator.next());
}
return (ArrayList<String>) list;
}
public void PermutationCore(int begin) {
if(begin==buffer.length()-1){
set.add(buffer.toString());
}
for(int i = begin;i<buffer.length();i++){
//if(buffer.charAt(i)==buffer.charAt(begin) && begin!=i) continue;
swap(begin,i);
PermutationCore(begin+1);
swap(begin,i);
}
}
public void swap(int i,int j){
char a = buffer.charAt(i);
char b = buffer.charAt(j);
buffer.setCharAt(i, b);
buffer.setCharAt(j, a);
}
}

输入“abc” ,输出:"abc" "acb" "bac" "bca" "cab" "cba"  ; 输入“aaa”,输出"aaa" ,显然符合要求了。

最后我们来看一看TreeSet的层次结构:

类似的结构还有ArrayList,LinkedList,HashSet,HashMap,TreeMap,PriorityQueue,Stack。另外重要的接口有:List,Set,Map,Queue,Deque,Comparator,Comparable,Itrerator。这些都是在编写数据结构和算法的时候经常用到的,尤其需要留意。

《剑指offer》面试题28:字符串的排列(牛客网版本) java的更多相关文章

  1. C++版 - 剑指offer面试题28: 字符串的排列

    题目: 字符串的排列 热度指数:5777 时间限制:1秒 空间限制:32768K 本题知识点: 字符串 题目描述 输入一个字符串,按字典序打印出该字符串中字符的所有排列.例如输入字符串abc,则打印出 ...

  2. 剑指Offer:面试题28——字符串的排列(java实现)(待序)

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

  3. 剑指offer 面试题38 字符串的排列

    我惯用的dfs模板直接拿来套 class Solution { public: vector<string> Permutation(string str) { if(str.empty( ...

  4. 剑指Offer - 九度1369 - 字符串的排列

    剑指Offer - 九度1369 - 字符串的排列2014-02-05 21:12 题目描述: 输入一个字符串,按字典序打印出该字符串中字符的所有排列.例如输入字符串abc,则打印出由字符a,b,c所 ...

  5. 剑指Offer:面试题15——链表中倒数第k个结点(java实现)

    问题描述 输入一个链表,输出该链表中倒数第k个结点.(尾结点是倒数第一个) 结点定义如下: public class ListNode { int val; ListNode next = null; ...

  6. 剑指offer(27)字符串的排列

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

  7. 【剑指Offer】27、字符串的排列

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

  8. 剑指Offer:面试题12——打印1到最大的n位数(java实现)

    问题描述: 输入数字n,按顺序打印出从1到最大的n位十进制数,比如输入3,则打印出1,2,3一直到最大的3位数即999. 思路1:最简单的想法就是先找出最大的n位数,然后循环打印即可. public ...

  9. 剑指offer面试题3 二维数组中的查找 (java)

    注:java主要可以利用字符串的length方法求出长度解决这个问题带来方便 public class FindNum { public static void main(String[] args) ...

  10. 剑指offer二十七之字符串的排列

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

随机推荐

  1. 20135316王剑桥 linux第三周课实验笔记

    通过使用标准的字符码能够对文档中的字母和符号进行编码. 三种重要的数字表现形式: 1. 无符号数:编码基于传统的二进制表示法表示大于或等于零的数字. 2. 补码:编码是表示有符号整数的最常见方法,可以 ...

  2. 奔跑吧DKY——团队Scrum冲刺阶段-Day 2

    今日完成任务 各个成员今日完成的任务(如果完成的任务为开发或测试任务,需给出对应的Github代码签入记录截图:如果完成的任务为调研任务,需给出对应的调研总结博客链接:如果完成的任务为学习技术任务,需 ...

  3. android实战开发02

    正如我之前提到的,我想的是网页来进行测试发布是有较大难度的,但是我高兴的看到我的好友limary已经熬出头了,之后我会关注他的进度的,感谢他给我的鼓励和启发.现在我要讲讲我的天才运算器V2.0版. 在 ...

  4. 校友聊NABCD需求分析

    校友聊 NABCD需求分析 N:内网用户流量不够使用 A:基于局域网进行通讯 B:通讯不花费外网流量 C:目前学校还没有使用 D:将软件放在校园网,可以下载使用

  5. 使用Axure RP设计Android界面原型

    转至@徐州瑞步科技(http://www.cnblogs.com/brooks-dotnet/archive/2013/06/05/3119923.html) 资源地址:http://pan.baid ...

  6. Mac下OpenCV开发环境配置(Terminal和Xcode)

    亲证可用:http://www.jianshu.com/p/11959977589a   Mac OS X 10.1 Xcode 7.2(7C68) OpenCV 2.4.13 Mac OS10.11 ...

  7. Swift-懒加载使用

    //    懒加载 lazy var tableView : UITableView = {         let tempTableView = UITableView()         ret ...

  8. sprintf函数 %6.2f

    %6.2f6表示数据表示至少6位,后面的.2表示小数点后保留两位 比如2342.123415用这个表示的话,结果就是2342.12如果不足六位就会在前面补空格超过六位的话正常显示 代码例子:int m ...

  9. win10频繁提示证书即将过期怎么办

    最近几天每次开机都会提示许可证即将过期 ”Windows+R”打开“运行”窗口,输入“slmgr.vbs -xpr”并点击“确定”,弹出的窗口确实显示过期时间在本月1.29过期 百度各种激活方法后,发 ...

  10. #Leetcode# 451. Sort Characters By Frequency

    https://leetcode.com/problems/sort-characters-by-frequency/ Given a string, sort it in decreasing or ...