壹 ❀ 引

简单问题简单做,今天的题目来自leetcode771. 宝石与石头,字符串相关的一道题,题目描述如下:

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

J 中的字母不重复,JS中的所有字符都是字母。字母区分大小写,因此"a""A"是不同类型的石头。

示例 1:

输入: J = "aA", S = "aAAbbbb"
输出: 3

示例 2:

输入: J = "z", S = "ZZ"
输出: 0

注意:

  • SJ 最多含有50个字母。
  • J 中的字符不重复。

我们先来简单的分析问题,因为题目简单,我们尽可能灵活运用掌握的知识,多一些可能去实现它。

贰 ❀ 解题思路

我们来汇总题目信息,首先S表示宝石,S中的每种字符都是一种宝石类型,且S不存在重复,也就是每个字符只会出现一次。

J的每个字符都是一种石头,且区分大小写,也会重复,我们要做的,就是要看手上的石头中,一共有多少课是宝石。综上来说,也就是要看S中的每个字符出现在J中的次数统计。

那么我们首先能想到的就是最暴力的解法,使用双层遍历,S表现一共要查多少遍,J表示每遍要查多少次,直接上代码:

/**
* @param {string} J
* @param {string} S
* @return {number}
*/
var numJewelsInStones = function (J, S) {
let j_len = J.length,
s_len = S.length,
ans = 0;// 统计宝石个数
for (let i = 0; i < j_len; i++) {
for (let k = 0; k < s_len; k++) {
if (J[i] === S[k]) {
ans++;
}
};
};
return ans.length;
};

当到这时,我突然意识到一个问题,由于题目已经说了S中宝石不存在重复,也就是说只要一颗宝石出现过,后面就不会再出现,那对于J而言,已经查出的宝石是没必要再参与下次查找的。

这样针对J特别大的情况,随着宝石查询次数增多,J中的剩余石头会越来越少,自然越查越快,于是我有了如下思路:

/**
* @param {string} J
* @param {string} S
* @return {number}
*/
var numJewelsInStones = function (J, S) {
var j_len = J.length,
S = S.split(""),// 这里将宝石转成数组,便于每次查询后清除掉已查到的宝石
ans = "";
for (let i = 0; i < j_len; i++) {
for (let k = 0; k < S.length;) {
if (J[i] === S[k]) {
ans += S[k];
//将已找到的宝石清除掉
S.splice(k, 1);
} else {
k++;
};
};
};
return ans.length;
};

通过这样修改,相比上次效率就快了不少,非常棒。

有没有其它做法,让我们想想,我们要在S中找有没有J包含的字符,以及找出遍布在S中所有满足J的字符,这样一想,J不就是正则匹配条件吗。我们知道正则有字符组的概念,举个例子:

let reg = /[aA]/g

这段正则表示匹配所有的小写a与大写A,如下图:

所以不管J有几个字符,我们只用/[J]/即可,所以可以这样:

/**
* @param {string} J
* @param {string} S
* @return {number}
*/
var numJewelsInStones = function (J, S) {
// 考虑到可能匹配不到,所以得用三元判断一次
let ans = S.match(new RegExp('[' + J + ']', 'g'));
return ans ? ans.length : 0
};

你看,活用正则也能解决这个问题。

其实之前我发现对比直接遍历字符,如果转成数组遍历似乎会快一些,我当时以为是leetcode提供的例子差异问题,但这次似乎又加深了我这种感觉,我们将S与J都转成数组进行遍历:

/**
* @param {string} J
* @param {string} S
* @return {number}
*/
var numJewelsInStones = function (J, S) {
let j = J.split("");
let s = S.split("");
// 将j包含的元素全部过滤到新数组中,并返回长度
return s.filter(item => j.includes(item)).length;
};

这里主要借用了includes方法,它用来判断数组是否包含某个元素,并返回布尔值。我们都知道NaN不等于自己,在判断是否包含NaN就很麻烦,而这个API恰好就能解决这个问题,比如:

[1,NaN,1].includes(NaN);// true
[1,1].includes(NaN);// false

题目虽然简单,但我们还是尽力拓展思维,复习了一些有趣的API以及正则小知识,那么关于本题就说到这了。

