今天是参加代码随想录的第一天,原来都是使用c语言,也用过一点点java,没有接触过c++,但这次我选择使用c++(单纯喜欢),开头就遇到了一些问题
开始前的准备
今天的题目与数组相关,为了方便调试,我计划在visual studio中使用主函数调用class Solution,但出现了问题
辗转多地解决,原因是没有在开头加上“using namespace std;”,加上后解决问题
第一题-704. 二分查找
主函数
用于自己测试代码运行结果是否正确
int main() {
Solution solution;
vector<int> nums={ -1,0,3,5,9,12};
int target = 2;
int result = solution.search(nums, target);
if (result != -1) {
cout << "目标 " << target << " 在数组中的位置是: " << result << endl;
}
else {
cout << "目标 " << target << " 不在数组中。" <<endl;
}
return 0;
}
解决方法一——左闭右闭
左闭右闭即【left,right】
class Solution {
public:
//左闭右闭
int search(vector<int>& nums, int target) {
int len = nums.size();//数组长度
int left = 0, right = len - 1;
int mid;
//循环--当左边界<=右边界时
//左闭右闭可以取等号
while (left<=right) {
mid = (left + right) / 2;
//目标在左边
if (target < nums[mid]) {
//右闭,mid的值不在范围内,因此减一
right = mid - 1;
}
//目标在右边
else if (target > nums[mid]) {
//左闭,mid的值不在范围内,因此加一
left = mid + 1;
}
//找到目标所在数组位置-mid
else {
return mid;
}
}
//没找到
return -1;
}
};
运行结果
解决方法二——左闭右开
左开右开即【left,right)
class Solution {
public:
//左闭右开
int search(vector<int>& nums, int target) {
int len = nums.size();//数组长度
//取不到right因此可以等于len
int left = 0, right = len;
int mid;
//循环--当左边界<右边界时
//左闭右开不可以取等号
while (left<right) {
mid = (left + right) / 2;
//目标在左边
if (target < nums[mid]) {
//右开,mid的值不在范围内
right = mid;
}
//目标在右边
else if (target > nums[mid]) {
//左闭,mid的值不在范围内,因此加一
left = mid + 1;
}
//找到目标所在数组位置-mid
else {
return mid;
}
}
//没找到
return -1;
}
};
运行结果
第二题- 27. 移除元素
解决方法一——暴力解
class Solution {
public:
int removeElement(vector<int>& nums, int val) {
//两层暴力解法
int count = nums.size();
for (int i = 0; i < count; ) {
//不是被删除的元素
if (nums[i] != val) {
i++;
}
//是被删除的元素
else {
int del = i;
count--;
for (int j = i + 1; j < nums.size(); j++) {
nums[del++] = nums[j];
}
}
}
return count;
}
};
运行结果
【重难】解决方法二——双指针法
这部分是今天的难点,花了较长时间理解,双指针是使用一个快指针和一个慢指针在一个for循环下完成两个for循环的工作。
- 快指针:寻找新数组的元素 ,新数组就是不含有需要被删除元素的数组
- 慢指针:指向更新,新数组下标的位置
简单来说,快指针遇到新数组的元素会把元素的值赋给慢指针所在的位置,快指针遇到需要被删除的元素会前进1,再继续操作,需要注意的是,快指针会遍历完整个原始数组,慢指针不会
class Solution {
public:
int removeElement(vector<int>& nums, int val) {
//快慢指针都从头开始
int fast=0, slow=0;
for (fast = 0; fast < nums.size(); fast++) {
//当前元素不是要被删除的元素,赋值
if (nums[fast] != val) {
nums[slow] = nums[fast];
slow++;
}
//当前元素需要被删除时仅需要fast+1操作,在for循环里
}
return slow;
}
};
运行结果
总结
今天的训练结束啦,大概花费3-4h,由于是第一天,在选择看视频,看文章,做题三件事情的顺序上有一些纠结,由于同样一个题有多种解法,比如第一题,可以直接遍历求解(虽然不太明智,但也能解决),所以我认为第一次做可以先看视频了解一下这道题的优解,再自己写代码实现,会增加解题的效率。