题意整理
- 给定一个字符串s,长度为n,求s的所有子序列。
- 如果子序列重复,则只添加一次。
方法一(回溯)
1.思路整理
- 首先将字符串转化为字符数组。
- 然后对字符数组进行遍历,每一个字符要么添加、要么不添加,利用回溯法添加字符数组中所有可能的字符组合,每一个组合代表一个子序列。每完成一轮添加,将对应组合加入到结果集。
2.代码实现
import java.util.*;
public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 
     * @param s string字符串 
     * @return string字符串一维数组
     */
    //用set记录,防止重复添加
    Set<String> res=new HashSet<>();
    public String[] generatePermutation (String s) {
        //转化为字符数组
        char[] arr=s.toCharArray();
        //回溯
        dfs(arr,new StringBuilder(),0);
        return res.toArray(new String[res.size()]);
    }
    
    private void dfs(char[] arr,StringBuilder sb,int index){
        res.add(sb.toString());
        for(int i=index;i<arr.length;i++){
            //添加当前字符
            sb.append(arr[i]);
            //对下一位进行递归
            dfs(arr,sb,i+1);
            //回退到不添加的状态
            sb.deleteCharAt(sb.length()-1);
        }
    }
}
3.复杂度分析
- 时间复杂度:假设字符串长度为n,每个字符有添加和不添加两种选择,总共有种选择,所以时间复杂度为。
- 空间复杂度:需要额外深度为n的递归栈,所以空间复杂度是。
方法二(位运算)
1.思路整理
定义一个长度为n的二进制mask位。每一个mask对应一个子序列,mask对应位置为0,表示不选择当前字符,为1表示选择当前字符。只要遍历所有的mask位,就可以将所有的子序列加入到结果集。
图解展示:
2.代码实现
import java.util.*;
public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 
     * @param s string字符串 
     * @return string字符串一维数组
     */
    
    public String[] generatePermutation (String s) {
        //转化为字符数组
        char[] arr=s.toCharArray();
        int n=arr.length;
        //使用set存储,防止重复添加
        Set<String> res=new HashSet<>();
        //遍历所有mask位
        for(int mask=0;mask<(1<<n);mask++){
            StringBuilder sb=new StringBuilder();
            for(int i=0;i<n;i++){
                if((mask&(1<<i))!=0){
                    sb.append(arr[i]);
                }
            }
            //填加mask对应子序列
            res.add(sb.toString());
        }
        return res.toArray(new String[res.size()]);
    }
    
}
3.复杂度分析
- 时间复杂度:假设字符串长度为n,每个字符有添加和不添加两种选择,对应个mask位,所以时间复杂度为。
- 空间复杂度:需要额外常数级别的空间,所以空间复杂度是。

 京公网安备 11010502036488号
京公网安备 11010502036488号