LeetCode771 宝石与石头

题目描述

给定一个字符串 jewels,它代表石头中宝石的类型;另有一个字符串 stones,代表我们拥有的石头。其中,stones 里的每个字符对应一种石头类型,任务是要精准地统计出在 stones 当中,属于 jewels 所定义的宝石类型的石头究竟有多少。这里需特别注意,字母区分大小写,像 "a""A" 会被视作不同类型的石头。

解题思路

暴力解法:双层循环遍

最初想到的最直白的方法,就是利用双层 for 循环嵌套。外层循环负责逐个遍历 stones 中的字符,对于每一个 stones 里的字符,内层循环则遍历 jewels 字符串,去逐一比对是否有匹配的宝石类型。一旦找到匹配项,立马给计数器 count 加 1,随后中断内层循环,继续检查 stones 的下一个字符。

cs 复制代码
#include <stdio.h>
#include <string.h>

// 函数用于统计在stones中属于jewels定义的宝石类型的字符个数
int numJewelsInStones(char* jewels, char* stones) {
    int count = 0;
    // 遍历stones字符串中的每个字符
    for (int i = 0; stones[i]!= '\0'; i++) {
        // 对于stones中的每个字符,遍历jewels字符串进行匹配
        for (int j = 0; jewels[j]!= '\0'; j++) {
            if (stones[i] == jewels[j]) {
                count++;
                break;  // 一旦匹配成功,就不用继续在jewels中找了,直接去看下一个stones中的字符
            }
        }
    }
    return count;
}

int main() {
    char jewels[] = "aA";  // 可以自行修改这里的宝石类型字符串内容
    char stones[] = "aAAbbbb";  // 可以自行修改这里的拥有石头类型字符串内容
    int result = numJewelsInStones(jewels, stones);
    printf("在拥有的石头中宝石的数量是: %d\n", result);
    return 0;
}

这种方法虽然易于理解,代码逻辑清晰,但时间复杂度不容小觑,达到了 O(m * n),其中 mstones 字符串长度,njewels 字符串长度。想象一下,当 stonesjewels 都很长时,计算量会呈指数级增长,效率明显受限。

方法二:

哈希表优化解法:空间换时间

为了突破暴力解法的效率瓶颈,哈希表闪亮登场。其核心思路是预先利用一个数组(这里模拟哈希表,假设 ASCII 码值范围能涵盖处理字符)来存储宝石类型信息。

首先,遍历 jewels 字符串,将其中出现的字符对应的数组位置标记为 1,这就像是给宝石类型做了个快速索引目录。接着,遍历 stones 字符串时,只需凭借字符的 ASCII 码值瞬间定位到数组对应位置,若值为 1,那该字符就是宝石类型,计数器 count 顺势加 1。

cs 复制代码
#include <stdio.h>
#include <string.h>

// 函数用于统计在stones中属于jewels定义的宝石类型的字符个数
int numJewelsInStones(char* jewels, char* stones) {
    int hashTable[128] = {0};  // 假设ASCII码值范围足够涵盖我们要处理的字符,初始化哈希表数组元素都为0
    int count = 0;
    // 先将jewels中的字符对应的哈希表位置标记为1,表示存在这样的宝石类型
    for (int i = 0; jewels[i]!= '\0'; i++) {
        hashTable[(int)jewels[i]] = 1;
    }
    // 遍历stones,通过哈希表快速判断是否是宝石类型
    for (int j = 0; stones[j]!= '\0'; j++) {
        if (hashTable[(int)stones[j]] == 1) {
            count++;
        }
    }
    return count;
}

int main() {
    char jewels[] = "aA";  // 可根据需求修改宝石类型字符串内容
    char stones[] = "aAAbbbb";  // 可根据需求修改拥有石头类型字符串内容
    int result = numJewelsInStones(jewels, stones);
    printf("在拥有的石头中宝石的数量是: %d\n", result);
    return 0;
}

经此优化,时间复杂度大幅降至 O(m + n),尽管额外开辟了数组空间用于存储哈希表信息,但在数据量庞大时,计算效率的提升立竿见影,完美诠释了 "空间换时间" 的编程技巧精髓。

总结与启示

这道题犹如一面镜子,清晰映照出编程中效率权衡的艺术。从简单直接的暴力解法,到巧用数据结构优化的进阶之路,我们领悟到面对问题,思维不能局限于最初的直观想法。当性能瓶颈显现,积极探寻更优算法结构、大胆借助数据结构独特优势,才能在程序执行效率的赛道上弯道超车。

无论是日常刷题备战面试,还是实际项目开发优化性能,这种不断打磨解法、追求极致的精神,都将成为我们手中披荆斩棘的利刃,助力我们在代码世界里畅行无阻,攻克一个又一个难题。希望这次分享能给大家带来新的启发,一起在编程之旅中不断进阶!

相关推荐
东方翱翔3 分钟前
第十六届蓝桥杯大赛软件赛省赛第二场 C/C++ 大学 A 组
算法·职场和发展·蓝桥杯
Blossom.11831 分钟前
量子计算在密码学中的应用与挑战:重塑信息安全的未来
人工智能·深度学习·物联网·算法·密码学·量子计算·量子安全
1白天的黑夜135 分钟前
贪心算法-860.柠檬水找零-力扣(LeetCode)
c++·算法·leetcode·贪心算法
搏博43 分钟前
专家系统的基本概念解析——基于《人工智能原理与方法》的深度拓展
人工智能·python·深度学习·算法·机器学习·概率论
yzx99101344 分钟前
决策树随机深林
人工智能·python·算法·决策树·机器学习
Y1nhl1 小时前
力扣hot100_子串_python版本
开发语言·python·算法·leetcode·职场和发展
uhakadotcom1 小时前
过来人给1-3 年技术新人的几点小小的建议,帮助你提升职场竞争力
算法·面试·架构
wuqingshun3141592 小时前
蓝桥杯 16. 密文搜索
c++·算法·职场和发展·蓝桥杯·深度优先
Brookty2 小时前
【数据结构】哈希表
数据结构·算法·哈希算法·散列表
Dovis(誓平步青云)4 小时前
【数据结构】·励志大厂版(复习+刷题):二叉树
c语言·数据结构·经验分享·笔记·学习·算法·学习方法