Java&C++题解与拓展——leetcode784.字母大小写全排列【么的新知识】

112 阅读1分钟
每日一题做题记录,参考官方和三叶的题解

题目要求

image.png

思路一:DFS

  • 因为要输出所有的排列,所以要实打实得构造出每一个序列;
  • 采用DFS依次向深遍历:
    • 过程中对于字母元素修改其大小写,数字元素直接过;
    • curcur为当前正在构造的某一个答案。

Java

class Solution {
    char[] ss;
    List<String> res = new ArrayList<>();
    int n;
    char[] cur;
    public List<String> letterCasePermutation(String s) {
        ss = s.toCharArray();
        n = s.length();
        cur = new char[n];
        DFS(0);
        return res;
    }
    void DFS(int idx) {
        if (idx == n) {
            res.add(String.valueOf(cur));
            return ;
        }
        cur[idx] = ss[idx];
        DFS(idx + 1);
        if (Character.isLetter(ss[idx])) {
            cur[idx] = (char)(ss[idx]^32); // 修改大小写
            DFS(idx + 1);
        }
    }
}
  • 时间复杂度:O(n×2n)O(n\times 2^n)
  • 空间复杂度:O(n×2n)O(n\times 2^n)

C++

class Solution {
public:
    vector<string> res;
    string cur;
    string s;
    int n;
    vector<string> letterCasePermutation(string s) {
        this->s = s;
        n = s.size();
        cur = s;
        DFS(0);
        return res;
    }
    void DFS(int idx) {
        if (idx == n) {
            res.emplace_back(cur);
            return ;
        }
        cur[idx] = s[idx];
        DFS(idx + 1);
        if (isalpha(s[idx])) {
            cur[idx] = s[idx] ^ 32;
            DFS(idx + 1);
        }
    }
};
  • 时间复杂度:O(n×2n)O(n\times 2^n)
  • 空间复杂度:O(n×2n)O(n\times 2^n)

思路二:二进制枚举

  • 结果数量由原字符串ss中字母数量mm决定,所以用一个statestate表示每个字母的翻转状态,然后枚举每一种状态即可。

Java

class Solution {
    public List<String> letterCasePermutation(String s) {
        List<String> res = new ArrayList<String>();
        int n = s.length(), m = 0;
        for (int i = 0; i < n; i++) // 字母数量统计
            m += Character.isLetter(s.charAt(i)) ? 1 : 0;
        for (int state = 0; state < (1 << m); state++) {
            char[] ss = s.toCharArray();
            for (int i = 0, j = 0; i < n; i++) {
                if (!Character.isLetter(ss[i]))
                    continue;
                ss[i] = ((state >> j) & 1) == 1 ? (char)(ss[i]^32) : ss[i];
                j++; // 状态下一位、下一个字母
            }
            res.add(String.valueOf(ss));
        }
        return res;
    }
}
  • 时间复杂度:O(n×2n)O(n\times 2^n)
  • 空间复杂度:O(n×2n)O(n\times 2^n)

C++

class Solution {
public:
    vector<string> letterCasePermutation(string s) {
        vector<string> res;
        int n = s.size(), m = 0;
        for (int i = 0; i < n; i++)
            m += isalpha(s[i]) ? 1 : 0;
        for (int state = 0; state < (1 << m); state++) {
            string ss = s;
            for (int i = 0, j = 0; i < n; i++) {
                if (!isalpha(ss[i]))
                    continue;
                ss[i] = ((state >> j) & 1) == 1 ? (char)(ss[i]^32) : ss[i];
                j++; // 状态下一位、下一个字母
            }
            res.emplace_back(ss);
        }
        return res;
    }
};
  • 时间复杂度:O(n×2n)O(n\times 2^n)
  • 空间复杂度:O(n×2n)O(n\times 2^n)

总结

  • 没写Rust之今天就是不想写
  • 感觉也是半个暴力模拟题,复杂度贼高还没办法

欢迎指正与讨论!