leetcode刷题记录
-写在前面:我觉得应该是每天晚上把今天学的东西回顾一下,总结到掘金上面来
-每天的时间应该是 一半算法 一半八股
数组
01.两数之和【easy】
var twoSum = function(nums, target) {
// 先实例化一个map对象
let map = new Map()
// 遍历数组
for ( let i = 0; i < nums.length; i++){
// 如果map中有 target-nums[i] 的值,返回该值的下标和 i
if(map.has(target - nums[i])){
// 能这样返回的原因是,你在map里面存的是 key:元素值 value:元素索引
// 所以你在map.get(target-nums[i]) 获得的是 值为map.get(target-nums[i]) 的索引号
return [map.get(target - nums[i]), i]
} else{
// 如果没有符合条件的值 就把我遍历过的 nums[i] 存到map里面去
map.set(nums[i],i)
}
}
}
二分法
看到二分查找记住以下三个重要的点:
1.数组必须有序,否则二分查找算法就会失效, 换而言之,只要看到面试题里给出的数组是有序数组,都可以想一想是否可以使用二分法
2.定义两个指针,left 和 right
3.注意while循环的条件是否包含left = right的情况,同时也要注意中间变量 mid 的算法,防止其出现溢出现象。
红蓝二分法理论讲解
mid = left + ((right - left) >> 1) //二进制里面,右移一位就是除以2 而且这么写能保证一定是整数
一个讲的很好的视频 五点七边_二分法
对于该方法的讲解 文字版讲解
作者:随心源 链接:随心源 来源:力扣(LeetCode)
这个文字版讲解是对该模板的一些特殊情况的处理和说明,我们来看一下:
1.模板中的二分判断条件 哪个方便选哪个
可以写成
if isBlue(m)
l = m
else
r = m
也可以写成
if isRed(m)
r = m
else
l = m
2.模板中的循环判断条件建议写成l + 1 < r 能够提高运算速度
3.下标边界对应迭代器说明: 开始时,l 指针和 r 指针取在搜索区间界外,另一个重要作用就是构造了下标边界。
4.搜索完毕后的特殊情况:
如果二分查找跳出 while 循环之后,蓝色指针 l === 首个元素下标 - 1,即整个搜索区间都被染成红色,即左边蓝色区域长度为0,如果搜索目标位于左边蓝色区域,则搜索结果不存在,一般需要后处理;
如果二分查找跳出 while 循环之后,红色指针 l === 末尾元素下标 + 1,即整个搜索区间都被染成蓝色,即右边红色区域长度为0,如果搜索目标位于右边红色区域,则搜索结果不存在,一般需要后处理;
5.以下技巧必须掌握:
排序 二分查找的运用是建立在数组有序的基础上的,如果数组无序,我们要先对数组进行排序,如果数组有多个维度,我们针对需要二分查找的维度进行排序。
构造二分查找区间
多维度向量二分查找 有时候我们会遇到一类题我们要一组向量有多个维度,每个维度都要满足某种顺序,即需要对多个维度进行二分查找,但是我们只能对一个维度进行排序,怎么办?这时候我们以一个维度为主键进行排序,另一个维度我们有以下几种处理方式:(见原帖链接)
红蓝二分法做题
做题的时候,一是构建好输入(看样例要怎么输入),然后可以在主函数中去调用具体的实施函数,然后再把这个实施函数在外面写出来。
下面用蓝红分界法来做一下这些题:
704.二分查找【easy】
我划分的蓝色区域是 蓝色<= target, 红色> target 所以如果数组中有这个值的话 是left指针指向的
var search = function(nums, target) {
let n = nums.length
let left = -1, right = n
while(left + 1 !== right){
let mid = left + ((right - left) >> 1)
if(nums[mid] <= target){
left = mid
}else{
right = mid
}
}
if(nums[left] === target) return left
return -1
};
35.搜索插入【easy】
我划分的蓝色区域是 蓝色<= target, 红色> target
所以在找不到目标元素的时候,即蓝色区域最右边的,left指向的元素不是target时,返回的是 left + 1
var searchInsert = function(nums, target) {
// 这道题和704最大的不同就是如果目标值不存在的时候,704是返回-1
// 这里要求返回目标将会被按顺序插入的位置
let n = nums.length
let left = -1, right = n
// isBlue 的条件是 nums[mid] <= target
while(left + 1 !== right){
let mid = left + ((right - left) >> 1)
if(nums[mid] <= target){
left = mid
}
else{
right = mid
}
}
//循环结束后
if(nums[left] === target) {return left}
else {return left + 1}
};