java数据结构与算法之全排列问题
Posted wen-pan
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java数据结构与算法之全排列问题相关的知识,希望对你有一定的参考价值。
①、问题描述
- 给你一个字符串str,返回这个字符串的全部排列,比如:
- str = “abc”
- 返回,[abc , acb, bac, bca,cab,cba]
- 注意:如果字符串str里有重复字符呢?要求返回的全排列集合里不能存在重复字符串,比如:
- str = “aa”
- 返回,[aa]。而不是[aa, aa]
②、解题思路
- 这种求全排列的问题,最常见也是最容易想到的写法就是【暴力递归】
- 注意如果str里有重复字符,那么递归时需要做【剪枝】操作来保证结果集里不会有重复字符串
- 对于递归算法主要是【分析子问题】、【找到递归点】、【确定递归参数(需要几个参数、哪些是变参,哪些是不变参)】、【确定递归退出条件】,算法也比较简单,就直接上代码了
③、相关题目
④、代码
public class PermutationProblem
public static void main(String[] args)
List<String> list = findPermutation("aba");
System.out.println(list);
/**
* 求string字符串的所有全排列,比如:字符串abc,他的全排列为 abc、acb、bac、bca、cab、cba
* 比如:
* 力扣46题:https://leetcode-cn.com/problems/permutations/submissions/
* 力扣47题:https://leetcode-cn.com/problems/permutations-ii/
*/
public static List<String> findPermutation(String str)
// 特殊情况特殊处理
if (str == null || str.length() < 1)
return null;
List<String> resultList = new ArrayList<>();
process(str.toCharArray(), 0, resultList);
return resultList;
/**
* @param chars 字符数组
* @param index 当前来到的位置
* @param resList 结果集合(将结果收集到这个list里)
*/
public static void process(char[] chars, int index, List<String> resList)
// base case
if (index == chars.length)
// index超过数组最后一个位置时【开始结算】(因为后面已经没有可用选择了)
resList.add(new String(chars));
return;
// 利用缓存来剪枝(由于str只由26个小写字母组成,所以这里开一个长度为26的数组就够表示了),【这里也可以用hashSet来剪枝,原理一样】
int[] visited = new int[26];
// i后面的每个位置的字符,都可以来到index位置
for (int i = index; i < chars.length; i++)
int position = chars[i] - 'a';
// 【之前】有【和i位置的字符】相同的字符被交换到index位置过(那就不用交换,直接看 i + 1位置的数)
if (visited[position] != 0)
continue;
// 记录上,i位置的字符被交换到index位置过了
visited[position] = 1;
// 将i位置和index位置进行交换
swap(chars, i, index);
// 处理index + 1后面的位置,看看当index位置是i位置的字符时,后面的位置还有多少种可能(子问题)
process(chars, index + 1, resList);
// 每交换完一个位置后,进行第二轮交换时需要将上一轮交换的位置给换回来
swap(chars, i, index);
private static void swap(char[] chars, int i, int j)
char temp = chars[i];
chars[i] = chars[j];
chars[j] = temp;
以上是关于java数据结构与算法之全排列问题的主要内容,如果未能解决你的问题,请参考以下文章