当前位置:  首页>> 技术小册>> 数据结构与算法(下)

题目描述

输入一个字符串,按字典序打印出该字符串中字符的所有排列。例如输入字符串abc,则打印出由字符a,b,c所能排列出来的所有字符串abc,acb,bac,bca,cab和cba。(输入一个字符串,长度不超过9(可能有字符重复),字符只包括大小写字母)。ps:牛客上的测试用例对返回的list要排序。

解法

对整个字符串的排列可以看成两部分。第一步求所有可能出现在第一个位置的字符,即把第一个字符与后面所有非重复的字符进行交换。第二步固定第一个字符,求后面所有字符的排列;第二步中后面的所有字符又可以看成一个完整的字符,继续执行这两个步骤。

注意存在重复值得情况,比如输入字符串bab,将首字符b作为固定字符串,对于将第2个下标的b换到首位仍然是bab,所有这种情况无需输出。

这道题的时间复杂度应该为O(n!)

  1. /**
  2. * @author mcrwayfun
  3. * @version 1.0
  4. * @description
  5. * @date Created in 2019/1/14
  6. */
  7. public class Solution {
  8. public ArrayList<String> Permutation(String str) {
  9. ArrayList<String> reList = new ArrayList<>();
  10. if (str == null || str.length() == 0) {
  11. return reList;
  12. }
  13. char[] chars = str.toCharArray();
  14. // 递归输出字符串排列
  15. permutationHelper(chars, 0, reList);
  16. Collections.sort(reList);
  17. return reList;
  18. }
  19. private void permutationHelper(char[] chars, int index, ArrayList<String> list) {
  20. if (index == chars.length - 1) {
  21. list.add(new String(chars));
  22. return;
  23. }
  24. Set<Character> set = new HashSet<>();
  25. // 确定交换的字符,包括自己[index,length-1]
  26. for (int i = index; i < chars.length; i++) {
  27. // 排除出现重复字符
  28. // hash表,查询花费O(1)
  29. if (!set.contains(chars[i])) {
  30. set.add(chars[i]);
  31. // 固定字符index
  32. swap(chars, i, index);
  33. // 递归固定剩余字符[index+1,length-1]
  34. permutationHelper(chars, index + 1, list);
  35. // 恢复原数组
  36. swap(chars, index, i);
  37. }
  38. }
  39. }
  40. private void swap(char[] chars, int x, int y) {
  41. char temp = chars[x];
  42. chars[x] = chars[y];
  43. chars[y] = temp;
  44. }
  45. }

测试用例

  1. 功能测试(输入的字符串有一个或多个字符);
  2. 特殊输入测试(输入的字符串为nullptr指针或者内容为空)。

该分类下的相关小册推荐: