剑指offer系列之26:字符串的排列
2016-04-12 14:43
453 查看
题目描述:输入一个字符串,按字典序打印出该字符串中字符的所有排列。例如输入字符串abc,则打印出由字符a,b,c所能排列出来的所有字符串abc,acb,bac,bca,cab和cba。 结果请按字母顺序输出。
输入描述:输入一个字符串,长度不超过9(可能有字符重复),字符只包括大小写字母。
思路:先不考虑是否出现重读字符,要对一个字符进行全排列,可以把第一个字符和后面的字符看成两部分,而第一个字符后面的字符又可看成第一个字符与后面两部分,这显然是一个递归的过程,只要第一个字符的位置没有到达字符串的末尾就分别将第一个字符与后面的字符进行交换。这里有一点需要注意:那就是比如第一个字符与后面的某个位置的字符发生交换后,需要再次发生交换,不然顺序就会被打乱。举个例子,在字符串abc中,在把第一个字符看成是a,后面的字符b、c看成一个整体的时候,abc这个相对顺序不能改变,所以当b与c发生交换变成了acb之后,需要再次交换两个字符,重新回到abc。
下面是一种非递归的实现:
输入描述:输入一个字符串,长度不超过9(可能有字符重复),字符只包括大小写字母。
思路:先不考虑是否出现重读字符,要对一个字符进行全排列,可以把第一个字符和后面的字符看成两部分,而第一个字符后面的字符又可看成第一个字符与后面两部分,这显然是一个递归的过程,只要第一个字符的位置没有到达字符串的末尾就分别将第一个字符与后面的字符进行交换。这里有一点需要注意:那就是比如第一个字符与后面的某个位置的字符发生交换后,需要再次发生交换,不然顺序就会被打乱。举个例子,在字符串abc中,在把第一个字符看成是a,后面的字符b、c看成一个整体的时候,abc这个相对顺序不能改变,所以当b与c发生交换变成了acb之后,需要再次交换两个字符,重新回到abc。
public ArrayList<String> permutation(String str) { ArrayList<String> list = new ArrayList<String>(); if (str == null || str.length() <= 0) return list; list = permutation(list, str.toCharArray(), 0, str.length()); Collections.sort(list); return list; } private ArrayList<String> permutation(ArrayList<String> list, char[] str, int begin, int length) { if (begin == length - 1) { if(!list.contains(String.valueOf(str))){ list.add(String.valueOf(str)); } } else { for (int i = begin; i < length; i++) { if(i == begin || str[i] != str[begin]){ swap(str, begin, i); permutation(list, str, begin + 1, length); swap(str, begin, i); } } } return list; } private void swap(char[] str, int begin, int i) { char temp = str[begin]; str[begin] = str[i]; str[i] = temp; }
下面是一种非递归的实现:
public ArrayList<String> permutation2(String str) { //使用TressSet是因为它是有序的 TreeSet<String> tree = new TreeSet<String>(); //创建一个栈保存每次排列的字符组合 Stack<String[]> stack = new Stack<String[]>(); //存放最终的排列结果 ArrayList<String> results = new ArrayList<String>(); stack.push(new String[] { str, "" }); do { //这里的popStrs就是str输入的字符串 String[] popStrs = stack.pop(); //空串 String oldStr = popStrs[1]; //str String statckStr = popStrs[0]; for (int i = statckStr.length() - 1; i >= 0; i--) { String[] strs = new String[] { statckStr.substring(0, i) + statckStr.substring(i + 1), oldStr + statckStr.substring(i, i + 1) }; if (strs[0].length() == 0) { tree.add(strs[1]); } else { stack.push(strs); } } } while (!stack.isEmpty()); for (String s : tree) results.add(s); return results; }
相关文章推荐
- 原生js实现百叶窗效果及原理介绍
- javascript中0级DOM和2级DOM事件模型浅析
- javascript的全局函数
- jquery学习之事件委派
- angular js点击tab中的li标签加载相应div区域
- 【前端】【转】JS跨域问题总结
- 剑指Offer--014-调整数组顺序使奇数位于偶数前面
- ajax返回json数组遍历添加到html
- jQueryx相关
- JS拼接字符串单引号与双引号的区别
- HTML&CSS——line-height设置成height使得文字居中
- JavaScript闭包
- 前端直接调用OC的native方法
- 【JS】:JS 日期类的使用
- HTML 5 Canvas
- the difference between min SDK version/target SDK version vs. compile SDK version?
- 几种获取IP 根据IP获取地址的方法 JS,第三方 新浪 网易 腾讯
- jquery实现简单的表单验证
- Obeject Tracking Reference
- JSP/Servlet处理系统异常的两种方式、路径(地址)问题、线程安全问题