day2打卡

4. 有序数组的平方

输入非递减顺序 排序的整数数组 ,返回 每个数字的平方 组成的新数组,要求也按 非递减顺序 排序。

  1. 暴力的解法

平方后排序,时间复杂度O(n+sort算法)

/**
 * @param {number[]} nums
 * @return {number[]}
 */
var sortedSquares = function(nums) {
    for(let i = 0; i < nums.length; i++) {
        nums[i] *= nums[i]
    }
    nums.sort((a, b) => {return a-b}) // 不同浏览器实现的sort都不同,常见的有归并排序、快速排序和桶排序
    return nums;
};
  1. 双指针法

数组有序,则平方后的最大值只可能在数组两端,可以考虑使用两个指针分别指在起始位置和末尾位置。

/**
 * @param {number[]} nums
 * @return {number[]}
 */
var sortedSquares = function(nums) {
    let left = 0, right = nums.length - 1;
    let result = new Array(nums.length).fill(0);
    let i = nums.length - 1;
    while(i >= 0) {
        if(nums[left] * nums[left] < nums[right] * nums[right]) {
            result[i] = nums[right] * nums[right];
            right--;
        } else {
            result[i] = nums[left] * nums[left];
            left++;
        }
        i--;
    }
    return result;
};

改进后:

/**
 * @param {number[]} nums
 * @return {number[]}
 */
var sortedSquares = function(nums) {
    let left = 0, right = nums.length - 1;
    let result = [];
    while(right >= left) { // =是因为left=right时,仍然没有结束,还需要将此元素追加到新数组
        const i = Math.abs(nums[left]);
        const j = Math.abs(nums[right]);
        if(i < j) {
            result.unshift(j * j);
            right--;
        } else {
            result.unshift(i * i);
            left++;
        }
    }
    return result;
};
5. 长度最小的子数组
  1. 暴力解法,因为使用了两个for循环时间复杂度为O(n2)

测试未通过,原因不明

/**
 * @param {number} target
 * @param {number[]} nums
 * @return {number}
 */
var minSubArrayLen = function(target, nums) {
    let result = Number.MAX_VALUE;
    let sub_length = 0;
    for(let i = 0; i < nums.length; i++) {
        let sum = 0;
        for(let j = i; j < nums.length; j++) {
            sum += nums[j];
            if(sum >= target) {
                sub_length = j - i + 1;
                result = result < sub_length ? result : sub_length;
                break;
            }
        }
    }
    return result == Number.MAX_VALUE ? 0 : result;
};
  1. 滑动窗口

通过一个循环移动两个指针,具体来讲,循环移动右指针,判断sum是否满足条件移动左指针,时间复杂度O(n)。

/**
 * @param {number} target
 * @param {number[]} nums
 * @return {number}
 */
var minSubArrayLen = function(target, nums) {
    let result = Infinity;
    let left = 0;
    let right = 0; // 这样let left, right = 0赋值的语法是错的,ES6新增语法let [left, right] = [0, 0]是正确的
    let sum = 0
    
    while(right < nums.length) {
        sum += nums[right];
        while(sum >= target) {
            let len = right - left + 1;
            result = result < len ? result : len;
            sum -= nums[left];
            left++;
        }
        right++;
    }
    return result === Infinity ? 0 : result;
};
6. 绘制螺旋矩阵

通过offset控制,使用左闭右开的区间

/**
 * @param {number} n
 * @return {number[][]}
 */
var generateMatrix = function(n) {
    let result = Array(n).fill().map(() => Array(n));// 创建二维数组
    let loop = Math.floor(n/2); // n/2=1.5,控制画多少圈
    let mid = Math.floor(n/2);
    let offset = 1; // 控制每一层填充元素个数
    let count = 1; // 每个位置的填充
    let startX = startY = 0; // 起始位置
    while(loop) {
        let row = startX, col = startY;
        for (; col < n - offset; col++) { //n - offset为每层填充的个数,此处为左闭右开,边界不做处理,故为<
            result[row][col] = count++;
        }
        for (; row < n - offset; row++) {
            result[row][col] = count++;
        }
        for (; col > startY; col--) {
            result[row][col] = count++;
        }
        for (; row > startX; row--) {
            result[row][col] = count++;
        }
		// 调整下一圈的位置等
        startX++;
        startY++;

        offset += 1;

        loop--;
    }
    if (n % 2 === 1) {
        result[mid][mid] = count;
    }
    return result;
};
  • 9
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值