首页 > 试题广场 >

字符串的全部子序列

[编程题]字符串的全部子序列
  • 热度指数:3549 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 256M,其他语言512M
  • 算法知识视频讲解
给定一个字符串s,长度为n,求s的所有子序列
1.子序列: 指一个字符串删掉部分字符(也可以不删)形成的字符串,可以是不连续的,比如"abcde"的子序列可以有"ace","ad"等等
2.将所有的子序列的结果返回为一个字符串数组
3.字符串里面可能有重复字符,但是返回的子序列不能有重复的子序列,比如"aab"的子序列只有"","a","aa","aab","ab","b",不能存在2个相同的"ab"
4.返回字符串数组里面的顺序可以不唯一

数据范围:


要求:时间复杂度为

示例1

输入

"ab"

输出

["","a","ab","b"]

说明

返回["","b","a","ab"]也是可以的,视为正确,顺序不唯一 
示例2

输入

"dbcq"

输出

["","b","bc","bcq","bq","c","cq","d","db","dbc","dbcq","dbq","dc","dcq","dq","q"]
示例3

输入

"aab"

输出

["","a","aa","aab","ab","b"]

说明

返回的字符串数组里面不能存在"ab","ab"这样2个相同的子序列 
public static String[] generatePermutation (String s) {
        // write code here
        Set<String> set = new HashSet<>();
        set.add("");
        char[] chars = s.toCharArray();
        for (char c : chars) {
            ArrayList<String> strings = new ArrayList<>(set);
            for (String str : strings) {
                str += c;
                set.add(str);
            }
        }
        return set.toArray(new String[0]);
    }

发表于 2022-05-25 18:05:01 回复(0)
二进制数字选择法
#
# 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
#
# 
# @param s string字符串 
# @return string字符串一维数组
#
class Solution:
    def generatePermutation(self , s: str) -> List[str]:
        # write code here
        res_set = set()

        count = 0
        for i in range(2**len(s)):
            bin_s = bin(i)[2:]
            
            tmp = ''
            for j in range(len(bin_s)):
                if bin_s[j] == '1':
                    tmp += s[len(s)-len(bin_s) + j]

            res_set.add(tmp)

        res = list(res_set)
        return res


编辑于 2024-04-24 22:14:16 回复(0)
class Solution:
    def generatePermutation(self , s: str) -> List[str]:
        # write code here
        res = set()
        res.add("")
        def f(s, index, res, path):
            if index >= len(s):
                return 
            
            # 当前字符要
            res.add(path+s[index])
            f(s, index + 1, res, path+s[index])
            # 当前字符不要
            res.add(path)
            f(s, index + 1, res, path)
        f(s,0,res, '')
        return list(res)

编辑于 2024-03-17 20:34:35 回复(0)
import java.util.*;


public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 
     * @param s string字符串 
     * @return string字符串一维数组
     */
    public String[] generatePermutation (String s) {
        // write code here
        HashSet<String> set=new HashSet<>();
        char arr[]=s.toCharArray();
        dfs(arr,new StringBuilder(),0,set);
        String str[]=set.toArray(new String[set.size()]);
        return str;
        
    }
    public void dfs(char[] arr,StringBuilder sb,int index,HashSet<String> set){
        set.add(sb.toString());
        for(int i=index;i<arr.length;i++){
            sb.append(arr[i]);
            dfs(arr,sb,i+1,set);
            sb.deleteCharAt(sb.length()-1);
        }
    }
}

发表于 2023-05-19 10:13:15 回复(0)
package main
import _"fmt"

/**
 * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
 *
 * 
 * @param s string字符串 
 * @return string字符串一维数组
*/
func generatePermutation( s string ) []string {
    ans:=[]string{}
    vis:=map[string]bool{}
    var back_tracking func(string,int)
    back_tracking=func(path string,idx int){
        if _,ok:=vis[path];!ok{
            ans=append(ans,path)
            vis[path]=true
        }
        for i:=idx;i<len(s);i++{
            path+=string(s[i])
            back_tracking(path,i+1)
            path=path[:len(path)-1]
        }
    }
    back_tracking("",0)
    return ans
}

发表于 2023-03-09 23:25:18 回复(0)
class Solution {
public:
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 
     * @param s string字符串 
     * @return string字符串vector
     */
    void recursion(const string& s, vector<string>& v, string s1, int index, int capacity){
        if(s1.length() == capacity && m.find(s1) == m.end()){
            m[s1]++;
            v.push_back(s1);
            return;
        }
        for(int i=index; i<s.length(); i++){
            s1.push_back(s[i]);
            recursion(s, v, s1, i+1, capacity);
            s1.pop_back();
        }
    }
    unordered_map<string, int> m;
    vector<string> generatePermutation(string s) {
        // write code here
        vector<string> v;
        string s1 = "";
        v.push_back(s1);
        for(int i=1; i<=s.length(); i++){
            recursion(s, v, s1, 0, i);
        }
        return v;
    }
};

