Loading

Medium | 剑指 Offer 38. 字符串的排列 | 回溯

剑指 Offer 38. 字符串的排列

输入一个字符串,打印出该字符串中字符的所有排列。

你可以以任意顺序返回这个字符串数组,但里面不能有重复元素。

示例:

输入:s = "abc"
输出:["abc","acb","bac","bca","cab","cba"]

限制:

1 <= s 的长度 <= 8

解题思路: 回溯算法 + 排列问题

  1. 如何获得所有的排列:

首先尝试着把所有元素放到第一位, 可以通过交换的方式, 然后递归后面的字符串。并且由于输入字符串有重复元素, 而输出不允许有重复, 可以在每个递归的方法内 , 设置一个set, 来保存所有已经放到当前位置的所有字符。

private List<String> res = new ArrayList<>();

public String[] permutation(String s) {
    char[] c = s.toCharArray();
    permutation(c, 0);
    return res.toArray(new String[0]);
}

public void permutation(char[] c, int index) {
    // 递归出口
    if (index == c.length) {
        res.add(String.valueOf(c));
        return;
    }
    Set<Character> set = new HashSet<>();
    // 把后面的所有元素依次放到当前index位置上
    for(int i = index; i < c.length; i++) {
        if (set.contains(c[i])) { // c[i]这个数字曾经放到index位置过, 进行剪枝
            continue;
        }
        set.add(c[i]);   // 记录放到index位置的每个元素
        swap(c, index, i); 
        // 递归后面的元素
        permutation(c, index+1);
        // 将交换过的元素还原回来
        swap(c, index, i);
    }
}

public void swap(char[] arr, int idx1, int idx2) {
    if (idx1 == idx2) return;
    char temp = arr[idx1];
    arr[idx1] = arr[idx2];
    arr[idx2] = temp;
}
posted @ 2021-01-15 16:45  反身而诚、  阅读(71)  评论(0编辑  收藏  举报