LeetCode体操-1 | 704. 二分查找、27. 移除元素(JS)

122 阅读3分钟

数组理论基础

数组是存放在连续内存空间上的相同类型数据的集合,可以方便地通过下标索引的方式获取到下标所对应的数据

要点:

  • 数组下标都是从0开始的
  • 数组内存空间的地址是连续的
    • 增删元素时,需移动其他元素的地址
    • 元素的地址只能覆盖,不能删除

Untitled diagram-2024-07-03-063224.png

概念数组链表
内存分配连续内存非连续内存,节点通过指针连接
访问速度快速,通过索引直接访问较慢,需要从头遍历到目标节点
插入/删除较慢,需要移动元素快速,只需改变指针
内存效率效率较高,无需额外指针存储效率较低,每个节点需要额外指针

704. 二分查找

解题方法: 二分查找

特征: 有序数组且数组中无重复元素(确保查找下标值唯一)

重难点: 区间的定义就是不变量,要在二分查找的过程中,保持不变量,即:在while循环中坚持根据查找区间的定义来做边界处理,就是循环不变量规则。

实现方式: 1、左闭右闭,定义target在[left, right]区间;2、左闭右开,定义target在[left, right)区间

1、左闭右闭

思路:

  1. while (left <= right) 要使用 <= ,因为left == right是有意义的,所以使用 <=;
  2. if (nums[middle] > target) right 要赋值为 middle - 1,因为当前这个nums[middle]一定不是target,那么接下来要查找的左区间结束下标位置就是 middle - 1
function search(nums, target) {
  let mid, left = 0, right = nums.length - 1;
  while (left <= right) {
    mid = left + ((right - left) >> 1);
    if (nums[mid] > target) {
      right = mid - 1;
    } else if (nums[mid] < target) {
      left = mid + 1;
    } else {
      return mid;
    }
  }
  return -1;
}
  • 时间复杂度:O(log n);
  • 空间复杂度:O(1);

2、左闭右开

思路:

  1. while (left < right),这里使用 < ,因为left == right在区间[left, right)是没有意义的;
  2. if (nums[middle] > target) right 更新为 middle,因为当前nums[middle]不等于target,去左区间继续寻找,而寻找区间是左闭右开区间,所以right更新为middle,即:下一个查询区间不会去比较nums[middle]
function search(nums, target) {
  let mid, left = 0, right = nums.length;
  while (left < right) {
    mid = left + ((right - left) >> 1);
    if (nums[mid] > target) {
      right = mid;
    } else if (nums[mid] < target) {
      left = mid + 1;
    } else {
      return mid;
    }
  }
  return -1;
}
  • 时间复杂度:O(log n);
  • 空间复杂度:O(1);

27. 移除元素

解题方法: 双指针法

特征: 通过一个快指针和慢指针在一个for循环下完成两个for循环的工作;2、定义快慢指针,快指针:寻找新数组的元素 ,新数组就是不含有目标元素的数组。慢指针:指向更新 新数组下标的位置;

重难点: 1、确定指针的移动策略;2、处理边界条件;

1、双指针法(快慢指针法)

思路:

  1. 定义快慢指针;
  2. 利用两个指针分别用于遍历和标记的不同行为高效解题(一个for循环下完成两个for循环的工作)
function removeElement(nums, target) {
  let slow = 0;
  for (let fast = 0; fast < nums.length; fast++) {
    if (nums[fast] !== target) {
      nums[slow++] = nums[fast];
    }
  }
  return slow;
}
  • 时间复杂度:O(n)
  • 空间复杂度:O(1)