此文为阅读’代码随想录‘所写笔记。代码参考作者’程序员Carl‘(代码随想录)
参考链接:https://programmercarl.com/0027.%E7%A7%BB%E9%99%A4%E5%85%83%E7%B4%A0.html#%E6%80%9D%E8%B7%AF
数组的理论知识
数组是存储在连续内存空间上的相同类型数据的集合。
- 数组下标都是从0开始的
- 数组在内存空间的地址是连续的
因为连续的性质,所以数组在删除或者添加的时候都需要对后续的元素进行操作,如下图所示,数组的元素是不能删的,只能覆盖。
补充:C++中vector的底层实现其实就是array。
1.1二分查找
Leetcode:704.二分查找
思路:
- 有序数组 + 无重复 -> 使用二分法(二分法无法应对多个返回值的情况)
- 设定边界条件:左闭右开(不变量的设定,循环不变量)
class Solution {
public:
int search(vector<int>& nums, int target) {
// 使用左闭右开的写法
int left = 0;
int right = nums.size();
while (left < right){
int middle = left + ((right - left) / 2);
if (nums[middle] < target) {
left = middle + 1;
} else if (nums[middle] > target) {
right = middle;
} else {
return middle;
}
}
return -1;
}
};
1.2双指针
Leetcode:27.移除元素
思路:
- 数组中没有办法真正的删除元素,只能是覆盖
- 使用双指针的方式,相较于暴力解法不会做过多的数据搬运,一次搬运就可以结束
class Solution {
public:
int removeElement(vector<int>& nums, int val) {
int slowIndex = 0;
for (int fastIndex = 0; fastIndex < nums.size(); fastIndex++) {
if (nums[fastIndex] != val) {
nums[slowIndex++] = nums[fastIndex];
}
}
return slowIndex;
}
};
1.3滑动窗口
Leetcode:209.长度最小的子数组
思路:
- 滑动窗口需要注意窗口的起始位置和结束位置,一种变相的双指针
- 满足条件后,起始位置开始滑动(可能多次变化)(while循环)
- 注意初始值、窗口的相关信息的设定(INT32_MAX、窗口内和、窗口长度、起始位置)
class Solution {
public:
int minSubArrayLen(int target, vector<int>& nums) {
int results = INT32_MAX;
// 设计滑动窗口
int sum = 0;
int length = 0;
int index = 0;
for (int i = 0; i < nums.size(); i++) {
sum += nums[i];
while (sum >= target) {
// 可以开始滑动了
length = i - index + 1;
results = results < length ? results : length;
sum -= nums[index++];
}
}
return results == INT32_MAX ? 0 : results;
}
};
1.4螺旋矩阵
Leetcode:59.螺旋矩阵 II
思路:
- 规定每次循环的不变量——左闭右开
- 注意每次循环的开始位置(startx)和结束位置(startx+length-1)
class Solution {
public:
vector<vector<int>> generateMatrix(int n) {
vector<vector<int>> res(n, vector<int>(n, 0));
int startx = 0;
int starty = 0;
int loop = n / 2;
int length = n;
int count = 1;
int mid = n / 2;
while (loop--) {
int i = startx;
int j = starty;
for (j = starty; j < starty + length - 1; j++) {
res[i][j] = count++;
}
for (i = startx; i < startx + length - 1; i++) {
res[i][j] = count++;
}
for (; j > starty; j--) {
res[i][j] = count++;
}
for (; i > startx; i--) {
res[i][j] = count++;
}
startx++;
starty++;
length -= 2;
}
if (n % 2) {
res[mid][mid] = count;
}
return res;
}
};