LeetCode771 宝石与石头

题目描述

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

解题思路

暴力解法:双层循环遍

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

#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),其中 m 是 stones 字符串长度,n 是 jewels 字符串长度。想象一下,当 stones 和 jewels 都很长时,计算量会呈指数级增长,效率明显受限。

方法二:

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

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

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

#include <stdio.h>
#include <string.h>// 函数用于统计在stones中属于jewels定义的宝石类型的字符个数
int numJewelsInStones(char* jewels, char* stones) {int hashTable[128] = {0};  // 假设ASCII码值范围足够涵盖我们要处理的字符,初始化哈希表数组元素都为0int 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),尽管额外开辟了数组空间用于存储哈希表信息,但在数据量庞大时,计算效率的提升立竿见影,完美诠释了 “空间换时间” 的编程技巧精髓。

总结与启示

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

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/64251.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

MySQL基础大全(看这一篇足够!!!)

文章目录 前言一、初识MySQL1.1 数据库基础1.2 数据库技术构成1.2.1 数据库系统1.2.2 SQL语言1.2.3 数据库访问接口 1.3 什么是MySQL 二、数据库的基本操作2.1 数据库创建和删除2.2 数据库存储引擎2.2.1 MySQL存储引擎简介2.2.2 InnoDB存储引擎2.2.3 MyISAM存储引擎2.2.4 存储引…

[论文阅读笔记]-PalmTree: 学习一个用于指令嵌入的汇编语言模型

深度学习已在众多二进制分析任务中展示了其优势&#xff0c;包括函数边界检测、二进制代码搜索、函数原型推理、值集分析等。现有方案忽略了复杂的指令内结构&#xff0c;主要依赖于控制流&#xff0c;其中上下文信息是嘈杂的&#xff0c;并且可能受到编译器优化的影响。为了解…

手搓一个极简远端git库

原文地址&#xff1a;手搓一个极简远端git库 – 无敌牛 欢迎参观我的个人博客&#xff1a;无敌牛 – 技术/著作/典籍/分享等 问题分析 公司一直用 gitlab &#xff08;或者 极狐 都是一样的&#xff09;作为代码管理库&#xff0c;但是看了一些文章说代码最小的管理只需要 g…

米哈游大数据面试题及参考答案

怎么判断两个链表是否相交?怎么优化? 判断两个链表是否相交可以采用多种方法。 一种方法是使用双指针。首先分别遍历两个链表,得到两个链表的长度。然后让长链表的指针先走两个链表长度差的步数。之后,同时移动两个链表的指针,每次比较两个指针是否指向相同的节点。如果指…

Linux 服务器下非root用户安装CUDA完整流程(多次踩雷经验总结)

参考博客&#xff1a; linux下安装cuda和cudnn&#xff08;非root权限&#xff09;_cuda下载安装 远程服务器 linux-CSDN博客 Linux下非root用户安装CUDA_linux下cuda-toolkit-archive-CSDN博客 非root用户安装cuda10.1&#xff0c;以及CUDA不同版本间切换_非root用户.run文…

Netty 常见面试题原理解析

Netty 是一个异步的、事件驱动的网络应用程序框架&#xff0c;用于快速开发可维护的高性能协议服务器和客户端。在面试中&#xff0c;Netty 经常成为热门话题。本文将对一些常见的 Netty 面试题进行原理解析。 一、Netty 是什么&#xff1f; Netty 是一个基于 NIO&#xff08…

分立器件---运算放大器关键参数

运算放大器 关键参数 1、供电电压:有单电源电压、双电源电压,双电源电压尽量两个电源都接。如图LM358B,供电电压可以是20V或者是40V和GND。 2、输入偏置电流IB:当运放输出直流电压为零时,运放两个输入端流进或者流出直流电流的平均值。同向输入端电流IB+与反向输入端电流…

【数据结构——查找】二叉排序树(头歌实践教学平台习题)【合集】

目录&#x1f60b; 任务描述 相关知识 测试说明 我的通关代码: 测试结果&#xff1a; 任务描述 本关任务&#xff1a;实现二叉排序树的基本算法。 相关知识 为了完成本关任务&#xff0c;你需要掌握&#xff1a;二叉树的创建、查找和删除算法。具体如下&#xff1a; (1)由…

240004基于Jamva+ssm+maven+mysql的房屋租赁系统的设计与实现

基于ssmmavenmysql的房屋租赁系统的设计与实现 1.项目描述2.运行环境3.项目截图4.源码获取 1.项目描述 该项目在原有的基础上进行了优化&#xff0c;包括新增了注册功能&#xff0c;房屋模糊查询功能&#xff0c;管理员和用户信息管理等功能&#xff0c;以及对网站界面进行了优…

聊聊Oracle自适应查询优化

成也AQO败也AQO 因为工作的原因&#xff0c;我们接触到的客户大部分是金融和运营商行业&#xff0c;这些客户有个最大的特点是追求稳定&#xff0c;对于使用数据库新特性持保守的态度&#xff0c;不会轻易尝试某些可能会导致生产系统不稳定的新特性。上线前通常都会将一些新特…

电脑显示器选购指南2024

选择显示器是五花八门的显示参数&#xff0c;如何选择&#xff0c;以下给出参数说明&#xff0c;及部分参考&#xff1a; 1. 尺寸和分辨率 尺寸&#xff08;英寸&#xff09; 根据使用距离和用途选择合适的屏幕尺寸&#xff1a; 21-24 英寸&#xff1a;适合小桌面空间、日常…

(八)机器学习 - 线性回归

线性回归&#xff08;Linear Regression&#xff09;是一种统计学方法&#xff0c;用于建立一个或多个自变量&#xff08;解释变量&#xff09;与因变量&#xff08;响应变量&#xff09;之间的线性关系。线性回归的目的是通过最小化预测误差来找到最佳的线性拟合模型&#xff…

huggingface NLP-微调一个预训练模型

微调一个预训练模型 1 预处理数据 1.1 处理数据 1.1.1 fine-tune 使用tokenizer后的token 进行训练 batch tokenizer(sequences, paddingTrue, truncationTrue, return_tensors"pt")# This is new batch["labels"] torch.tensor([1, 1])optimizer A…

【文档搜索引擎】在内存中构造出索引结构(下)

文章目录 4.保存到磁盘中为什么要保存在磁盘中怎么保存操作步骤1. 前期准备2. 主要操作 5. 将磁盘中的数据加载到内存中Parser 类完整源码Index 类完整源码 4.保存到磁盘中 为什么要保存在磁盘中 索引本来是存储在内存中的&#xff0c;为什么要将其保存在硬盘中&#xff1f; …

STM32-FATFS文件系统

一、FATFS文件系统介绍&#xff1a; FATFS 是一个完全免费开源的 FAT/exFAT 文件系统模块&#xff0c;专门为小型的嵌入式系统而设计。它完全用标准 C 语言&#xff08;ANSI C C89&#xff09;编写&#xff0c;所以具有良好的硬件平台独立性&#xff0c;只需做简单的修改就可以…

Unity NTPComponent应用, 实现一个无后端高效获取网络时间的组件

无后端高效获取网络时间的组件 废话不多说&#xff0c;直接上源码m_NowSerivceTime 一个基于你发行游戏地区的时间偏移&#xff0c; 比如北京时区就是 8, 巴西就是-3&#xff0c;美国就是-5using Newtonsoft.Json; 如果这里报错&#xff0c; 就说明项目没有 NewtonsoftJson插件…

华为ensp中nat server 公网访问内网服务器

作者主页&#xff1a;点击&#xff01; ENSP专栏&#xff1a;点击&#xff01; 创作时间&#xff1a;2024年4月15日17点30分 &#x1f4af;趣站推荐&#x1f4af; 前些天发现了一个巨牛的&#x1f916;人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;…

R语言学习笔记-1

1. 基础操作和函数 清空环境&#xff1a;rm(list ls()) 用于清空当前的R环境。 打印输出&#xff1a;print("Hello, world") 用于输出文本到控制台。 查看已安装包和加载包&#xff1a; search()&#xff1a;查看当前加载的包。install.packages("package_na…

二、FIFO缓存

FIFO缓存 1.FIFO缓存介绍2.FIFO缓存实现3.FIFO缓存总结 1.FIFO缓存介绍 FIFO&#xff08;First-In-First-Out&#xff09;缓存 是一种简单的缓存淘汰策略&#xff0c;它基于先进先出的原则来管理数据。当缓存达到容量限制并需要淘汰元素时&#xff0c;最先进入缓存的元素会被移…