面试题38. 字符串的排列

题目:

面试题38. 字符串的排列
面试题38. 字符串的排列_第1张图片

题解:

面试题38. 字符串的排列_第2张图片
面试题38. 字符串的排列_第3张图片
在这里插入图片描述
面试题38. 字符串的排列_第4张图片
面试题38. 字符串的排列_第5张图片
在这里插入图片描述
面试题38. 字符串的排列_第6张图片

代码:

import java.util.*;

public class 面试题38 {

    public static String[] permutation(String s) {
        Set<String> set = new TreeSet<>();  // 所有排列的可能都在这里
        if(s != null || s.length() > 0)
        {
            int n = s.length();
            char str[] = s.toCharArray();
            Arrays.sort(str); // 输入字符串如果是乱序,则需要先按照从小到大的顺序排列
            backtrack(str, 0, n - 1, set);
        }
        String res[] = new String[set.size()];
        int i = 0;
        for(String str: set)
        {
            res[i++] = str;
        }
        return res;
    }

    public static void backtrack(char s[], int begin, int end, Set<String> set)
    {
        if(begin == end)
        {
            String str = String.valueOf(s);
            set.add(str); // 添加排列方案
        }
        for(int i = begin; i <= end; i++)
        {
            swap(s, i, begin);  // 交换,将 s[i] 固定在第 begin 位 (依次选一个数固定住)
            backtrack(s, begin + 1, end, set); // 开启固定第 begin + 1 位的字符(让后面的进行全排列)
            swap(s, i, begin);  // 恢复交换(恢复原来的模样,回溯关键)
        }
    }

    public static void swap(char s[], int i, int j)
    {
        char temp = s[i];
        s[i] = s[j];
        s[j] = temp;
    }

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        while(sc.hasNext())
        {
            String str = sc.next();
            String res[] = permutation(str);
            for(int i = 0; i < res.length; i++)
            {
                System.out.println(res[i]);
            }
            System.out.println();
        }
    }   
}

参考:

  1. 面试题38. 字符串的排列(回溯法,清晰图解)
  2. 回溯算法(Java)
  3. 回溯,使用set去重
  4. 两种回溯解法:Set去重和排序去重

你可能感兴趣的:(剑指Offer)