力扣784(java)-字母大小写全排列(中等)

题目:

给定一个字符串 s ,通过将字符串 s 中的每个字母转变大小写,我们可以获得一个新的字符串。

返回 所有可能得到的字符串集合 。以 任意顺序 返回输出。

 

示例 1:

输入:s = "a1b2"
输出:["a1b2", "a1B2", "A1b2", "A1B2"]
示例 2:

输入: s = "3z4"
输出: ["3z4","3Z4"]
 

提示:

  • 1 <= s.length <= 12
  • s 由小写英文字母、大写英文字母和数字组成

来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/letter-case-permutation
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

解题思路:

一、用List模拟

有思路,但是写不出来完整的代码

参考@【爪哇缪斯】:https://leetcode.cn/problems/letter-case-permutation/solution/zhua-wa-mou-si-by-muse-77-7jb8/

首先将原字符串 s 放进结果ans中,然后再从头开始遍历字符串 s :

  • 当发现下标为 i 处是数字时,就跳过;
  • 当发现下标为 i 处是英文字母时,就进行大小写的转换,将本次转换后的整个字符串加入到ans中。

直到i 到达字符串的末尾表示字符串 s 遍历完成,返回ans。结合图进行理解。

 

 java代码:

 1 class Solution {
 2     public List<String> letterCasePermutation(String s) {
 3         List<String> ans = new ArrayList<>();
 4         //先将原字符串添加进结果中
 5         ans.add(s);
 6         //外层循环控制遍历的字符下标
 7         for(int i = 0; i < s.length(); i++){
 8             //如果是数字就跳过
 9             if(s.charAt(i) < 'A') continue;
10             int n = ans.size();
11             //内层循环控制改变的字符串下标
12             for(int j = 0; j < n; j++){
13                 char[] cs = ans.get(j).toCharArray();
14                 //直接定位在是字符的下标进行大小写转换
15                 //将小写转换成大写
16                 if(cs[i] >= 'a'){
17                     cs[i] = (char)(cs[i] - 32);
18                 }else{
19                     //将大写转换成小写
20                   cs[i] = (char)(cs[i] + 32);
21                 }
22                 //将本次转换后的字符串加入到结果中
23                 ans.add(new String(cs));
24             }
25         }
26         return ans;
27     }
28 }

 二、DFS

设计DFS函数为void dfs(char[] cs, List<String> ans, int index),cs为原来字符串s转换成字符数组,ans为当前具体的字符串,index表示当前处理到的字符位置。从前往后遍历每个cs[index],根据cs[index]是否为字母具体讨论:

  • 若cs[index]不是字母,则保留,不做任何改变,继续dfs下一个位置 index +1;
  • 若cs[index]是字母,则保留原有字母或改变大小写,然后继续dfs下一个位置 index + 1。

当index  == n时,说明对原字符串的每一个位置都已经变换完成,直接将当前cs加入到ans中。

注意:

异或:相同为0,不同为1

A 的Ascii 值为65(十进制) 二进制为  01000010
Z 的Ascii 值为90(十进制) 二进制为  01011010
32的二进制值为                       00100000

所以可以从大写转小写,从小转大异或运算32,去掉1 也就可以了

举例:

1.c(99):1100011转换成大写,与32(00100000)异或为:1000011(67)为C

2.M(77):01001101转换成小写,与32(00100000)异或为:01101101(109)为m

java代码:

 1 class Solution {
 2     public List<String> letterCasePermutation(String s) {
 3         List<String> ans = new ArrayList<>();
 4         char[] cs = s.toCharArray();
 5         dfs(cs, ans, 0);
 6         return ans;
 7     }
 8     public void dfs(char[] cs, List<String> ans, int index){
 9         if(index == cs.length){
10             ans.add(new String(cs));
11             return;
12         }
13         //不做任何改变继续dfs
14         dfs(cs, ans, index + 1);
15         //改变字母大小写状态
16         if(Character.isLetter(cs[index])){
17             cs[index] ^= 32;
18             dfs(cs, ans, index + 1);
19         }
20     }
21 }

posted on 2022-10-30 15:28  我不想一直当菜鸟  阅读(80)  评论(0编辑  收藏  举报