我正在参加「掘金·启航计划」
第一章 数组
数组定义
参考代码随想录的讲解:数组是存放在连续内存空间上的相同类型数据的集合,数组可以很方便的通过下标来获取对应的数据.
有2个注意点
- 下标都是从0开始
- 数组内存空间的地址都是连续的
因为数组内存空间的地址都是连续的,所以删除或者添加某一项时候,就难免要移动其他元素的地址。数组的元素是不能删的,只能覆盖。
leetcode 704二分查找
这题的前提条件是数组为有序数组,且没有重复项,有重复元素时,找出的下标可能不唯一,这也是使用二分法的前提条件。 已经刷完N次本题,但是都没记住用while循环,还是写文章记下来比较好。首先找到要查找的targer的区间,区间划分一般有两种左闭右闭即[left, right],或者左闭右开即[left, right),区间的定义就是不变量要在二分查找的过程中,保持不变量,就是在while寻找中每一次边界的处理都要坚持根据区间的定义来操作,这就是循环不变量规则。
-
第一种 左闭右闭[left, right],即target在区间中间,两头都有可能
/** * @param {number[]} nums * @param {number} target * @return {number} */ var search = function(nums, target) { // 首先定义left,right,从0开始,right取length - 1,nums[right]是数组最后一个值,所以right可以闭合 let left = 0,right = nums.length - 1 while(left <= right) { // 找数组长度的中位数 const middle = left + ((right-left) / 2) // 防止溢出 等同于(left + right)/2 if(nums[middle] > targer) { right = middle - 1 // target 在左区间,所以[left, middle - 1] } else if(nums[middle] < terget) { left = middle + 1 // target在右区间,所以[middle + 1, right] } else { // nums[middle] = target return middle } } // 没有找到目标值 return -1 }; -
左闭右开 [left,right)
// 代码和上边去吧,主要看区间 var search = function(nums, target) { let left = 0,right = nums.length; while(left < right) { // 区别 右边区间是不包含的,所以left < right而不能等于right const middle = left + ((right - left) >> 1) if(nums[middle] > target) { right = middle // 同上,右边不能等于,所以不能减1 } else if(nums[middle] < target) { left = middle + 1 } else { return middle } } return -1 };
leetcode 27移除元素
因为数组的元素是不能删的,只能覆盖。
-
解法1 暴力解法 所以如果当前元素和val相等的话,就把后边的一位移过来覆盖掉当前
/** * @param {number[]} nums * @param {number} val * @return {number} */ var removeElement = function(nums, val) { let size = nums.length for(let i = 0; i < size; i++) { if(nums[i] === val) { for(let j = i + 1; j < size; j++) { nums[j - 1] = nums[j] // 把后一位的值赋值给前一位 } i--; // 因为下标i以后的数值都向前移动了一位,所以i也向前移动一位 size--; // 此时数组的大小-1 } } return size };- 时间复杂度:O(n^2)
- 空间复杂度:O(1)
-
解法2 双指针法 双指针法(快慢指针法): 通过一个快指针和慢指针在一个for循环下完成两个for循环的工作。
- 快指针:寻找新数组,新数组就是不含有目标元素的数组
- 慢指针:指向更新 新数组下标的位置
/** * @param {number[]} nums * @param {number} val * @return {number} */ var removeElement = function(nums, val) { let slow = 0 for(let i = 0; i < nums.length; i++) { if(nums[i] !== val) { // 当前不是需要的val的时候,slow才会+1,否则slow就在原地 nums[slow++] = nums[i] } } return slow };
代码参照代码随想录