写在前面:
- 本人基础相当相当薄弱 本科四年几乎没写过代码
- 研究生决定痛改前非 好好学习
- 什么语言都学过一点(本科有过课程),什么语言都没学会(可能只会输入输出)
- 在这纯属自己记录 监督自己的学习历程
数组的基础知识(找了自己认为不太熟的几点)
//数组内存空间的地址是连续的
//数组的元素是不能删的,只能覆盖
//C++中二维数组是连续分布的
//因为数组的在内存空间的地址是连续的,所以我们在删除或者增添元素的时候,就难免要移动其他元素的地址
704 二分法查找(这个考研的时候学过一遍了,但是写代码还是有点费劲,代码能力真是差的要命)
- 大前提是数组有序
- 主要思想就是利用左右两个指针,找出中间位置(利用有序性),根据中间位置的值可以判断是移动哪个指针
代码如下:
class Solution {
public:
int search(vector<int>& nums, int target) {
int left=nums.size()-1;
int right=0;
while(right<=left){
int m=(left+right)/2;
if(nums[m]>target)
left=m-1;
else if(nums[m]<target)
right=m+1;
else if(nums[m]==target)
return m;
else
return -1;
}
return -1;
}
};
27 移除元素
- 不增加空间来移动数组(这涉及到了前面提到的因为数组空间的地址是连续的,所以删除元素时就要移动别的元素)
- 自己写了好久想用暴力的解法没解出来,看了别人的代码,瞬间感觉好神奇
暴力解法(感觉好像也没有很暴力,至少代码很简洁哈哈哈)
- 相当于把等于val的值用最后一个元素覆盖掉
- 之后遍历还是要从当前元素开始(更新后的),所以是i--
class Solution {
public:
int removeElement(vector<int>& nums, int val) {
int len=nums.size();
for(int i=0;i<len;i++)
if(nums[i]==val){
nums[i--]=nums[--len];
}
return len;
}
};
左右指针(照着题解敲的)
- 相当于两个指针,从一边开始遍历(跟二分法查找不同),有个题解说这两个指针是暧昧的夫妻
- 左指针跟着右指针行动,如果没有val,左指针就相应跟着右指针变化(相当于更新数组),如果有val则跳过
- 更新后的数组就是不含val值的了
class Solution {
public:
int removeElement(vector<int>& nums, int val) {
int right=0;
int len=nums.size();
int left=0;
for( right=0;right<len;right++){
if(nums[right]!=val){
nums[left]=nums[right];
left++;
}
}
return left;
}
};
总结一下
这两个题都用到了两个指针的方法,这种思想值得借鉴,有时总想着从一边遍历,以后应该想到多借助个“工具”可能效果更好,有一种“男女搭配,干活不累“的感觉哈哈哈哈哈。
还有就是自己的代码能力真的很差,需要加强一下。
最后,这是第一天。前路漫漫,道阻且长,加油!