1、在跑步路上念叨一边自己每天学的算法,感觉很适合消化,跑步也不无聊了,希望可以坚持下去。
2、今天学的代码随想录部分的内容主要是
二分查找 | 左闭右闭区间 |
左闭右开区间 | |
数组元素删除 | 暴力双层循环 |
双指针 |
3、二分查找需要注意的地方
while循环中left和right的关系处理 | 如果是左闭右闭,则<=合法; 如果是左闭右开,则<合法 |
变换左右边界时middle的关系处理 | 如果是左闭右闭,则left = middle + 1; right = middle -1; 如果是左闭右开,则left = midde + 1; right = middle ; |
middle表示 | 防止越界,表示为middle = left + (right - left)/2; 原先纠结过的奇数偶数问题,如果分情况讨论的话就会发现根本不会影响middle。而左右边界的处理完全是看区间开闭和middle的关系。因此这个就不需要再有疑虑。 |
4、双指针
指针 | fast 和 slow不是真正的指针,功能和画图类似指针。 |
原理 | fast遍历原数组,slow代表新数组。原数组中除去需要删除的元素以外的所有元素放到新数组中,即for(fast = 0; fast<n; fast++){ if(nums[fast] != val) { nums[slow++] = nums[fast]; } |
自增自减操作 | nums[slow++] = nums[fast] <==> nums[slow] = nums[fast]; slow++;即先操作后自增。这一块老是记不住真的很离谱 |
5、移除元素
这块最开始犯了两个错误
如下代码 | 当 i = numsSize - 1 时,nums[j+1]越界 |
i - - | 元素被删除后,所有元素全部前移,i 对应的元素其实是原来数组中i+1对应的元素。这个元素并没有判断是否是要被删除的元素。所以此时需先i - -, 再执行循环中的 i + + 操作,才能把这个漏网之鱼考虑进去。 |
int removeElement(int* nums, int numsSize, int val){
int i;
int j;
for(i=0; i<numsSize; i++)
{
if(nums[i]==val)
{
for( j=i; j<numsSize; j++)
{
nums[j] = nums[j+1];
}
i--;
numsSize--;
}
}
return numsSize;
}
写这一块时脑子又犯了迷糊,开始思考为什么正确答案那种解法不会越界呢
int removeElement(int* nums, int numsSize, int val){
int i;
int j;
for(i=0; i<numsSize; i++)
{
if(nums[i]==val)
{
for( j=i + 1; j<numsSize; j++)
{
nums[j - 1] = nums[j];
}
i--;
numsSize--;
}
}
return numsSize;
}
我们看内层循环的条件,当 j < numsSize 时跳出循环。而当 i = numsSize - 1 时,j = numsSize,也就是说这时候时不进入循环的,也就不会出现 nums[ j ], 自然也就不会越界。而我犯的那个错误呢,是实实在在存在着nums[ j ] 即nums[ numsSize ] 的,实实在在是越界了的。
6、总体来说今天的任务比较轻松,但是拓展题目没做完,力扣上还有一些高效的解法没有分析,还有一些录友的优化没有看,明天要尽量补上。第一次写博客,风格是按自己熟悉的来的,没有太在意规不规范,但是感觉这个风格可以让自己坚持下去,所以还是怎么舒服怎么来吧。