剑指offer面试题28 字符串的全排列

来源:互联网 发布:excel不能导入数据 编辑:程序博客网 时间:2024/06/06 09:27
有重复全排列解题思路:
整体思路:可以把一个字符串看成两部分组成,第一部分为第一个字符,第二部分是后面的所有字符。这是典型的分治思想,可以用递归实现。

具体来说:第一步首先求所有可能出现在第一个位置上的字符,即把第一个字符和后面的所有的字符(包括第一个字符)进行交换。因字符串中可能有重复的字符,因此在交换前,需要判断从当前字符串的开始位置start到待交换位置end之前,是否有字符和end指向的字符相等,若有,则不进行交换,等到递归到那个字串的时候在进行交换,否则在结果中会出现重复元素。第二步固定第一个字符,求后面所有字符的全排列,过程同上。

import java.util.ArrayList;import java.util.Collections;public class Solution {public static ArrayList<String> Permutation(String str) {ArrayList<String> arrayList = new ArrayList<>();if (str == null || str.length() == 0) {return arrayList;}char[] charArray = str.toCharArray();int start = 0;int end = charArray.length - 1;arrayList = Permutation(charArray,start,end,arrayList);Collections.sort(arrayList);return arrayList;           }/** * 从start到end-1之间有没有元素和end指向元素相同,若有,则不进行交换,因为在此之前肯定进行了交换 */private static boolean isSwap(char[] charArray, int start, int end) {for (int i = start; i < end; i++) {if (charArray[i] == charArray[end]) {return false;}}return true;}private static ArrayList<String> Permutation(char[] charArray,int start, int end, ArrayList<String> arrayList) {if (start == charArray.length - 1) {//递归地结束条件String str = String.valueOf(charArray);arrayList.add(str);return arrayList;}for (int i = start; i < charArray.length; i++) {//如果在start到i-1之间,i元素已经出现过,则此时无需交换,因为在此之前已经交换了,避免重复if (!isSwap(charArray, start, i)) {continue;}swap(charArray, start, i);Permutation(charArray, start + 1, end,arrayList);swap(charArray, start, i);}return arrayList;}private static void swap(char[] charArray, int i, int j) {char temp = charArray[i];charArray[i] = charArray[j];charArray[j] = temp;}public static void main(String[] args) {String s = "abab";ArrayList<String> list = Permutation(s);for (int i = 0; i < list.size(); i++) {System.out.println(list.get(i));}}}


阅读全文
1 0
原创粉丝点击