题目描述

输入一个字符串,按字典序打印出该字符串中字符的所有排列。例如输入字符串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. 第二阶段Sprint冲刺会议1

    进展:总结第一阶段冲刺成就,讨论第二阶段任务,要实现的主要功能,分工及任务认领.

  2. 《Spring1之第九次站立会议》

    <第九次站立会议> 昨天:对用C#写的视频功能进行了相关的了解. 今天:试着把用C#写的代码转换为java语言. 遇到的问题:说实话,真心不好转换,转换过程中遇到了很多问题.

  3. Sdn - 基础题试水

    ## sdn - 初步分析基于OpenFlow的SDN网络控制功能 题目要求: 1.下发流表项实现 h1 和 h2,h2 和 h3 不能互通.h1 和 h3 可互通. 2.结合捕获的 SDN 相关协议 ...

  4. APP案例分析——Steam

    本次作业的分析对象是Steam,一款全球最大最广泛的游戏平台.之所以选择Steam是因为我已经在这上面挥洒了大量的青春,对它也有了很深的感情. 调研.评测 个人第一次上手体验 打开首页就可以看到琳琅满 ...

  5. 二路归并排序java实现

    二路归并排序:其核心思想时将问题一分为二,并递归调用一分为二方法,使问题分割到不能再分各的原子问题,然后再归并,从实现原子问题开始,层层向上归并,最终解决整体问题.即所谓“分而治之,万流归一” 二路归 ...

  6. 批量梯度下降(BGD)、随机梯度下降(SGD)以及小批量梯度下降(MBGD)的理解

      梯度下降法作为机器学习中较常使用的优化算法,其有着三种不同的形式:批量梯度下降(Batch Gradient Descent).随机梯度下降(Stochastic Gradient Descent ...

  7. psp本周

    四人项目: 日期 类别 内容 开始时间 结束时间 中断时间 净时间 10.4 站立会议 站立会议报告 21:12 21:37 0 25 结对项目: 日期 类别 内容 开始时间 结束时间 中断时间 净时 ...

  8. Delphi 判断TImage是否为空及注意事项

    Delphi 判断TImage是否为空:1)非空 Image1.Picture.Graphic <> nil2)为空 Image1.Picture.Graphic = nil注意不能用Im ...

  9. javascript获取当前日期和时间

    ){ ){ _time = year+"-"+month+"-"+date+" "+hour+":"+minu+&quo ...

  10. spring远程服务知识梳理

    序:本文主要是总结和归纳spring的远程服务相关知识,可作为入门学习笔记.写博客目的也是为了进行知识梳理,便于以后查看.本文主要参考资料 spring 实战第三版 本文主要讨论内容如下: 远程调度概 ...