前言
一个本硕双非的小菜鸡,备战24年秋招,计划二刷完卡子哥的刷题计划,加油!
二刷决定精刷了,于是参加了卡子哥的刷题班,训练营为期60天,我一定能坚持下去,迎来两个月后的脱变的,加油!
推荐一手卡子哥的刷题网站,感谢卡子哥。代码随想录
数组知识点
数组是存放在连续内存空间上的相同类型数据的集合。
数组下标都是从0开始的。
数组内存空间的地址是连续的。二维数组一样如此。
因为数组的在内存空间的地址是连续的,所以我们在删除或者增添元素的时候,就难免要移动其他元素的地址。数组的元素是不能删的,只能覆盖。
vector的底层实现是array,严格来讲vector是容器,不是数组。
一、 704. 二分查找
704. 二分查找
Note:左闭右闭区间规则的二分法,注意right得-1计算,否则在数组长度为1的情况会发生内存泄漏。
class Solution {
public:
int search(vector<int>& nums, int target) {
int left = 0;
int right = nums.size() - 1;
while (left <= right) {
int middle = left + ((right - left) / 2);
if (nums[middle] > target)
right = middle - 1;
else if (nums[middle] < target)
left = middle + 1;
else
return middle;
}
return -1;
}
};
Note:左闭右开区间规则的二分法,注意right不用-1了。
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)
right = middle;
else if (nums[middle] < target)
left = middle + 1;
else
return middle;
}
return -1;
}
};
Note:左开右闭区间规则的二分法,变化不小:left初始值为-1,middle计算得+1
class Solution {
public:
int search(vector<int>& nums, int target) {
int left = -1;
int right = nums.size() - 1;
while (left < right) {
int middle = left + ((right - left + 1) / 2);
if (nums[middle] > target)
right = middle - 1;
else if (nums[middle] < target)
left = middle;
else
return middle;
}
return -1;
}
};
二、27. 移除元素
Note:暴力/快慢指针
暴力:
class Solution {
public:
int removeElement(vector<int>& nums, int val) {
int size = nums.size();
for (int i = 0; i < size; i++) {
if (nums[i] == val) {
for (int j = i + 1; j < size; j++)
nums[j - 1] = nums[j];
i--;
size--;
}
}
return size;
}
};
快慢指针交换
class Solution {
public:
int removeElement(vector<int>& nums, int val) {
int slowIndex = 0;
int fastIndex = 0;
int size = nums.size();
for (fastIndex; fastIndex < size; fastIndex++) {
if (nums[fastIndex] != val)
swap(nums[slowIndex++], nums[fastIndex]);
}
return slowIndex;
}
};
总结
写二分法经常写乱,主要是因为对区间的定义没有想清楚,区间的定义就是不变量。要在二分查找的过程中,保持不变量,就是在while寻找中每一次边界的处理都要坚持根据区间的定义来操作,这就是循环不变量规则。
写二分法,区间的定义一般为两种,左闭右闭即[left, right],或者左闭右开即[left, right)。