• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录
ivelisya
博客园    首页    新随笔    联系   管理    订阅  订阅
“键盘行”和“宝石与石头”的解题思路和代码实现。

碎碎念

既然是一个长期更新的频道,那么肯定不可能只有一篇文章对不对 其实今天的题目我都还没开始写 but 不妨碍我先写个占位符?占位文章在这,等我今天的题目写完会继续来更新>ᴗ<!或许我应该抽个时间来写一下hexo + next在部署上遇见的问题,毕竟这玩意很麻烦且有很多坑。先预告在这吧,具体什么时候写还不一定呢 毕竟我懒。或许只要有一个人跟我留言,表达需要,我就会开始写了 谁叫我乐于助人呢。遇到任何问题,或者想跟我交朋友,请在文章下留言,或者在我的github个人介绍仓库提交issue或者开个discussion,我很乐意提供帮助!

题目一:键盘行

500. 键盘行

给你一个字符串数组 words ,只返回可以使用在 美式键盘 同一行的字母打印出来的单词。键盘如下图所示。

请注意,字符串 不区分大小写,相同字母的大小写形式都被视为在同一行。

美式键盘 中:

  • 第一行由字符 "qwertyuiop" 组成。
  • 第二行由字符 "asdfghjkl" 组成。
  • 第三行由字符 "zxcvbnm" 组成。

keyboard
示例 1

输入: words = ["Hello","Alaska","Dad","Peace"]

输出: ["Alaska","Dad"]

解释: 由于不区分大小写,"a" 和 "A" 都在美式键盘的第二行。

示例 2

输入: words = ["omk"]

输出: []

示例 3

输入: words = ["adsdf","sfd"]

输出: ["adsdf","sfd"]

提示

  • 1 <= words.length <= 20
  • 1 <= words[i].length <= 100
  • words[i] 由英文字母(小写和大写字母)组成

难度: 简单

解题思路

首先,我们看到这个题目。不区分大小写,相同字母的大小写形式都被视为在同一行。但是我们的words里面,可能会有大写的字符串。所以,我们应该把大写转化成小写。我采用的是

for (auto &word : words)
{
    // 转换成小写
    string lowerWord = word;
    for (auto &i : lowerWord)
    {
        if (i >= 'A' && i <= 'Z')
        {
            i += ('a' - 'A');
        }
    }
}

string lowerWord = word; 为什么要这么写呢,因为我们要把 words 里面的原始数据放到一个数组里面,所以原始数据不能更改。

然后我们定义 row1,row2,和 row3 判断在哪一行里。

然后使用循环和 string 的 find 方法来查找在哪一行,哪一行就++。

如果 row1 + row2 + row3 > 1,就跳出循环。

words 里面的某一个元素被遍历完或提前跳出,就判断 row1 + row2 + row3 是否等于 1。

如果等于就 push_back 进入结果数组。

代码如下:

vector<string> findWords(vector<string> &words)
{
    vector<string> res;
    string ln1 = "qwertyuiop", ln2 = "asdfghjkl", ln3 = "zxcvbnm";
    for (auto &word : words)
    {
        // 转换成小写
        string lowerWord = word;
        for (auto &i : lowerWord)
        {
            if (i >= 'A' && i <= 'Z')
            {
                i += ('a' - 'A');
            }
        }
        int row1 = 0, row2 = 0, row3 = 0;
        for (auto &ch : lowerWord)
        {
            if (ln1.find(ch) != string::npos)
            {
                row1 = 1;
            }
            else if (ln2.find(ch) != string::npos)
            {
                row2 = 1;
            }
            else if (ln3.find(ch) != string::npos)
            {
                row3 = 1;
            }
            if (row1 + row2 + row3 > 1)
                break;
        }
        if (row1 + row2 + row3 == 1)
            res.push_back(word);
    }
    return res;
}

比较简单的题目,注意题目要求即可。

题目二:宝石与石头

771. 宝石与石头

给你一个字符串 jewels 代表石头中宝石的类型,另有一个字符串 stones 代表你拥有的石头。 stones 中每个字符代表了一种你拥有的石头的类型,你想知道你拥有的石头中有多少是宝石。

字母区分大小写,因此 "a" 和 "A" 是不同类型的石头。

示例 1:

输入:jewels = "aA", stones = "aAAbbbb"
输出:3

示例 2:

输入:jewels = "z", stones = "ZZ"
输出:0

解题思路

要统计宝石的数量,可以采取以下步骤:

  1. 创建宝石集合:将 jewels 中的字符存入一个集合,便于查找。
  2. 遍历石头字符串:统计 stones 中出现的宝石类型。

为什么要放到集合呢。因为unordered_set基于哈希,效率比较高。其实是比较方便一点。我比较懒
std::set::count
参数:
count 接受一个元素作为参数,表示要查找的元素。

返回值:
对于std::set,count 函数返回一个 size_t 类型的值,表示元素在容器中出现的次数。由于 std::set 中的元素是唯一的,所以该函数的返回值要么是 0(元素不存在),要么是 1(元素存在)。

知识点

  • 哈希集合 (unordered_set):快速查找元素是否存在于集合中。
  • 遍历字符串:逐一检查每个字符。

代码实现

class Solution {
public:
    int numJewelsInStones(string jewels, string stones) {
        unordered_set<char> jewelSet(jewels.begin(), jewels.end());
        int count = 0;
        for (char ch : stones) {
            if (jewelSet.count(ch)) {
                ++count;
            }
        }
        return count;
    }
};

总结

以上两道题都是比较简单的题目,都涉及 字符串处理 和 集合操作。

posted on 2024-12-18 01:43  Ivelisya  阅读(16)  评论(0)    收藏  举报
刷新页面返回顶部
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3