字符串的排列

面试题38. 字符串的排列

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

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

示例:

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

限制:

1 <= s 的长度 <= 8

通用解法1:原字符串可包含重复字符

class Solution {
    public String[] permutation(String s) {
        char[] chars = s.toCharArray();
        if(s == null || s.length() == 0){return null;}
        TreeSet<String> list = new TreeSet<>();
        help(list,chars,0);
        String[] res = new String[list.size()];
        int i = 0;
        for(String str : list) res[i++] = str;
        return res;
    }
    private void help(TreeSet<String> list,char[] chars,int index){
        if(index == chars.length) return;
         list.add(new String(chars));
        for(int i = index;i < chars.length;i++){
            swap(chars,i,index);
            help(list,chars,index + 1);
            swap(chars,i,index);
        }
    }
    private void swap(char[] chars,int i,int j){
        char c = chars[i];
        chars[i] = chars[j];
        chars[j] = c;
    }
}

通用解法二:

public class Solution {
    ArrayList<String> list = new ArrayList<>();
    public ArrayList<String> Permutation(String str) {
        if (str == null || str.length() == 0) {
            return list;
        }
        char[] chars = str.toCharArray();
        Arrays.sort(chars);
        backtracking(chars, new boolean[chars.length], new StringBuilder());
        return list;
    }


    private void backtracking(char[] chars, boolean[] used, StringBuilder sb) {
        if (sb.length() == chars.length) {
            list.add(sb.toString());
        }
        for (int i = 0; i < chars.length; i++) {
            //每个字母做一次头部
            if (used[i]) {
                continue;
            }
            if (i != 0 && chars[i] == chars[i - 1] && !used[i - 1]) {
                continue;
            }
            sb.append(chars[i]);
            used[i] = true;
            backtracking(chars, used, sb);
            sb.deleteCharAt(sb.length() - 1);
            used[i] = false;
        }
    }
}

 

面试题 08.07. 无重复字符串的排列组合

无重复字符串的排列组合。编写一种方法,计算某字符串的所有排列组合,字符串每个字符均不相同。

示例1:

输入:S = "qwe"
输出:["qwe", "qew", "wqe", "weq", "ewq", "eqw"]
示例2:

输入:S = "ab"
输出:["ab", "ba"]
提示:

字符都是英文字母。
字符串长度在[1, 9]之间。

class Solution {
    public String[] permutation(String s) {
        if(s == null || s.length() == 0){return null;}
        char[] chars = s.toCharArray();
        ArrayList<String> list = new ArrayList<>();
        boolean[] used = new boolean[chars.length];
        help(chars,list,"",used);
        String[] strs = new String[list.size()];
        return list.toArray(strs);
    }
    private void help(char[] chars,ArrayList<String> list,String str,boolean[] used){
        if(str.length() ==  chars.length){
            list.add(str);
            return;
        }
        for(int i = 0;i < chars.length;i++){
            if(used[i]) continue;
            used[i] = true;
            help(chars,list,str + chars[i],used);
            used[i] = false;
        }  
    }
}

面试题 08.08. 有重复字符串的排列组合

有重复字符串的排列组合。编写一种方法,计算某字符串的所有排列组合。

示例1:

输入:S = "qqe"
输出:["eqq","qeq","qqe"]
示例2:

输入:S = "ab"
输出:["ab", "ba"]
提示:

字符都是英文字母。
字符串长度在[1, 9]之间。

class Solution {
    public String[] permutation(String s) {
        char[] chars = s.toCharArray();
        if(s == null || s.length() == 0){return null;}
        TreeSet<String> list = new TreeSet<>();
        help(list,chars,0);
        String[] res = new String[list.size()];
        int i = 0;
        for(String str : list) res[i++] = str;
        return res;
    }
    private void help(TreeSet<String> list,char[] chars,int index){
        if(index == chars.length) return;
         list.add(new String(chars));
        for(int i = index;i < chars.length;i++){
            swap(chars,i,index);
            help(list,chars,index + 1);
            swap(chars,i,index);
        }
    }
    private void swap(char[] chars,int i,int j){
        char c = chars[i];
        chars[i] = chars[j];
        chars[j] = c;
    }
}
  • 组合

