攻克代码随想录Day1(JavaScript) | 704. 二分查找 | 35.搜索插入位置 | 27.移除元素

一、704.二分查找

二分查找是LeetCode上一段非常经典的例题,而二分法也是十分重要的算法之一。由于笔者求职方向是前端工程师,本篇及之后的博客都主要以JavaScript作为编程语言。点击右侧的链接可以跳转至题目:704.二分查找

当我们看到这一题目的时候,对于没有系统性学过数据结构的同学,上来会先选择暴力解法,暴力解法的代码如下:

/**
 * @param {number[]} nums
 * @param {number} target
 * @return {number}
 */
var search = function(nums, target) {
    for(let i = 0;i < nums.length;i++){
        if(nums[i] === target){
            return i;
        }
    }
    return -1;
};

暴力解法的原理非常简单:一个for循环进行遍历,之后就能得出结果。

除此之外,我们接下来要介绍的就是本期的重点二分法,代码如下所示:

/**
 * @param {number[]} nums
 * @param {number} target
 * @return {number}
 */
var search = function(nums, target) {
    let left = 0;
    let right = nums.length;
    while(left < right){
        let mid = left + Math.floor((right - left) / 2);
        if(nums[mid] === target){
            return mid;
        }
        else if(nums[mid] > target){
            right = mid;
        }
        else if(nums[mid] < target){
            left = mid + 1;
        }
    }
    return -1;
};

在二分法中,我采用的是左闭右开的区间设计。原理其实同样很好理解,先声明left和right两个变量,left代表左侧的起始位置0,而right代表数组的长度。我们的数组就在[0,nums.length)的区间里面。

接下来我们设计一个while循环,while循环的条件(left < right)意味着只有区间里存在数组,才继续进行循环。然后我们声明一个在while循环里的变量mid,mid是left和right的平均值。值得注意的是,由于JS的变量声明不像Java或Python,整数做完除法如果没法除尽,将会变成浮点数。因此需要在得出结果之前增加一个**Math.floor()**函数。

之后,我们就可以进行接下来的判断了,如果nums[mid]的值等于target,那我们就将mid的值return出来。当出现其它情况的时候,我们就可以根据nums[mid]和target之间的大小在左侧或右侧缩小区间,而新的left或right又会被代入循环,直至循环结束找到相等的值或返回-1.

二、35.搜索插入位置

LeetCode的35题搜索插入位置也是一道非常经典的二分查找类题目,该题目的代码如下:

/**
 * @param {number[]} nums
 * @param {number} target
 * @return {number}
 */
var searchInsert = function(nums, target) {
    if(target < nums[0]){
        return 0;
    }
    if(target > nums[nums.length - 1]){
        return nums.length;
    }
    let left = 0;
    let right = nums.length;
    while(left < right){
        let mid = left + Math.floor((right - left) / 2);
        if(nums[mid] === target){
            return mid;
        }
        else if(target > nums[mid - 1] && target < nums[mid]){
            return mid;
        }
        else if(target > nums[mid] && target < nums[mid + 1]){
            return mid + 1;
        }
        else if(target <= nums[mid - 1]){
            right = mid;
        }
        else if(target >= nums[mid + 1]){
            left = mid + 1;
        }
    }
    return 0;
};

总体而言,该题的整体思路与二分查找是相似的。但由于该题多了:如果目标值不存在于数组中,返回它将会被按顺序插入的位置的条件。因此我们需要考虑更多的情况。

首先,在函数的开头设计两个if条件判断目标值是否在区间外,若都不是,则target应在区间内有对应的值或者在区间内的两个值之间
接下来跟704题相似地,我们继续进行while循环,在该while循环里我们判断的条件就更多了,直接返回值的有三个条件:1.值相等,2. 在nums[mid-1]和nums[mid]之间,3.在nums[mid]和nums[mid+1]之间,在这三种情况都可以立即返回值。而对于剩下两种情况,类似704题继续缩小区间进行循环,然后就能得到我们的答案啦!

三、27.移除元素

移除元素也是一道非常经典的LeetCode题目,在该题中我们采用的是双指针法(快慢指针法),具体代码如下:

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

该题的思路非常简单,首先声明两个指针,一慢一快,然后利用快指针进行遍历。如果快指针指向的数等同于val,那么慢指针不变,快指针继续遍历;如果不等同的话,那么快指针将所指向的数传递给慢指针,同时慢指针向后移动一格。如此循环,最后我们得到的慢指针的数值就是我们想要的答案。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值