编程语言爱好者算法编程数据结构和算法分析

【算法】排列问题

2018-06-07  本文已影响25人  黑暗终将过去

一、问题

描述

给定一个字符串,求它的全排列。

示例输入

abc

示例输出

abc
acb
bac
bca
cba
cab

二、分析

在高中数学中,求所有的排列,我们往往会按每个开头的有几种进行列举。比如abc,我们会分析所有a开头的有几个,b开头的有几个,依次列举。
在a开头的里面,再进行继续列举,a开头前提下,剩下的b开头有几个,c开头有几个。
可以看见这个过程和分治思想非常像。分治思想的解决方法是使用递归。
递归关心两个:

注意:这里需要判断字符是否有相同,即如果s1 ~ sn有相同的,那就应该跳过计算。所以需要记录下已经开头过的,可以用Set进行存储。

三、代码

import java.util.HashSet;
import java.util.Scanner;
import java.util.Set;

public class Main {
    public static void main(String []args) {
        Scanner in = new Scanner(System.in);
        String str = in.nextLine();
        char[] list = str.toCharArray();
        perm(list, 0, list.length - 1);
    }
    
    //对list[s]到list[e]进行排列
    public static void perm(char[] list, int s, int e) {
        //结束递归
        if (s == e) {
            System.out.println(String.valueOf(list));
            return;
        }
        //开始递归
        Set<Character> characters = new HashSet<>(); //存储已经开头过的char
        for(int i = s; i <= e; i++ ) {
            if(characters.contains(list[i])) {
                continue;
            }
            characters.add(list[i]);
            swap(list, s, i);
            perm(list, s + 1, e);
            swap(list, s, i);
        }
    }
    
    private static void swap(char[] list, int i, int j) {
        char temp = list[i];
        list[i] = list[j];
        list[j] = temp;
    }
}
上一篇 下一篇

猜你喜欢

热点阅读