leetcode
leetcode 701 ~ 750
字母大小写全排列

字母大小写全排列

难度:

标签:

题目描述

代码结果

运行时间: 22 ms, 内存: 17.3 MB


/*
题目思路:
1. 使用流操作将所有可能的字符组合生成。
2. 对于每个字符,如果是字母,则生成大小写两种组合,否则保持原样。
3. 使用流的flatMap和collect方法来汇总所有结果。
*/

import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public class SolutionStream {
    public List<String> letterCasePermutation(String s) {
        return letterCasePermutationHelper(s).collect(Collectors.toList());
    }

    private Stream<String> letterCasePermutationHelper(String s) {
        if (s.isEmpty()) {
            return Stream.of("");
        }
        char firstChar = s.charAt(0);
        String rest = s.substring(1);
        Stream<String> restStream = letterCasePermutationHelper(rest);
        if (Character.isLetter(firstChar)) {
            return Stream.concat(
                    restStream.map(str -> firstChar + str),
                    restStream.map(str -> Character.toLowerCase(firstChar) + str)
            );
        } else {
            return restStream.map(str -> firstChar + str);
        }
    }
}

解释

方法:

此题解采用了回溯算法。主要思路是遍历给定字符串s的每个字符,如果字符是字母,则有两个选择:小写形式和大写形式。对于每个字母,都递归地探索这两种可能性。如果字符是数字,则无需改变,直接添加到当前字符串,并继续处理下一个字符。当递归到字符串末尾时,将当前构建的字符串添加到结果列表中。这种方法系统地探索了所有可能的字母大小写组合,从而生成所有可能的字符串。

时间复杂度:

O(2^n)

空间复杂度:

O(2^n * n)

代码细节讲解

🦆
回溯算法在处理字母大小写全排列时的基本逻辑是什么?
回溯算法在处理字母大小写全排列时,首先遍历输入字符串的每一个字符。对于每个字符,如果它是字母,则会产生两个选择分支:一个是该字符的小写形式,另一个是大写形式。对这两种选择分别进行递归探索,继续处理字符串的下一个字符。如果字符是数字或其他非字母字符,则直接将其添加到当前正在构建的字符串中,并只有一个递归分支继续向下处理。这样,通过逐字符决策,递归地探索所有可能的大小写组合,直至处理完整个字符串,最终达到生成所有可能字符串的目的。
🦆
在递归函数中,为何在处理完一个字符后,需要立即递归处理下一个字符的索引?
在递归函数中,立即处理下一个字符的索引是为了继续构建从当前字符派生的所有可能的字符串。递归的本质是分解问题为更小的子问题进行解决,而在这个问题中,每处理完一个字符,都需要考虑下一个字符的所有可能性(大小写或直接继承),以确保能够探索到从当前字符开始的所有可能组合。这种连续的递归调用保证了算法能够遍历整个字符串的每一种大小写变体组合。
🦆
当字符为数字时,直接继承到当前字符串中,这种处理方式是否可能漏掉其他潜在的字符串组合?
当字符是数字时,直接将其添加到当前字符串并继续处理不会漏掉任何潜在的字符串组合。这是因为数字和其他非字母字符没有大小写变体,因此不像字母字符那样有多个处理分支。数字的处理只有一种可能性,即保持其原样,所以直接继承到当前字符串是正确且高效的处理方式。
🦆
你是如何保证在递归结束时,所有的字符串都已经完整地添加到结果列表中的?
在递归函数中,每当到达字符串的末端(即处理完所有字符),当前构建的字符串就会被添加到结果列表中。这是通过在递归函数中设置一个基本条件来实现的:如果当前的字符索引等于字符串长度,表明已经处理完字符串中的所有字符,此时将当前构建的字符串添加到结果列表。这种方法确保了每一条递归路径(即每一个字符的大小写决策路径)都能在字符串处理完毕时将其结果存储,从而保证了所有可能的字符串都被完整生成并收录。

相关问题

子集

给你一个整数数组 nums ,数组中的元素 互不相同 。返回该数组所有可能的子集(幂集)。

解集 不能 包含重复的子集。你可以按 任意顺序 返回解集。

 

示例 1:

输入:nums = [1,2,3]
输出:[[],[1],[2],[1,2],[3],[1,3],[2,3],[1,2,3]]

示例 2:

输入:nums = [0]
输出:[[],[0]]

 

提示:

  • 1 <= nums.length <= 10
  • -10 <= nums[i] <= 10
  • nums 中的所有元素 互不相同

花括号展开

花括号展开