参加训练营前的感想
很早就从对象那边知道代码随想录了哈哈,在参加卡哥的算法训练营前,自己跟着代码随想录的顺序刷题,效率没那么高,也就一天刷一题,周末还给自己放个假,目前已经刷到图论内容了,由于一刷时我是按照代码随想录的顺序来做的,做题时感到有很强的连贯性和阶梯性,有很多题虽然前一天做不出来,但经过总结思考做题的思路方法,第二天做更难的题时运用总结过的方法去做也能自己一次做出来,非常有成就感!回过头看,虽然之前也有用Typora做笔记的习惯,但前面的内容看着已经比较陌生了,有很多题也记不起来做过,做代码题就是要多练,不练则废,所以这次打算通过算法训练营的集中训练来锻炼代码能力,为研二找实习打好基础,希望能坚持下来,60天后一定会收获满满,fighting!
704.二分查找
解题过程
- 采用左闭右闭区间,一次做出来了,不过也是看了这题的题目建议才想到要注意区间的开闭性,下次直接做题目不看题目建议试试。
知识点
- 采用二分法查找的前提是数组为有序数组,且无重复元素,
- 循环不变量规则在本题中运用:区间的定义是不变量,在循环中坚持区间开闭规则,也就是
while (left <= right) {...}
二分法
class Solution {
public:
int search(vector<int>& nums, int target) {
int left = 0;
int right = nums.size() - 1;
int mid;
while (left <= right) {
mid = (right - left) / 2 + left;
if (nums[mid] < target) {
left = mid + 1;
} else if (nums[mid] > target) {
right = mid - 1;
} else return mid;
}
return -1;
}
}
27.移除元素
解题过程
- 记得以前做过时用过双指针法,但还是先用暴力法做了,正好用暴力法验证一下学过的迭代器失效问题。
- 尝试双指针法,试了记下做出来,原来是没注意中文的分号。
知识点
- 使用快慢指针在一次循环里完成目标
- 快指针用来找数组里值不等于val的下标,并更新计数
- 慢指针用来指向新数组下标的位置
暴力解法
class Solution {
public:
int removeElement(vector<int>& nums, int val) {
int count = 0;
auto it = nums.begin();
while (it != nums.end()) {
if (*it != val) {
count++;
it++;
} else {
it = nums.erase(it);
}
}
return count;
}
};
双指针法
class Solution {
public:
int removeElement(vector<int>& nums, int val) {
int result = 0;
int left = 0;
int right = 0;
while (right < nums.size()) {
if (nums[right] != val) {
nums[left++] = nums[right];
result++;
}
right++;
}
return result;
}
};
977.有序数组的平方
解题过程
- 用双指针做出来了,左指针指向数组开头位置,右指针指向数组结尾,比较平方大小,大的插入输出数组的尾部,注意区间开闭。
知识点
- 双指针的时间复杂度为O(n),相对于暴力排序的解法O(n + nlog n)还是提升不少的。
双指针法
class Solution {
public:
vector<int> sortedSquares(vector<int>& nums) {
int len = nums.size();
vector<int>result(len);
int left = 0;
int right = len - 1;
while (left <= right) {
int leftNum = nums[left] * nums[left];
int rightNum = nums[right] * nums[right];
if (leftNum > rightNum) {
result[--len] = leftNum;
left++;
} else {
result[--len] = rightNum;
right--;
}
}
return result;
}
};