字符串的排列

2年前 (2022) 程序员胖胖胖虎阿
189 0 0

输入一个字符串,按字典序打印出该字符串中字符的所有排列。例如输入字符串 abc,则按字典序打印出所能排列出来的所有字符串 abc,acb,bac,bca,cab,cba

解题思路

字符串的排列

我们假设这么一个场景:

  • 固定 A 为字符串开头,要知道以 A 开头的组合有多少,则必须知道 A 之后的字符串(B、C)能构成多少种组合
    • 固定 B 为字符串开头,要知道以 B 开头的组合有多少,则必须知道 B 之后的字符串能构成多少种组合,但这时剩下的字符只有 C 了,所以得出一个组合就是 ABC
    • 固定 C 为字符串开头,要知道以 C 开头的组合有多少,则必须知道 C 之后的字符串能构成多少种组合,但这时剩下的字符只有 B 了,所以得出一个组合就是 ACB
  • 固定 B .....

可以发现这是一个递归的过程,或者说基于回溯法的思想。这个规律可以简单总结成:

  • 固定第一个字符,递归取得首位后面的各种字符串组
  • 再把第一个字符与后面每一个字符交换,并同样递归获得首位后面的字符串组合
  • 递归的出口,就是只剩一个字符的时候,递归的循环过程,就是从每个子串的第二个字符开始依次与第一个字符交换,然后继续处理子串
import java.util.ArrayList;
import java.util.Collections;
public class Solution {
    public ArrayList<String> Permutation(String str) {
        ArrayList<String> list = new ArrayList<>();
        if(str != null && str.length() > 0) {
            PermutationHelper(list, str.toCharArray(), 0);
            Collections.sort(list);
        }
        return list;
    }

    public void PermutationHelper(ArrayList<String> list, char[] characters, int i) {
    	// 如果只剩一个字符,则比较结果集中是否已存在当前组合,没有就添加
        if(i == characters.length - 1) {
            String str = new String(characters);
            if(!list.contains(str)) {
                list.add(str);
            }
        } else {
        	// 递归的主体,第一次交换相当于固定字符,之后还要交换回来
            for(int j = i; j < characters.length; j++) {
                swap(characters, i, j);
                PermutationHelper(list, characters, i + 1);
                swap(characters, i, j);
            }
        }
    }
    
    public void swap(char[] characters, int i, int j) {
        char temp = characters[i];
        characters[i] = characters[j];
        characters[j] = temp;
    }
}

版权声明:程序员胖胖胖虎阿 发表于 2022年11月22日 下午2:48。
转载请注明:字符串的排列 | 胖虎的工具箱-编程导航

相关文章

暂无评论

暂无评论...