代码随想录算法训练营第六天 | LeetCode
LeetCode 242.有效的字母异位词
给定两个字符串 s 和 t ,编写一个函数来判断 t 是否是 s 的字母异位词。
注意:若 s 和 t 中每个字符出现的次数都相同,则称 s 和 t 互为字母异位词
let isAnagram = function (s, t) {
if (s.length !== t.length) return false
// 长度为26的0值数组待存放字母出现次数
const record = new Array(26).fill(0)
const base = 'a'.codePointAt(0)
// 把字母出现次数存放进record,索引为字母与'a'的ASCII差值
for (let i = 0; i < s.length; i++) {
record[s.codePointAt(i) - base]++
}
// 把record的字母出现次数抵消,索引为字母与'a'的ASCII差值
for (let i = 0; i < t.length; i++) {
record[t.codePointAt(i) - base]--
// 如果record被减穿了,说明不是异位词
if (record[t.codePointAt(i) - base] < 0){
return false
}
}
for (let r of record) {
// 只要遍历到record数组里有值,就说明不是异位词
if (r !== 0) {
return false
}
}
// 如果record数组全是0,就说明是异位词
return true
}
思考
本题巧妙的点是运用数组(哈希表)的record[i] ++,–进行次数的判断;
转化思想:把26个小写英文字母映射到数组的26个index
语法拾遗
for let … in … 是遍历键名(索引)
for let … of … 是遍历键值(内容)
LeetCode 349. 两个数组的交集
给定两个数组 nums1
和 nums2
,返回 它们的交集 。输出结果中的每个元素一定是 唯一 的。我们可以 不考虑输出结果的顺序 。
let intersection = function(nums1, nums2) {
// 重复不考虑;不考虑输出结果顺序 => 用无序集合
let record = new Set()
// 不涉及索引用for of 循环
for (let num1 of nums1){
for(let num2 of nums2){
if (num1 === num2){
record.add(num1)
}
}
}
// 注意返回值是list,要转换为list
return Array.from(record)
}
LeetCode 202. 快乐数**
快慢指针法
let isHappy = function (n) {
// 定义函数:计算下一个数字
function getNext(number) {
let totalSum = 0;
while (number > 0) {
// 取出最后一位数字
let digit = number % 10;
// 计算平方和 (JS的**表示次方)
totalSum += digit ** 2;
// 取出前面的数字
number = Math.floor(number / 10);
}
return totalSum;
}
// 设置快慢指针
let slowRunner = n;
let fastRunner = getNext(n);
// 当快指针不等于1且慢指针不等于快指针时,循环计算下一个数字
while (fastRunner !== 1 && slowRunner !== fastRunner) {
slowRunner = getNext(slowRunner);
fastRunner = getNext(getNext(fastRunner));
}
// 如果快指针等于1,那么这个数是快乐数,返回 true
return fastRunner === 1;
}
LeetCode 1. 两数之和
法一 : Set
let twoSum = function (nums, target) {
// 数组同一个元素在答案里不能重复出现 => Set
let record = new Set()
for (let i = 0; i < nums.length; i++) {
for (let j = 0; j < nums.length; j++) {
if (nums[i] + nums[j] === target && i !== j) {
record.add(i)
record.add(j)
}
}
}
// 别忘了转换成目标形式的返回值
return Array.from(record)
}
法二 : List
let twoSum = function (nums, target) {
// 新建一个空列表
let record = ][]
for (let i = 0; i <nums.length; i++) {
for (let j = 0; j < nums.length; j++) {
if (nums[i] + nums[j] === target && i !== j) {
// 这里是因为遍历了同数组两重循环,必然产生两对答案,
// 为了避免最简单的方法是只存i不存,因为j在后半段循环也会被遍历到
record.unshift(i)
}
}
}
// 目标形式的返回值就是list
return record
}
思考
不管用List,还是Set,要拿捏住它的有序/无序性