题目描述

输入一个字符串,按字典序打印出该字符串中字符的所有排列。例如输入字符串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. Class 2 四则运算2的设计思路

    设计思路 1.主函数中有一个大的for循环,用户可以一直随机得到相应题目.在嵌套一个循环,其可以直接确定题目数量:定义两个变量,分别作为四则运算的两个运算数,用随机数函数得到两个数值:再利用随机生成函 ...

  2. Socket 记录

    心跳检测步骤:1客户端每隔一个时间间隔发生一个探测包给服务器2客户端发包时启动一个超时定时器3服务器端接收到检测包,应该回应一个包4如果客户机收到服务器的应答包,则说明服务器正常,删除超时定时器5如果 ...

  3. DispatcherServlet的作用

    DispatcherServlet是前端控制器设计模式的实现,提供Spring Web MVC的集中访问点,而且负责职责的分派,而且与Spring IoC容器无缝集成,从而可以获得Spring的所有好 ...

  4. Spring框架的补充

    1.使用xml文件方式配置bean ——property标签ref属性和ref标签区别 <property name=“bean” ref="myBbean" /> r ...

  5. Qt之美(一):d指针/p指针详解(二进制兼容,不能改变它们的对象布局)

    Translated  by  mznewfacer   2011.11.16 首先,看了Xizhi Zhu 的这篇Qt之美(一):D指针/私有实现,对于很多批评不美的同路人,暂且不去评论,只是想支持 ...

  6. java中为什么要进行对象序列化?

    序列化其实很好理解,假如你现在做一个项目,项目是分工合作的,并且你喝其他小组成员不在同一个城市,那么你要如何把你写的那些类给其他小组成员呢?这个时候就要用到序列化了,简单的说:序列化就是将内存中的类或 ...

  7. Code Blocks中配置OpenGL

    使用的文件:我的CSDN资源共享 将glut.h文件放到MinGw\include\GL目录下面 将glut32.dll文件放到C:\windows\system32目录下面(如果是64位操作系统的话 ...

  8. js复制内容到剪切板

    注意第一部分的内容不兼容Safari,全兼容的请使用第二部分方法 第一部分 查看demo请点  这里. 原生js复制指定内容到剪切板,超简单的实现方式, 实现思路如下: 1.创建一个input,把想要 ...

  9. js浏览器缩放提示

    data() { return { instance: null, isZoomOpen: false }; }, mounted() { const that = this; this.isZoom ...

  10. python selenium判断元素是否存在的问题

    爬虫的时候经常用到这个,找到了一个比较好用的方法 原文链接:http://blog.csdn.net/u012189659/article/details/36391837 背景:selenium+p ...