数组
数组基本概念
- 数组是存放在连续内存空间上的相同类型数据的集合
- 数组下标都是从0开始的
- 数组内存空间的地址是连续的
- 数组的元素是不能删的,只能覆盖
- 二维数组在内存的空间地址是连续的么?
- 不一定,比如在c++中是,但是在java中不是
- 数组方便查找,不方便插入和删除,这和它存储的空间连续有关
主要方法
- 二分法
- 双指针(快慢指针)
- 滑动窗口
示例
二分查找
题目链接:[704.二分查找](Loading Question… - 力扣(LeetCode) (leetcode-cn.com))
解答:二分法
var search = function(nums, target) {
let left = 0, right = nums.length - 1;
while(left <= right){
// let mid = left + Math.floor((right - left) / 2);
let mid = left + ((right - left) >> 1);
if(nums[mid] < target){
left = mid + 1;
} else if(nums[mid] > target){
right = mid - 1;
} else {
return mid;
}
}
return -1;
};
说明:
-
注意根据while里面的条件判断区间的开闭情况,
right = nums.length - 1
和while(left <= right)
则为左闭右闭区间,所以left = mid + 1;
right = mid - 1
。 -
right = nums.length
和while(left < right)
则为左闭右开区间,所以left = mid + 1;
right = mid
。 -
注意
let mid = left + ((right - left) >> 1);
其中的((right - left) >> 1)
是需要用括号括起来的,不然的话会出错,因为优先级的问题。
移除元素
题目链接:[27.移除元素](Loading Question… - 力扣(LeetCode) (leetcode-cn.com))
解答:快慢指针
var removeElement = function(nums, val) {
let left = 0;
for(let i = 0; i < nums.length; i++){
if(nums[i] !== val){
nums[left++] = nums[i];
}
}
return left;
};
有序数组的平方
题目链接:[977.有序数组的平方](977. 有序数组的平方 - 力扣(LeetCode) (leetcode-cn.com))
解答:双指针
var sortedSquares = function(nums) {
let left = 0, right = nums.length - 1, k = nums.length - 1;
let res = new Array(nums.length).fill(0);
while(left <= right){
let l = nums[left] * nums[left];
let r = nums[right] * nums[right];
if(l < r){
res[k--] = r;
right--;
} else {
res[k--] = l;
left++;
}
}
return res;
};
长度最小的子数组
题目链接:[209.长度最小的子数组](209. 长度最小的子数组 - 力扣(LeetCode) (leetcode-cn.com))
解答:滑动窗口
滑动窗口的精妙之处在于根据当前子序列和大小的情况,不断调节子序列的起始位置
var minSubArrayLen = function(target, nums) {
let left = 0, len = Infinity, sum = 0, subLen = 0;
for(let right = 0; right < nums.length; right++){
sum += nums[right];
while(sum >= target){
subLen = right - left + 1;
len = Math.min(subLen, len);
sum -= nums[left++];
}
}
return len === Infinity ? 0 : len;
};
螺旋矩阵II
题目链接:[59.螺旋矩阵II](59. 螺旋矩阵 II - 力扣(LeetCode) (leetcode-cn.com))
解答:模拟
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;
// n - offset表示剩余长度,startY + 剩余长度正好是这一圈循环的边界
for(;col < startY - offset + n; col++){
res[row][col] = count++;
}
for(;row < startX - offset + n; row++){
res[row][col] = count++;
}
for(;col > startX; col--){
res[row][col] = count++;
}
for(;row > startX; row--){
res[row][col] = count++;
}
startX++;
startY++;
offset += 2; // 每走完一圈都会加2
}
// 如果是奇数时需要另外处理
if(n % 2 === 1){
res[mid][mid] = count;
}
return res;
};