链接:https://www.nowcoder.com/questionTerminal/837f4d04f5cb4f26a8215b2b95cc76a5?source=relative
来源:牛客网

输入一个字符串,输出该字符串中相邻字符的所有组合。
举个例子,如果输入abc,它的组合有a、b、c、ab、bc、abc。(注意:输出的组合需要去重)(40分)

输入描述:

一个字符串
输出描述:
一行,每个组合以空格分隔,相同长度的组合需要以字典序排序,且去重。
示例1

输入

bac

输出

a b c ac ba bac
public class Main{
    public static void main(String[] args){
        Scanner sc = new Scanner(System.in);
        String str = sc.nextLine();
        TreeSet<String> set = new TreeSet<String>(new Comparator<String>(){
            @Override
            public int compare(String s1,String s2){
                if(s1.length() == s2.length()){
                    return s1.compareTo(s2);
                }else{
                    return s1.length() - s2.length();
                }
            }
        });
        for(int i = 0;i < str.length();i++){
            help(str.toCharArray(),set,new StringBuilder(),i);
        }
        //Collections.sort(set);
        for(String s : set){
            System.out.print(s + " ");
        }
        
    }
    private static void help(char[] chars,TreeSet<String> set,StringBuilder sb,int start){
        if(start == chars.length) return;
        sb.append(chars[start]);
        set.add(sb.toString());
            help(chars,set,sb,start + 1);
               
    }
}
  • n皇后

 

n 皇后问题研究的是如何将 n 个皇后放置在 n×n 的棋盘上,并且使皇后彼此之间不能相互攻击。

上图为 8 皇后问题的一种解法。

给定一个整数 n,返回所有不同的 n 皇后问题的解决方案。

每一种解法包含一个明确的 n 皇后问题的棋子放置方案,该方案中 'Q' 和 '.' 分别代表了皇后和空位。

示例:

输入: 4
输出: [
[".Q..", // 解法 1
"...Q",
"Q...",
"..Q."],

["..Q.", // 解法 2
"Q...",
"...Q",
".Q.."]
]
解释: 4 皇后问题存在两个不同的解法。

class Solution {
    public List<List<String>> solveNQueens(int n) {
        List<List<String>> ress = new ArrayList<>();
        if(n <= 0) return ress;
        HashSet<Integer> rowSet = new HashSet<>();
                HashSet<Integer> posSet = new HashSet<>();
        HashSet<Integer> nevSet = new HashSet<>();

        backtracking(0,n,ress,new ArrayList<String>(),rowSet,posSet,nevSet);
        return ress;
    }
    private void backtracking(int rowIndex,int n,List<List<String>> ress,List<String> res,
                             HashSet<Integer> rowSet,HashSet<Integer> posSet,HashSet<Integer> nevSet){
        if(rowIndex == n){ress.add(new ArrayList<>(res));return;}
        for(int j = 0;j < n;j++){
            if(!rowSet.contains(j) && !posSet.contains(j - rowIndex) && !nevSet.contains(j + rowIndex)){
                rowSet.add(j);
                posSet.add(j - rowIndex);
                nevSet.add(j + rowIndex);
                char[] s = new char[n];
                Arrays.fill(s,'.');
                s[j] = 'Q';
                res.add(new String(s));
                backtracking(rowIndex + 1,n,ress,res,rowSet,posSet,nevSet);
                rowSet.remove(j);
                posSet.remove(j - rowIndex);
                nevSet.remove(j + rowIndex);
                res.remove(res.size() - 1);
            }
        }
        
    }
}
一回生,二回熟
原文地址:https://www.cnblogs.com/zzytxl/p/12588199.html