五月刷题02——字符串


今日刷题内容: 字符串

前言

  • 一个算法废材的刷题之路开更了, 更新每天刷题的题解内容
  • 注重个人理解,看难度更新题目数量
  • 题目来源于力扣
  • 新开专栏,争取每日都能做出至少一题=v=
  • 语言java、python、c\c++

一、今日题目

  1. 500. 键盘行★☆☆☆☆
  2. 1160. 拼写单词★☆☆☆☆
  3. 1047. 删除字符串中的所有相邻重复项★☆☆☆☆
  4. 1935. 可以输入的最大单词数★☆☆☆☆

二、解题思路

1. 500. 键盘行★☆☆☆☆

  1. 用三个字符串来记录每个键盘行的字符
  2. 通过每个单词的第一个字符确认所在字符行
  3. 验证后序字符是否在同一字符行
  4. 如果在同一字符行,将结果加入到结果列表中
class Solution:
    def findWords(self, words: List[str]) -> List[str]:
        str1 = "qwertyuiopQWERTYUIOP"
        str2 = "asdfghjklASDFGHJKLK"
        str3 = "zxcvbnmZXCVBNM"
        ret = []
        # 通过每个单词的开头确认来自哪个键盘行
        for word in words:
            flag = True  # 标识当前单词是否来自同一个键盘行
            if word[0] in str1:
                for i in range(1, len(word)):
                    if word[i] not in str1:
                        flag = False
                        break
            elif word[0] in str2:
                for i in range(1, len(word)):
                    if word[i] not in str2:
                        flag = False
                        break
            elif word[0] in str3:
                for i in range(1, len(word)):
                    if word[i] not in str3:
                        flag = False
                        break
            if flag:
                ret.append(word)  # 如果来自同一个键盘行
        
        return ret

2. 1160. 拼写单词★☆☆☆☆

  1. 用一个hash表来记录已掌握的字符
  2. 遍历每个单词的每个字母,用flag来标识当前单词
  3. 遍历当前单词的所有字符,一旦有一个字符不在已掌握的字符中,flagfalse,退出当前循环
  4. 下一个单词时需要恢复原来的hash表,使用到深复制
class Solution {
    public int countCharacters(String[] words, String chars) {
        int[] hash = new int[256];
        // 用一个hash表来存储已掌握的词汇
        for(char c: chars.toCharArray()){
            hash[c]++;
        }
        int ret = 0;  // 统计字母个数
        int[] temp = new int[256];
        for (String word: words){
            boolean flag = true;
            // 恢复原来的hash表
            System.arraycopy(hash, 0, temp, 0, hash.length);
            for (char w: word.toCharArray()){
                if (temp[w] <= 0){
                    flag = false;
                    break;
                } else{
                    temp[w]--;
                }
            }
            // 如果单词中的每个字符都在已掌握的字符串中
            if (flag){
                ret += word.length();
            }
        }
        
        return ret;
    }
}


3. 1047. 删除字符串中的所有相邻重复项★☆☆☆☆

  1. 定义两个相邻指针l, r,采用滑动窗口的方式移动两个指针
  2. 需要注意的是,当左指针l大于0时,此时左右指针的字符相同,将相同字符删除后应该将左右指针回退
  3. 否则将左右指针右移即可
class Solution {
    public String removeDuplicates(String s) {
        int l = 0;
        int r = 1;
        int n = s.length();
        StringBuffer sb = new StringBuffer(s);  // 初始化结果
        while(r < sb.length() && l < sb.length()){
            if (sb.charAt(l) == sb.charAt(r)){
                sb.deleteCharAt(l);
                sb.deleteCharAt(l);
                // 如果此时左指针大于0,应该将左右指针同时回退一位
                if (l > 0){
                    l--;
                    r--;
                }
            }else{
                l++;
                r++;
            }
        }
        return sb.toString();
    }
}

4. 1935. 可以输入的最大单词数★☆☆☆☆

  1. 通过空格分割字符串成为单词数组
  2. 遍历单词数组中的每个单词的字符
  3. 一旦发现有字符属于坏掉的键盘键,跳过该字符,否则将结果count+1
class Solution:
    def canBeTypedWords(self, text: str, brokenLetters: str) -> int:
        words = text.split(" ")
        count = 0
        for word in words:
            flag = True
            for char in word:
                if char in brokenLetters:
                    flag = False
                    break
            if flag:
                count += 1
                
        return count
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值