其他分享
首页 > 其他分享> > 【LeetCode-784】字母大小写全排列

【LeetCode-784】字母大小写全排列

作者:互联网

问题

给定一个字符串S,通过将字符串S中的每个字母转变大小写,我们可以获得一个新的字符串。返回所有可能得到的字符串集合。

示例

输入: S = "a1b2"
输出: ["a1b2", "a1B2", "A1b2", "A1B2"]

解答1:DFS

class Solution {
public:
    vector<string> letterCasePermutation(string S) {
        dfs(S, 0);
        return res;
    }
private:
    vector<string> res;
    void dfs(string& S, int pos) {
        if (S.size() == pos) {
            res.push_back(S);
            return;
        }
        dfs(S, pos + 1); // 为数字或字母不改变大小写
        if (isalpha(S[pos])) {
            S[pos] ^= 32; // 字母改变大小写
            dfs(S, pos + 1);
        }
    }
};

重点思路

DFS的精髓是change - explore - unchange,本题需要explore的地方即大小写。

其中改变大小写的方法需要注意。小写转大写需要减去32,大写转小写需要加上32,而32的二进制表示为100000,所以只需要在二进制的第5位做无进位的加法(异或)即可。

解答2:不考虑数字的二进制

class Solution {
public:
    vector<string> letterCasePermutation(string S) {
        int cnt = 0;
        vector<string> res;
        for (char ch : S) // 统计字母数量
            if (isalpha(ch)) cnt++;
        for (int mask = 0; mask < (1 << cnt); mask++) {
            string ans;
            int mv = 0;
            for (char ch : S) {
                if (isdigit(ch)) ans += ch;
                else {
                    if (mask & (1 << mv++)) ans += ch ^ 32; // mask当前位为1时变大小写
                    else ans += ch;
                }
            }
            res.push_back(ans);
        }
        return res;
    }
};

解答3:考虑数字的二进制

class Solution {
public:
    vector<string> letterCasePermutation(string S) {
        int n = S.size(), k = 0;
        vector<string> res;
        for (int i = n - 1; i >= 0; i--) { // 反向遍历保证后续取值方便
            k <<= 1;
            if (isalpha(ch)) k |= 1; // 使用二进制标记当前位是否为字母
        }
        int sub = k;
        do {
            string ans = S;
            for (int i = 0; i < n; i++)
                if (sub & (1 << i)) ans[i] ^= 32; 
            res.push_back(ans);
            sub = (sub - 1) & k; // 注意此处取子集的方式
        } while (sub != k);
        return res;
    }
};

重点思路

本题取子集的方式比较特殊,相较于解答2也更加的通用。例如,它能取100101的所有子集,而解答2的取子集方法只能取得全1二进制(类似11111)的所有子集。

标签:784,int,res,pos,二进制,vector,大小写,LeetCode
来源: https://www.cnblogs.com/tmpUser/p/14616722.html