JS leetcode 宝石与石头 题解分析,正则字符组也有妙用的更多相关文章

  1. Leetcode#771.Jewels and Stones(宝石与石头)

    题目描述 给定字符串J 代表石头中宝石的类型,和字符串 S代表你拥有的石头. S 中每个字符代表了一种你拥有的石头的类型,你想知道你拥有的石头中有多少是宝石. J 中的字母不重复,J 和 S中的所有字 ...

  2. Java实现 LeetCode 771 宝石与石头(这是真暴力)

    771. 宝石与石头 给定字符串J 代表石头中宝石的类型,和字符串 S代表你拥有的石头. S 中每个字符代表了一种你拥有的石头的类型,你想知道你拥有的石头中有多少是宝石. J 中的字母不重复,J 和 ...

  3. Leetcode 10. 正则表达式匹配 - 题解

    版权声明: 本文为博主Bravo Yeung(知乎UserName同名)的原创文章,欲转载请先私信获博主允许,转载时请附上网址 http://blog.csdn.net/lzuacm. C#版 - L ...

  4. node.js基础模块http、网页分析工具cherrio实现爬虫

    node.js基础模块http.网页分析工具cherrio实现爬虫 一.前言      说是爬虫初探,其实并没有用到爬虫相关第三方类库,主要用了node.js基础模块http.网页分析工具cherri ...

  5. diff.js 列表对比算法 源码分析

    diff.js列表对比算法 源码分析 npm上的代码可以查看 (https://www.npmjs.com/package/list-diff2) 源码如下: /** * * @param {Arra ...

  6. C#版 - Leetcode 306. 累加数 - 题解

    版权声明: 本文为博主Bravo Yeung(知乎UserName同名)的原创文章,欲转载请先私信获博主允许,转载时请附上网址 http://blog.csdn.net/lzuacm. C#版 - L ...

  7. C#版(击败100.00%的提交) - Leetcode 372. 超级次方 - 题解

    版权声明: 本文为博主Bravo Yeung(知乎UserName同名)的原创文章,欲转载请先私信获博主允许,转载时请附上网址 http://blog.csdn.net/lzuacm. Leetcod ...

  8. C#版(打败97.89%的提交) - Leetcode 202. 快乐数 - 题解

    版权声明: 本文为博主Bravo Yeung(知乎UserName同名)的原创文章,欲转载请先私信获博主允许,转载时请附上网址 http://blog.csdn.net/lzuacm. C#版 - L ...

  9. LeetCode All in One题解汇总(持续更新中...)

    突然很想刷刷题,LeetCode是一个不错的选择,忽略了输入输出,更好的突出了算法,省去了不少时间. dalao们发现了任何错误,或是代码无法通过,或是有更好的解法,或是有任何疑问和建议的话,可以在对 ...

  10. Leet Code 771.宝石与石头

    Leet Code编程题 希望能从现在开始,有空就做一些题,自己的编程能力太差了. 771 宝石与石头 简单题 应该用集合来做 给定字符串J 代表石头中宝石的类型,和字符串 S代表你拥有的石头. S  ...

随机推荐

  1. C++ Lambda 表达式递归写法

    今天看到一篇博客介绍使用 Lambda 表达式递归计算 n!.使用了 C++14 的 generic lambda,给 Lambda 表达式加了一个模板参数,在函数调用的时候将 Lambda 表达式作 ...

  2. TCP 三次握手和四次挥手详解

    转载请注明出处: TCP协议(Transmission Control Protocol) 面向连接的,可靠的,基于字节流的传输层通信协议 特点: 基于连接的:数据传输之前需要建立连接 全双工的:双向 ...

  3. springboot升级到2.6.x和2.7.x 兼容hystrix

    一.pom.xml需要引入的依赖 二.项目开启熔断器开关 2.1 注解方式 2.2 xml方式 三.依赖类缺失问题 四.版本匹配安全检查问题 五.测试验证 六.结论 一.pom.xml需要引入的依赖 ...

  4. 笔记本也能飞:运行chat大模型

    背景 在过去的一年,ChatGPT的崛起彻底改变了我们与AI的交互方式.它不再是被动的信息提供者,而是成为了一个可以与我们自由交流.分享知识的伙伴.无论是生活中的琐事,还是工作中的难题,ChatGPT ...

  5. 【译】Visual Studio 2013 退役 :旧版本 Visual Studio 的支持提醒

    新年到了,也是提醒我们 Visual Studio 支持生命周期中即将到来的日期的好时机.对 Visual Studio 2013 的支持将于今年4月9日结束.如果您使用的是旧版本的Visual St ...

  6. [转帖]elasticsearch8.0以上版本修改内置用户密码

    https://www.cnblogs.com/zhang-ding-1314/p/16199682.html 修改密码需要在es启动,并cd到es的bin目录下执行: 1.重置密码并在控制台显示新密 ...

  7. Windows 修改时间提示: 某些设置已隐藏或由你的组织管理 的解决方案

    最近公司的一台生产服务器时间不对. 因为机器有域控的需求, 所以加入了域, 想改时间时有这样的提示信息: 某些设置已隐藏或由你的组织管理 百度了很久发现没有解决方法.. 但是突然发现可以使用 运行-& ...

  8. [转帖]CPU结构对Redis性能的影响

    文章系转载,便于分类和归纳,源文地址:https://wangkai.blog.csdn.net/article/details/111571446 CPU的多核架构和多CPU架构都会影响到Redis ...

  9. 六个节点三主三从Redis集群最简单搭建方法

    背景 一个服务器上面的三主三从的界面太low,容易出问题. 为了验证高可用, 我这边使用六台机器进行了三主三从的搭建. 模仿开源版的一键搭建集群的脚本进行使用,感觉非常简单,这里简单进行一下总结. 环 ...

  10. 分布式日志追踪ID实战 | 京东物流技术团队

    本文通过介绍分布式应用下各个场景的全局日志ID透传思路,以及介绍分布式日志追踪ID简单实现原理和实战效果,从而达到通过提高日志查询排查问题的效率. 背景 开发排查系统问题用得最多的手段就是查看系统日志 ...