代码随想录算法训练营第一天|704.二分查找、27.移除元素

92 阅读1分钟

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; //返回的是数组的长度
};