剑指offer:字符串的排列
http://blog.csdn.net/libing13820393394/article/details/45072029?ref=myread
输入一个字符串,按字典序打印出该字符串中字符的所有排列。例如输入字符串abc,则打印出由字符a,b,c所能排列出来的所有字符串abc,acb,bac,bca,cab和cba。
要考虑全排列的非递归实现,先来考虑如何计算字符串的下一个排列。如"1234"的下一个排列就是"1243"。只要对字符串反复求出下一个排列,全排列的也就迎刃而解了。
如何计算字符串的下一个排列了?来考虑"926520"这个字符串,我们从后向前找第一双相邻的递增数字,"20"、"52"都是非递增的,"26 "即满足要求,称前一个数字2为替换数,替换数的下标称为替换点,再从后面找一个比替换数大的最小数(这个数必然存在),0、2都不行,5可以,将5和2交换得到"956220",然后再将替换点后的字符串"6220"颠倒即得到"950226"。
对于像“4321”这种已经是最“大”的排列,采用STL中的处理方法,将字符串整个颠倒得到最“小”的排列"1234"并返回false。
public ArrayList<String> Permutation(String str) { java.util.ArrayList<String> list = new java.util.ArrayList<String>(); if(str==null||str.length()==0){ return list; } //先把初始字符串加进去 list.add(str); //对全部字符排序 char[] data = str.toCharArray(); Arrays.sort(data); //存在后续字符串则符合条件 while (hasNext(data)) { //获取后续字符串 next(data); //打印 StringBuilder sb = new StringBuilder(); for (int i = 0; i < data.length; i++) { sb.append(data[i]); } list.add(sb.toString()); } return list; } public boolean hasNext(char[] data) { for(int i=data.length-1;i>0;i--) if(data[i]>data[i-1]) return true; return false; } public void next(char[] data) { int top=0; int mm=0; //1.找到峰值 for ( int i=data.length-1;i>0;i--)if(data[i] > data[i-1]){top = i;break;} //2.1找到交换的数,大于峰值前一个数的 最小的数 mm = top-1; int max=top; for ( int i=top+1;i<data.length;i++) if(data[i]<data[max]&&data[i]>data[mm]){ max = i; } //2.2交换 char tmp = data[mm]; data[mm] = data[max]; data[max] = tmp; //3颠倒后面的数 int end = data.length-1; int middle=(top+end)/2; while(top<=middle){ tmp = data[top]; data[top] = data[end]; data[end] = tmp; top++; end--; } }
递归
- 把字符串分成两部分,一部分是第一个字符,另一个部分是后面其余的字符串
- 拿第一个字符和后面的字符串依次交换,这是一个递归的过程
- 注意:在递归里第一次交换是自身和自身的交换,保证不缺少字符串
public ArrayList<String> Permutation(String str) { ArrayList<String> list = new ArrayList<String>(); if (str == null || str.length() == 0) { return list; } char[] strArr = str.toCharArray(); permu(list, strArr, 0); Collections.sort(list); return list; } public void permu(ArrayList<String> list, char[] strArr, int start) { if (start == strArr.length - 1) { String result = String.valueOf(strArr); if (list.indexOf(result) < 0) { list.add(String.valueOf(strArr)); } } for (int i = start; i < strArr.length; i++) { char temp = strArr[i]; strArr[i] = strArr[start]; strArr[start] = temp; permu(list, strArr, start + 1); temp = strArr[i]; strArr[i] = strArr[start]; strArr[start] = temp; } return; }
posted on 2017-08-28 16:30 zhangxiaoyu 阅读(196) 评论(0) 收藏 举报
浙公网安备 33010602011771号