前端算法刷题之数组

156 阅读2分钟

自己也刷了一些算法题了,但是做起题来依旧很费劲,时常怀疑自己笨的过分。反思了一下,一是做完就扔,二是哪怕记了笔记,也因为没有条理性不太爱回顾,再者也没有按照分类刷题。所以停下来把之前做过的题整理一下,发到掘金上方便回顾复习。因为能力一般,刷的题大多还比较基础。 可能会分几个章节,第一篇先从数组开始吧!

力扣35简单题:搜索插入位置

给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。

二分查找:

二分可使时间复杂度降低到O(logN)

mid值与目标值相等直接返回下标。如果mid值小于目标数,则左指针右移;如果大于目标数,则右指针左移。

查找结束如果没有相等值则返回 left,该值为插入位置。

var searchInsert = function(nums, target) {
    let left = 0, right = nums.length - 1;
    while (left <= right) {
        let mid = (left + right) >> 1;
        if (nums[mid] === target) return mid;
        if (nums[mid] < target) {
            left = mid + 1;
        } else {
            right = mid - 1;
        }
    }
    return left;
};

力扣27简单题:移除元素

给你一个数组 nums 和一个值 val,你需要 原地 移除所有数值等于 val 的元素,并返回移除后数组的新长度。 不要使用额外的数组空间,你必须仅使用 O(1) 额外空间并 原地 修改输入数组。 元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素。

快慢指针:

快的在前面走,慢的在后面。如果快指针遇到了目标值,就再往前走,慢指针不动。 相当于慢的在遍历数组的时候重新赋值,返回这个慢的。

也就是说,未遇到目标值时,慢指针指向的位置正常赋值快指针指向的值,而遇到需要删除的值时,则快指针移动,慢指针不动。

var removeElement = function(nums, val) {
    let slow=0;
    for(let fast=0;fast<nums.length;fast++){
        //正常情况直接赋值给  
        if(nums[fast]!==val){
            nums[slow]=nums[fast];
            slow++;
        }
        //如果为需要删除的值时,则快指针移动,慢指针不动。
    }
    return slow;
};

力扣26简单题:删除排序数组中的重复项

给定一个排序数组,你需要在 原地 删除重复出现的元素,使得每个元素只出现一次,返回移除后数组的新长度。 不要使用额外的数组空间,你必须在 原地 修改输入数组 并在使用 O(1) 额外空间的条件下完成。

和上题类似

var removeDuplicates = function(nums) {
    if(nums.length==0) return 0;
    let slow=0;
    for(let fast=slow+1;fast<nums.length;fast++){
        if(nums[fast]!=nums[slow]){
            slow++;
            nums[slow]=nums[fast];
        }
    }
    return slow+1;
};

力扣209中等题:长度最小的子数组

给定一个含有 n 个正整数的数组和一个正整数 target 。 找出该数组中满足其和 ≥ target 的长度最小的 连续子数组 [numsl, numsl+1, ..., numsr-1, numsr] ,并返回其长度。如果不存在符合条件的子数组,返回 0 。

双指针,滑动窗口思想:

定义两个指针,用来定位子数组的头和尾。 头指针往前走,然后不断的累加遍历的数,直到和sum大于给定的target,记录这个长度。 然后尾指针前移,看是否还是大于target,更新长度,直到sum小于target。 头指针再继续前移。 持续这个过程,直到头指针到达末尾。

var minSubArrayLen = function(target, nums) {
    let sum=0;
    let child =Infinity;  //表示符合条件的子数组长度!
    let j=0;   //尾指针
    for(let i=0;i<nums.length;i++){
        sum+=nums[i];
        while(sum>=target){
            child=Math.min(i-j+1,child);
            sum-=nums[j];
            j++;
        }
    }
    return child===Infinity?0:child;
};

未完待续,谁能想到做过的题再回顾还像新题一样,我好笨(ㄒoㄒ)