这是我参与更文挑战的第 22 天,活动详情查看 更文挑战
这个系列没啥花头,就是纯 leetcode 题目拆解分析,不求用骚气的一行或者小众取巧解法,而是用清晰的代码和足够简单的思路帮你理清题意。让你在面试中再也不怕算法笔试。
132. 快乐数 (happy-number)
标签
- 快慢指针
- 简单
题目
这里不贴题了,leetcode打开就行,题目大意:
编写一个算法来判断一个数 n 是不是快乐数。
「快乐数」定义为:
- 对于一个正整数,每一次将该数替换为它每个位置上的数字的平方和。
- 然后重复这个过程直到这个数变为 1,也可能是 无限循环 但始终变不到 1。
- 如果 可以变为 1,那么这个数就是快乐数。
- 如果 n 是快乐数就返回 true ;不是,则返回 false 。
示例 1
输入:19
输出:true
解释:
1^2 + 9^2 = 82
8^2 + 2^2 = 68
6^2 + 8^2 = 100
1^2 + 0^2 + 0^2 = 1
示例 2
输入:n = 2
输出:false
基本思路
这题我们的思路如果是暴力求解,就很简单,不赘述,但我们要知道计算机资源优先,栈空间有限,递归层数有限,时间有限,所以在诸多限制下,找寻一个好的算法就非常重要。
快乐数按某种方式计算,如果无限循环,基本上就是表明中间有重复数了,像不像我们之前做的一道题,判断链表是否有环,没错其实我们只要找到数字的规律,判断是否有环形成无限循环就行了。
然后代码需要拆着写
- 求平方和函数
- 快慢指针
写法实现
var isHappy = function(n) {
// 这是计算一个数的各数位平方和的函数 19 => 1^2 + 9^2 = 1 + 81 = 82
// 82 是作为下一个数
const calcSum = (num) => {
let numArr = num.toString().split('')
// 各位平方之后再加和
return numArr.map(item => item ** 2).reduce((acc, cur) => acc + cur)
}
// 定义快慢指针,一个走一步(算 1 次平方和)
// 一个走两步(算 2 次平方和),如果中间有相遇就是有环
let [slow, fast] = [n, n]
// 先走一次,让两指针错开
do {
slow = calcSum(slow);
fast = calcSum(calcSum(fast));
} while (fast !== slow)
return fast === 1
};
console.log(isHappy(19))
133. 验证回文串 (valid-palindrome)
标签
- 字符串
- 中等
题目
这里不贴题了,leetcode打开就行,题目大意:
给定一个字符串,验证它是否是回文串,只考虑字母和数字字符,可以忽略字母的大小写。
说明:本题中,我们将空字符串定义为有效的回文串。
示例 1:
输入: "A man, a plan, a canal: Panama"
输出: true
示例 2:
输入: "race a car"
输出: false
基本思路
主要考察预处理,先把数据处理成能简单判断回文的东西即可。
需要用到这个 api
String.prototype.match()
match()
方法检索返回一个字符串匹配正则表达式的结果。
例子
const paragraph = 'The quick 3 brown 66fox jumps over the lazy dog. It barked.';
const regex = /[A-Z]/g;
const found = paragraph.match(regex);
const regex2 = /[0-9]/g;
const num = paragraph.match(regex2)
console.log(found);
// expected output: Array ["T", "I"]
console.log(num)
// ["3", "6", "6"]
语法
str.match(regexp)
参数
regexp
-
一个正则表达式对象。如果传入一个非正则表达式对象,则会隐式地使用 new RegExp(obj) 将其转换为一个 RegExp 。
-
如果你没有给出任何参数并直接使用
match()
方法 ,你将会得到一个包含空字符串的 Array :[""]
。 返回值 -
如果使用
g
标志,则将返回与完整正则表达式匹配的所有结果,但不会返回捕获组。 -
如果未使用
g
标志,则仅返回第一个
完整匹配及其相关的捕获组(Array)。
其他内容 请看 MDN
实现步骤
- 因为大小写不管,直接全部转小写或大写
- 用正则上面的
match
api 过滤成只剩字母和数字的字符串 - 判断是否回文就行,无论是双指针,还是用各种 api 都行(reverse)
关于正则写法请看这篇 正则的基本要点
写法实现
var isPalindrome = function(s) {
// 预处理 转小写 => 匹配字母数字
let strArr = s.toLocaleLowerCase().match(/[a-z0-9]/g)
// 注意一个空格也是回文!
if (!strArr) {
return true
}
return strArr.join('') === strArr.reverse().join('')
};
let str = "A man, a plan, a canal: Panama"
console.log(isPalindrome(str))
另外向大家着重推荐下这个系列的文章,非常深入浅出,对前端进阶的同学非常有作用,墙裂推荐!!!核心概念和算法拆解系列
今天就到这儿,想跟我一起刷题的小伙伴可以加我微信哦 点击此处交个朋友
Or 搜索我的微信号infinity_9368
,可以聊天说地
加我暗号 "天王盖地虎" 下一句的英文
,验证消息请发给我
presious tower shock the rever monster
,我看到就通过,加了之后我会尽我所能帮你,但是注意提问方式,建议先看这篇文章:提问的智慧