LeetCode 704.二分查找
相关学习
分析
初步理解与思路:
1.设置两个变量用来实现二分查找的查找范围收缩,low=0、hight=nums.size(); mid=(low+hight)/2
2.再通过mid与target比较来收缩范围。
随想录读后理解
初步理解的遗漏,收缩范围就是对区间进行操作,其中是选择左开还是右开等未能深度理解其中作用
疑问:什么叫做循环不变量?
代码实现
//左闭右闭
int low=0,hight=nums.size()-1;
int mid;
while(low<=hight){
mid=(low+hight)/2;
//防止溢出且等同于mid=(low+hight)/2;
//mid=low+((hight-low)/2);
//mid=low+((hight-low)>>1);??
if(nums[mid]==target){return mid;}
else if(nums[mid]<target){ low=mid+1;}
else if(nums[mid]>target){hight=mid-1;}
}
return -1;
}
//左闭右开
int low=0,hight=nums.size();
int mid;
while(low<hight){
mid=(low+hight)/2;
mid=low+((hight-low)/2);
//mid=low+((hight-low)>>1);??
if(nums[mid]==target){return mid;}
else if(nums[mid]<target){ low=mid+1;}
else if(nums[mid]>target){hight=mid;}
}
return -1;
}
代码分析:
- 关键点Ⅰ:区间定义 左闭右闭、左闭右开
左闭右闭区间 如数组a[8] 其区间为 low=0、hight=7;
条件为low<=hight,low=mid+1,hight=mid-1; 因为mid已经判断过,收缩区间中无mid。
左闭右开区间 区间为low=0、hight=8;
条件为 low<hight,low=mid+1,hight=mid.因为为右开 low==hight不存在故无等号,hight=mid 是需要保持右开的状态,最后一个比较元素为low位置。
查找的情况不同:
左闭右闭查找情况如下
左闭右开查找情况如下 - 关键点Ⅱ 防止溢出且等同于mid=(low+hight)/2;
//mid=low+((hight-low)/2);
//mid=low+((hight-low)>>1);
笔记整理与收获
LeetCode 27-移除元素
相关学习
分析
初步理解与思路:
1.设置一个遍历变量依次往后遍历整个给数组,长度为原数组长度。设置一个累计变量记录不相等的元素数量,最后将该值返回即为数组长度,遍历变量++。每找到一个元素,将后续元素前移一位,重新判断。
2.设置快慢变量,慢变量为最后剩下元素数量,快变量为遍历变量。
随想录读后理解
初步理解的遗漏,后继元素前移遍历数还是会继续往后遍历,但是前移的元素就会被跳过判断。使用快慢变量能更加准确的继续替换,而不出现前移的元素被跳过。遍历变量作为快变量,low变量作为慢变量。
另一种方式,可以采用两头并进的方式,将需要删除的元素移到后面,故从前找需要删除的,从后找不需要删除的,交换两个位置的值,直到前后“指针”会于一点。
代码实现
int size=nums.size();
int low=0;
for(int i=0;i<size;i++){
if(nums[i]!=val){nums[low++]=nums[i];}
}
return low;
}
//代码随想录
int rear=nums.size()-1;
int front=0;
while(front<=rear){
while(front<=rear&&nums[front]!=val){front++;}
while(front<=rear&&nums[rear]==val){rear--;}
if(front<rear){nums[front++]=nums[rear--];}
}
return front;
}
代码分析:
- 关键点Ⅰ:快慢指针
常用于将两个循环简化成一个循环。对于数组的覆盖较为方便。 - 关键点Ⅱ :两个指针,一个从前遍历,一个从后遍历。 需要注意的是,再设置两个方向遍历时,== 其中的变量如 front 或rear都是在变化的,故也需要加上判断条件如 front<=rear ==。因为在front与rear相遇之前就实现了题目的要求,也就不需要进行交换了。
笔记整理与收获
VsdeDebug代码
#include<iostream>
using namespace std;
//二分查找
/*
void search(int a[], int size, int target){
int low = 0,hight;
int mid;
//左闭右闭
hight = size - 1;
while (low <= hight){
mid = low + ((hight - low) >> 1);
if (a[mid] > target){
cout << "当前找到位置为:" << mid << " 其值:" << a[mid] << endl;
hight = mid - 1;
}
else if (a[mid] < target){
cout << "当前找到位置为:" << mid << " 其值:" << a[mid] << endl;
low = mid + 1;
}
else if (a[mid] == target){
cout << "找到target位置为:" << mid <<" 值为:"<< a[mid] << endl;
return;
}
}
cout << "未找到target位置"<< endl;
//左闭右开
hight=size;
while (low < hight){
mid = low + ((hight - low) >> 1);
if (a[mid] > target){
cout << "当前找到位置为:" << mid << " 其值:" << a[mid] << endl;
hight = mid ;
}
else if (a[mid] < target){
cout << "当前找到位置为:" << mid << " 其值:" << a[mid] << endl;
low = mid + 1;
}
else if (a[mid] == target){
cout << "找到target位置为:" << mid << " 值为:" << a[mid] << endl;
return;
}
}
cout << "未找到target位置" << endl;
}*/
//移除元素
int remove(int a[],int size,int val){
int low = 0;
for (int i = 0; i < size; i++){
if (a[i] != val){
a[low] = a[i]; low++;
}
}
return low;
}
int remove_2(int a[], int size, int val){
int front = 0;
int rear = size - 1;
while (front <= rear){
while (front <= rear&&a[front] != val){ front++; }
while (front <= rear&&a[rear] == val){ rear--; }
if (front < rear){ a[front++] = a[rear--]; }
}
return front;
}
void test_array(){//创建一个一维数组,并输出。
int array[4] = { 2, 3, 2, 3 };
for (int i = 0; i < 4; i++){
cout << array[i]<<" "<<endl;
}
int len=remove_2(array, 4, 3);
cout << len << endl;
//search(array,6,9);
}
int main(){
test_array();
}