长度最小的数组和螺旋矩阵

本文介绍了使用JavaScript实现的三种算法:有序数组的平方(双指针解法),寻找长度最小的子数组(滑动窗口),以及生成螺旋矩阵。文章详细展示了暴力解法和优化后的解决方案,涉及数据结构和算法的应用。
摘要由CSDN通过智能技术生成

长度最小的数组和螺旋矩阵

1. 有序数组的平方

JS内置API

遍历数组,先平方,后排序

/**
/**
 * @param {number[]} nums
 * @return {number[]}
 */
// 暴力解法
var sortedSquares = function(nums) {
    let res = nums.map(num => num * num).sort((a,b) => a - b );
    return res;
};

双指针

左右指针位于两侧,比较两个指针值的平方,然后按照大小依次倒序放入数组中。

/**
 * @param {number[]} nums
 * @return {number[]}
 */
// 双指针解法
var sortedSquares = function(nums) {
    // 定义开始和结束指针
    let start = 0, end = nums.length - 1;
    let res = [];
    for(let i = end; i >=0; ) {
        // 计算左右指针的平方
        let leftNumber = nums[start] * nums[start];
        let rightNumber = nums[end] * nums[end];
        // 比较两个值,较大的放入结果集
        if(leftNumber < rightNumber) {
            res[i--] = rightNumber;
            end--;
        } else {
            res[i--] = leftNumber;
            start++;
        }
    }
    return res;
}
};

2. 长度最小的子数组

暴力解法

两个循环,找第i位和第i位后面的j位,这段位置的sum之和大于target且j - i + 1(子数组的长度)最小即可

/**
 * @param {number} target
 * @param {number[]} nums
 * @return {number}
 */
// 暴力解法,要求返回长度
var minSubArrayLen = function(target, nums) {
    let res = Infinity, sum = 0, tempArr = 0;
    // 遍历数组,求sum
    for(let i = 0; i < nums.length; i++){
        // 重置sum
        sum = 0;
        for(let j = i; j < nums.length; j++) {
            sum += nums[j];
            // 判断sum和 target的大小
            if(sum >= target) {
                // 计算子数组的长度
                tempArr = j - i + 1;
                // tempArr如果比res小,则res更改为tempArr
                res = tempArr < res ? tempArr:res;
                break;
            }
        }
    }
    return res === Infinity ? 0 : res;
}

滑动窗口

双指针的一种,结束指针是当前遍历的位置,然后不断移动开始位置的指针(形成滑动窗口),直到找到最小的子数组长度。

/**
 * @param {number} target
 * @param {number[]} nums
 * @return {number}
 */
// 滑动窗口:结束指针就是当前遍历的位置,然后不断移动开始位置的指针
var minSubArrayLen = function(target, nums) {
    let res = Infinity, sum = 0, subArr = 0, i = 0;
    for(let j = 0; j <= nums.length;j++) {
        sum += nums[j];
        while(sum >= target) {
            subArr = j - i + 1;
            res = subArr < res ? subArr : res;
            sum -= nums[i++];  // 起始指针向前移动
        }
    }
    return res === Infinity ? 0:res;
}

3. 螺旋矩阵

/**
 * @param {number} n
 * @return {number[][]}
 */
var generateMatrix = function(n) {
    let startX = startY = 0; // 定义每一轮循环圈的起点和终点位置
    let loop = Math.floor(n / 2);     // loop表示遍历一圈的次数
    let mid = Math.floor(n / 2);  // mid表示矩阵中间的位置,比如n = 3, mid = (1,1)
    let count = 1;  // 从(0,0)开始计数,从1开始
    let offset = 1;  // 左闭右开区间,用于控制每一条边遍历的长度
    let res = new Array(n).fill(0).map(() => new Array(n).fill(0));
    while(loop--) {
        let row = startX;
        let 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;
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值