每天一道算法题——字符串的排列
2018-03-30 23:13
204 查看
前言:
这几天有点忙,这一个月没两天更新一次吧
题目描述
输入一个字符串,按字典序打印出该字符串中字符的所有排列。例如输入字符串abc,则打印出由字符a,b,c所能排列出来的所有字符串abc,acb,bac,bca,cab和cba。
测试用例:
abc
对应输出应该为:
[“abc”,”acb”,”bac”,”bca”,”cab”,”cba”]
错误的输出
[“bac”,”abc”,”acb”,”bca”,”cba”,”cab”]
没有进行排序,调用一下sort就好Collections.sort(list),不必要重新写一个函数吧,那就本末倒置了。
分析:
第一种使用递归的方法来解决此题。详情见代码。比较容易懂。
第二种方法是使用一个ArrayList将各个排列结果存放其中。首先将字符串分解为字符数组,然后从大到小进行排列后再对数组元素的值进行替换。直到形成最后的“最小的排列”,此时所有排列已经存储在了ArrayList之中了。返回ArrayList即可。称这种排列方式为字典排列。形如其名,就是按照词典排列的方式,将所有“词”无重复地录入到ArrayList这个“词典”当中。
源码:
递归的方法:
字典排列:
运行测试:
递归:运行时间:126ms 占用内存:13412k
字典排列:运行时间:96ms 占用内存:11864k
总结:
可以看到使用递归解决时还是占用相当多的资源的。所以如果需要做优化的话,可以将递归替换掉,虽然递归的条理更加清楚一点。
这几天有点忙,这一个月没两天更新一次吧
题目描述
输入一个字符串,按字典序打印出该字符串中字符的所有排列。例如输入字符串abc,则打印出由字符a,b,c所能排列出来的所有字符串abc,acb,bac,bca,cab和cba。
测试用例:
abc
对应输出应该为:
[“abc”,”acb”,”bac”,”bca”,”cab”,”cba”]
错误的输出
[“bac”,”abc”,”acb”,”bca”,”cba”,”cab”]
没有进行排序,调用一下sort就好Collections.sort(list),不必要重新写一个函数吧,那就本末倒置了。
分析:
第一种使用递归的方法来解决此题。详情见代码。比较容易懂。
第二种方法是使用一个ArrayList将各个排列结果存放其中。首先将字符串分解为字符数组,然后从大到小进行排列后再对数组元素的值进行替换。直到形成最后的“最小的排列”,此时所有排列已经存储在了ArrayList之中了。返回ArrayList即可。称这种排列方式为字典排列。形如其名,就是按照词典排列的方式,将所有“词”无重复地录入到ArrayList这个“词典”当中。
源码:
递归的方法:
import java.util.ArrayList; import java.util.Collections; public class Test1 { public class Solution { public ArrayList<String> Permutation(String str) { ArrayList<String> list = new ArrayList<>(); if (list!=null&&str.length()!=0) { Permutation(str.toCharArray(),0,list); Collections.sort(list); } return (ArrayList<String>) list; } private void Permutation(char[] charArray, int i, ArrayList<String> list) { if (i==charArray.length-1) { String val = String.valueOf(charArray); if (!list.contains(val)) { list.add(val); } }else { for (int j = 0; j < charArray.length; j++) { swap(charArray,i,j); Permutation(charArray, i+1, list); swap(charArray,i,j); } } } private void swap(char[] charArray, int i, int j) { char temp = charArray[i]; charArray[i] = charArray[j]; charArray[j] = temp; } } }
字典排列:
import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; public class Test1 { public class Solution { public ArrayList<String> Permutation(String str) { ArrayList<String> res = new ArrayList<>(); if (str != null && str.length() > 0) { char[] seq = str.toCharArray(); Arrays.sort(seq); // 排列 res.add(String.valueOf(seq)); // 先输出一个解 int len = seq.length; while (true) { int p = len - 1, q;// 从后向前找一个seq[p - 1] < seq[p] while (p >= 1 && seq[p - 1] >= seq[p]) --p; if (p == 0) break; // 已经是“最小”的排列,退出 // 从p向后找最后一个比seq[p]大的数 q = p; --p; while (q < len && seq[q] > seq[p]) q++; --q;// 交换这两个位置上的值 swap(seq, q, p); // 将p之后的序列倒序排列 reverse(seq, p + 1); res.add(String.valueOf(seq)); } } return res; } public void reverse(char[] seq, int start) { int len; if(seq == null || (len = seq.length) <= start) return; for (int i = 0; i < ((len - start) >> 1); i++) { int p = start + i, q = len - 1 - i; if (p != q) swap(seq, p, q); } } public void swap(char[] cs, int i, int j) { char temp = cs[i]; cs[i] = cs[j]; cs[j] = temp; } } }
运行测试:
递归:运行时间:126ms 占用内存:13412k
字典排列:运行时间:96ms 占用内存:11864k
总结:
可以看到使用递归解决时还是占用相当多的资源的。所以如果需要做优化的话,可以将递归替换掉,虽然递归的条理更加清楚一点。
相关文章推荐
- 每天一道算法题(21)——字符串的全排列和组合算法
- 每天一道算法题(21)——字符串的全排列和组合算法
- 每天一道算法题9 字符串的排列
- 一道字符串排列组合算法题
- 每天一道算法题(7)——在字符串中删除特定的字符
- 每天一道算法题——求全排列
- 每天一道算法题(7)——在字符串中删除特定的字符
- 每天一道算法题(5)——求2个字符串的最长公共子序列和最长公共子字符串
- 每天一道算法题(5)——求2个字符串的最长公共子序列和最长公共子字符串
- 每天一道算法题(35)——删除字符串首尾的空格
- 每天一道算法题(25)——字符串中连续出现次数最多的子串
- 每天一道算法题(35)——删除字符串首尾的空格
- 每天一道算法题12 在字符串中删除特定的字符
- 【每天一道算法题】字符串查找
- 每天一道算法题(25)——字符串中连续出现次数最多的子串
- 每天一道算法题(29)——检测字符串的是否由移位得到
- 每天一道算法题(29)——检测字符串的是否由移位得到
- 每天一道算法题1 判断字符串是否是回文字符串或者是否含有回文字符子串
- 每天一道算法题(26)——输入字符串表达式求值
- 每天一道算法题17 左旋转字符串