704-二分查找
【分析】
1、题干背景:根据题干的含义,是一个递增数组,这个奠定了使用二分查找的基础
2、区间选择逻辑:二分查找需要确定中间索引,以及取左边还是取右边
3、查找结束条件:startIndex>endIndex或者已经找到等于target的值了
4、二分查找需要借助while循环来执行这个循环逻辑
【疑问】
1、startIndex和endIndex如何取?
情况一:左闭右开,也就意味着endIndex是不用取的值,那么初始区间为[0,nums.length)
情况二:左闭右闭,endIndex是要取的值,初始区间为[0,nums.length-1]
2、while循环的执行条件是什么?
情况一:由于右区间是开区间,所以while的条件为 startIndex<endIndex
情况二:由于右区间是闭区间,所以while的条件为startIndex<=endIndex,这里是因为endIndex是会取到闭区间的值的,所以startIndex与endIndex相等时的情况也需要考虑进去
3、中间索引的确定规则是什么?
middleIndex = startIndex + Math.floor((endIndex-startIndex)/2)
使用Math.ceil也是可以的,只是对于中间值的取值是偏左还是偏右的差异
【代码实现】
var search = function (nums, target) {
// 二分查找需要使用while循环来执行这个循环逻辑
let startIndex = 0;
let endIndex = nums.length - 1;
while (startIndex <= endIndex) {
const middleIndex = startIndex + Math.floor((endIndex - startIndex) / 2);
const middleNum = nums[middleIndex];
if (middleNum === target) {
//说明找到了
return middleIndex;
} else if (middleNum < target) {
// 说明需要继续找右边
startIndex = middleIndex + 1;
} else {
// 说明需要继续找左边
endIndex = middleIndex - 1;
}
}
return -1; //说明最后都没有找到,返回-1
};
27-移除元素
【分析】
1、题目要求不使用额外数组空间,也就是说不能借助新数组,需要在原有数组上进行修改
2、元素的顺序是可以改变的(这里的意思我认为是提示可排序)
3、最终移除所有元素返回的是数组的新长度
【疑问】
1、如何结合二分查找?
先将数组进行排序处理
2、while循环是<=还是< ?
同样左闭右闭区间使用<=,防止漏判断情况
3、endIndex变动有哪些情况?
可以看到修改endIndex有两种情况:
情况一:中间值等于目标值的时候,由于我们会修改数组,所以需要同时变动endIndex
情况二:我们判断中间值大于目标值,需要取左侧时,需要把endIndex取到middleIndex-1
【代码实现】
var removeElement = function (nums, val) {
nums.sort((a, b) => a - b); //先将数组变成递增数组
// 这样操作后可以方便我们进行二分查找
let startIndex = 0;
let endIndex = nums.length - 1;
while (startIndex <= endIndex) {
const middleIndex = startIndex + Math.floor((endIndex - startIndex) / 2);
const middleNum = nums[middleIndex];
if (middleNum === val) {
// 说明是需要去除的元素->需要对元素进行移除
nums.splice(middleIndex, 1);
// 移除之后需要考虑索引变动的问题
endIndex--;
} else if (middleNum < val) {
// 说明val在右边,需要修改startIndex
startIndex = middleIndex + 1;
} else {
endIndex = middleIndex - 1;
}
}
return nums.length; //返回的是数组的长度
};