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

119 阅读2分钟

数组理论基础

数组是存放在 连续内存空间 上的相同类型数据的集合。

  • 数组下标都是从0开始的。
  • 数组内存空间的地址是连续的
  • 在删除或者增添元素的时候,需要移动其他元素的地址。

704. 二分查找

题目链接:704. 二分查找

题解:

  1. 先确认查找区间的开闭。([left,right] or [left, right))
  2. 确定right的值。
  3. 根据查找区间的开闭情况,确定while循环的条件(left<=right) or (left<right)。
  4. 根据if条件,判断middle的值是否仍需进行搜索,确定边界条件。

两种写法:

1.左闭右闭。

var search = function(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;
};

2.左闭右开。

var search = function(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;
};

补充

在取中间值middle时,通常的想法为:

mid = (left + right)/2

但是js中无法自动取整,于是可以想到导入js库函数进行取值:

mid = Math.floor((left + right)/2)

但当区间很大时,容易溢出,所以使用减法:

mid = left + Math.floor((right - left) / 2)

从代码随想录的解法中学到了:运用右移运算符进行整除运算。

mid = left + ((right - left) >> 1);

mid取值时:位运算 + 防止大数溢出

右移运算符(例):右移运算可以模拟2的 整除运算取整

//右移运算可以模拟2的整除运算
5 >> 1
// 2
// 相当于 5 / 2 = 2

21 >> 2
// 5
// 相当于 21 / 4 = 5

21 >> 3
// 2
// 相当于 21 / 8 = 2

21 >> 4
// 1
// 相当于 21 / 16 = 1

//右移运算可以用来取整
123.456 >> 0
//123

-123.456 >> 0
//123

相关题目:


27. 移除元素

题目链接:27. 移除元素

暴力解法:两个for循环。

var removeElement = function(nums, val) {
	let len = nums.length
	for(let i = 0; i < len; i ++){
        if(nums[i] == val){
            for(let j = i + 1; j < len; j++){
                nums[j - 1] = nums[j]
            }
            i--  // 需要返回一位
            len -- // 数组删除一位
        }
    }
    return len;
};

双指针思路:

两个指针:fast、slow
fast指针:新数组的元素
slow指针:新数组的下标
最后slow的值就是新数组的大小

var removeElement = function(nums, val) {
    slow = 0;
    for (fast = 0; fast < nums.length; fast++){
        if(nums[fast] != val) {
            nums[slow] = nums[fast];
            slow++;
        }
    }
    return slow;
};

相关题目

  • 26.删除排序数组中的重复项
  • 283.移动零
  • 844.比较含退格的字符串
  • 977.有序数组的平方

总结

训练营的第一天,二分法注意right的值和mid值!移除元素注意fast指针和slow指针的意义!
第一天完成啦~ 粗卡粗卡~ 希望自己可以逐渐上手,快速进行博客的一个写~
第二天也要加油鸭!