长度最小的数组和螺旋矩阵
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;
};