这是我参与8月更文挑战的第9天,活动详情查看:8月更文挑战
这个系列没啥花头,就是纯 leetcode 题目拆解分析,不求用骚气的一行或者小众取巧解法,而是用清晰的代码和足够简单的思路帮你理清题意。让你在面试中再也不怕算法笔试。
前面连续的难题,来几个简单点放松下
154. 和为K的子数组(subarray-sum-equals-k)
标签
- 中等
- hash
题目
给定一个整数数组
和一个整数 k
,你需要找到该数组中和为 k
的连续的子数组的个数。
示例 1
输入:nums = [1,1,1], k = 2
输出: 2 , [1,1] 与 [1,1] 为两种不同的情况。
基本思路
直接暴力枚举就行了,双重循环两个指针,i 和 j 计算 i, j
为首尾坐标的数组的和,等于 k 就 count++,非常简单暴力
暴力写法实现
function subarraySum(nums: number[], k: number): number {
let sum = 0, count = 0
for (let i = 0; i < nums.length; i++) {
sum = 0
for (let j = i; j < nums.length; j++) {
sum += nums[j]
if (sum === k) {
count++;
}
}
}
return count
};
当然我们可以优化这个算法
我们就想到,这种问题一般优化就是做缓存
,因为相邻顺序相加,其实很多加法是重复计算的, 我们枚举(i, j)就是 [j..i] 这个子数组和为 k
的情况
做缓存,那么我们 定义 pre[i]
为 [0..i]
里所有数的和
则 pre[i] = pre[i−1] + nums[i]
, 很明显的递推
那么 我们上面枚举的 [j..i] 这个子数组和为 k
这个条件我们可以转化为
[j..i]
这个子数组和我们可以表示为: preSum[i] - preSum[j−1]
那么就是 preSum[i] − preSum[j−1] === k
是我们想凑的等式,满足这个 count++
移项可得符合条件的下标 j
需要满足
preSum[j−1] === preSum[i] − k
接下来就是遍历 nums
- 发现前缀和满足条件,count++
- 保存前缀和与等式成立次数的映射
var subarraySum = function(nums, k) {
let count = 0, preSum = 0;
// 用 map 做缓存
const map = new Map([[0, 1]]);
for (let i = 0; i < nums.length; i++) {
preSum += nums[i]
// 发现前缀和满足条件,count++
if (map.has(preSum - k)) {
count += map.get(preSum - k);
}
// 保存前缀和与等式成立次数的映射
if (map.has(preSum)) {
map.set(preSum, map.get(preSum) + 1);
} else {
map.set(preSum, 1);
}
}
return count;
};
let nums = [1, 1, 1, 2, 2, 3], k = 5
console.log(subarraySum(nums, k))
155. 找到所有数组中消失的数字(find-all-numbers-disappeared-in-an-array)
标签
- 简单
题目
给你一个含 n 个整数
的数组 nums ,其中 nums[i]
在区间 [1, n]
内。请你找出所有在 [1, n]
范围内但没有出现在 nums 中的数字,并以数组的形式返回结果。
示例 1
输入:nums = [4,3,2,7,8,2,3,1]
输出:[5,6]
示例 2
输入:nums = [1,1]
输出:[2]
基本思路
遇到这种从 1 - n
的问题,就想想能不能用数组 index
做点啥
另外去重,想到 Set
本题就可以用一个 set 来处理,找出缺失
-
利用nums 长度来建立一个 len = n 的 set, 并把每个
index + 1
作为set 的 value -
遍历 nums 把数组中存在的数从 set 中移出, 那么剩下的数就是缺失的
-
set 转数组输出
写法实现
let findDisappearedNumbers = (nums) => {
let n = nums.length
// 使用 set 来去重,并把 index + 1 作为输出,
let set = new Set(new Array(n).fill(0).map((it, idx) => idx + 1))
// 此时 Set { 1, 2, 3, 4, 5, 6, 7, 8 }
for (let item of nums) {
// 把数组中存在的数从 set 中移出, 那么剩下的数就是缺失的
if (set.has(item)) {
set.delete(item)
}
}
return [...set]
}
console.log(findDisappearedNumbers([4,3,2,7,8,2,3,1]))
另外向大家着重推荐下这个系列的文章,非常深入浅出,对前端进阶的同学非常有作用,墙裂推荐!!!核心概念和算法拆解系列
今天就到这儿,想跟我一起刷题的小伙伴可以加我微信哦 点击此处交个朋友
Or 搜索我的微信号infinity_9368
,可以聊天说地
加我暗号 "天王盖地虎" 下一句的英文
,验证消息请发给我
presious tower shock the rever monster
,我看到就通过,加了之后我会尽我所能帮你,但是注意提问方式,建议先看这篇文章:提问的智慧