发表于 2022-12-07 22:56:56 回复(0)
public class Solution {
    public String[] generatePermutation (String s) {
        ArrayList<String> list = new ArrayList<>();
        char[] arr = s.toCharArray();
        process(arr,0,"",list);
        String result[] = new String[list.size()];
        int i=0;
        for(String e:list) {
        	result[i++] = e;
        }
        return result;
    }
    public void process(char arr[],int i,String str,ArrayList<String> list) {
    	if(i==arr.length) {
    		if(!list.contains(str)) {
    			list.add(str);
    		}
    		return;
    	}
    	process(arr,i+1,str,list);
    	process(arr,i+1,str+arr[i],list);
    }
}
暴力递归,最后一个用例超时了
发表于 2022-08-11 21:35:41 回复(0)
Java 深搜dfs解法 与 广搜bfs解法
Set<String> set;
    int n;
    public String[] generatePermutation (String s) {
        // write code here
        set = new HashSet<>();
        this.n = s.length();
        dfs(0, s, new StringBuilder());
        return set.toArray(new String[set.size()]);
    }
    
    // 18% 267ms dfs
    public void dfs(int start, String s, StringBuilder cur){
        set.add(cur.toString());
        if(start == n){
            return ;
        }
        char c = s.charAt(start);
        // 选与不选当前字符
        dfs(start+1, s, cur.append(c));
        cur.deleteCharAt(cur.length()-1);
        dfs(start+1, s, cur); 
    }
广搜
// 181ms 73%
    int n;
    public String[] generatePermutation (String s) {
        this.n = s.length();
        List<String> list = new ArrayList<>();
        list.add("");
        bfs(0, s, list);
        Set<String> hash = new HashSet<>(list);
        return hash.toArray(new String[hash.size()]);
    }
    
    public void bfs(int start, String s, List<String> list){
        if(start == n)
            return ;
        List<String> tmpList = new ArrayList<>(list);
        for(String tmp : tmpList){
            tmp += s.charAt(start);
            list.add(tmp);
        }
        bfs(start+1, s, list);
    }



发表于 2022-07-26 16:06:28 回复(0)
class Solution:
    def generatePermutation(self , s: str) -> List[str]:
        a = [""]
        for c in s:
            a.extend([ x+c for x in a ])
        return list(set(a)) 

发表于 2022-02-24 17:14:20 回复(1)
import java.util.*;

// 回溯比用位运算更好,毕竟是要成功率不是炫技
public class Solution {
    public String[] generatePermutation (String s) {
        backTrack(s.toCharArray(), 0);
        return res.toArray(new String[0]);
    }
    StringBuilder sb = new StringBuilder();
    HashSet<String> res = new HashSet<>();
    public void backTrack(char[] c, int idx) {
        if (!res.contains(sb.toString()))
            res.add(sb.toString());
        else return;
        for (int i = idx; i < c.length; i++) {
            sb.append(c[i]);
            backTrack(c, i+1);
            sb.deleteCharAt(sb.length()-1);
        }
    }
}
发表于 2022-01-24 21:17:43 回复(0)
import java.util.*;


public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 
     * @param s string字符串 
     * @return string字符串一维数组
     */
    public String[] generatePermutation (String s) {
        char[] chars = s.toCharArray();
        Set<String> res = new HashSet<>();
        StringBuilder builder = new StringBuilder();
        builder.append("");
        dfs(builder,chars,0,res);
        String[] strArr = new String[res.size()];
        int index = 0;
        for (String elem : res) {
            strArr[index++]=elem;
        }
        return strArr;
    }

    private void dfs(StringBuilder track,char[] chars,int depth,Set<String>res) {
        if (depth>=chars.length) {
            res.add(track.toString());
            return;
        }

        // 当前位置不选
        dfs(track,chars,depth+1,res);
        // 当前位置选择
        track.append(chars[depth]);
        dfs(track,chars,depth+1,res);
        track.delete(track.length()-1,track.length());
    }
}
发表于 2022-01-22 12:54:13 回复(0)
import java.util.*;
public class Solution {
    public String[] generatePermutation (String s) {
        ArrayList<String> list=new ArrayList<>();
        printAllSub(s.toCharArray(), 0, "",list);
        String[] res=new String[list.size()];
        for(int i=0;i<res.length;i++){
            res[i]=list.get(i);
        }
        return res;
    }
    
    public static void printAllSub(char[] str, int i, String res,ArrayList<String> list) {
        if (i == str.length) {
            list.add(res);
            return ;
        } else {
            printAllSub(str, i + 1, res,list); // 不要下标为i+1的字符
            printAllSub(str, i + 1, res+str[i],list); // 要第i+1个字符
        }
    }
}

发表于 2021-12-27 11:12:10 回复(1)
2种获得子序列的方法:
vector<string> v;
string permutation(string s, string result)
{
    if (s.empty())
    {
        v.push_back(result);
        return "";
    }

    permutation(s.substr(1), result + s[0]);
    permutation(s.substr(1), result);
    return "";
}


vector<string> f_t;
void func(string s)
{
    for (int i = 0; i < 1 << s.length(); i++)
    {
        string temp;
        for (int j = 0; j < s.length(); j++)
        {
            if ((1 << j) & i)
                temp += s[j];
        }
        // cout << temp << endl;
        f_t.push_back(temp);
        //对temp的操作
    }
}


发表于 2021-11-11 16:20:13 回复(0)