day2. 977.有序数组的平方 ,209.长度最小的子数组 ,59.螺旋矩阵II(js版本)

977.有序数组的平方

暴力解法:map求平方 sort排序

var sortedSquares = function(nums) {
    const arr = nums.map((item)=>{
        return item*item
    })
    // console.log(arr)
    arr.sort((a, b) => a - b) //递增排序
    return arr
    
};

左右指针思想:数组有序,平方最小值肯定在数组中间,利用左右指针找出平方最大值放入新数组,然后指针左移/右移,重复上述操作。

/**
 * @param {number[]} nums
 * @return {number[]}
 */
var sortedSquares = function(nums) {
    //左右指针思想
    let left = 0,right = nums.length-1
    let res = []
    let k = nums.length-1
    while(left <= right){
        if(nums[left] * nums[left] < nums[right] * nums[right]){
        res[k] = nums[right] * nums[right]
        k--
        right--
    }else{
        res[k] = nums[left] * nums[left]
        k--
        left++
        }
    }
    
    return res
    
};

209.长度最小的子数组

/**
 * @param {number} target
 * @param {number[]} nums
 * @return {number}
 */
var minSubArrayLen = function(target, nums) {
    let left=0, ans=Infinity, sum =0
    for(let right = 0; right < nums.length; right++){
        sum += nums[right]
        while(sum >= target){
            ans = Math.min(ans, right-left+1)
            sum -= nums[left]
            left++
        }
    }

    return ans === Infinity ? 0 : ans

};

滑动窗口基本思想
for 遍历窗口终止位置,每遍历一个元素计算窗口的值
满足whlie条件时,开始收缩窗口,左指针右移,直到不满足条件,并记录当前窗口最小长度。

let ans = Infinity 如果使用 min() 默认初始值为无穷大,并在return中判断边界条件。

时间复杂度为O(n)?
时间复杂度:算法的时间复杂度是一个函数,它定性描述该算法的运行时间,时间复杂度常用大O符号表述,不包括这个函数的低阶项首项系数。通常将程序语句的执行次数表示为T(n),根据Tn的渐进估算值,将时间复杂度来表示。
T(n)是常数:时间复杂度为O(1);
T(n)不是常数:时间复杂度为O(T(n)的最高次项并且去掉最高次项的系数)。

本题算法中执行语句,虽然存在两层循环,但主要是看每一个元素被操作的次数,每个元素在滑动窗后进来操作一次,出去操作一次,每个元素都是被操作两次,所以时间复杂度是 2 × n 也就是O(n)。

59.螺旋矩阵II

思路:遵循循环不变量原则,也就是对边界条件的处理,顺时针模拟填充数字的过程,由外到内,每条边坚持左闭右开。从第二圈开始的起始位置x,y都要+1。如果n为奇数的话,还需要单独给矩阵最中间的位置赋值

/**
 * @param {number} n
 * @return {number[][]}
 */
var generateMatrix = function(n) {
    let startX = startY = 0;   // 起始位置
    let loop = Math.floor(n/2);   // 旋转圈数
    let mid = Math.floor(n/2);    // 中间位置
    let offset = 1;    // 控制每一层填充元素个数
    let count = 1;     // 更新填充数字
    let res = new Array(n).fill(0).map(() => new Array(n).fill(0));

    while (loop--) {
        let row = startX, col = startY;
        // 上行从左到右(左闭右开)
        for (; col < startY + n - offset; col++) {
            res[row][col] = count++;
        }
        // 右列从上到下(左闭右开)
        for (; row < startX + n - offset; row++) {
            res[row][col] = count++;
        }
        // 下行从右到左(左闭右开)
        for (; col > startY; col--) {
            res[row][col] = count++;
        }
        // 左列做下到上(左闭右开)
        for (; row > startX; row--) {
            res[row][col] = count++;
        }

        // 更新起始位置
        startX++;
        startY++;

        // 更新offset
        offset += 2;
    }
    // 如果n为奇数的话,需要单独给矩阵最中间的位置赋值
    if (n % 2 === 1) {
        res[mid][mid] = count;
    }
    return res;
};
  

今天第三题没思路,需要加强练习,第二题滑动窗口思想写熟,第一题ac。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值