704.二分查找
思路:一个升序的有序数组,要找到目标值;
1.首先暴力当然是可以的,for循环遍历数组中所有元素,等于目标值时,返回下标。
2.二分查找:这里涉及到左闭右闭和左闭右开两种情况
2.1 左闭右闭[]
定义目标值在一个左闭右闭的区间,用while来判断二分是否停止,while(left<=right),
因为是左闭右闭,所以left = right的情况存在且允许。如果nums[mid]<target,说明target位于右区间,我们要更新左边界为mid+1;反过来就是更新右边届为mid-1。
class Solution {
public:
int search(vector<int> &nums, int target){
int left = 0;
int right = nums.size() - 1;//左闭右闭区间,最右边元素索为数组大小减一,数组首元素索引为0
while(left <= right){//定义的为左闭右闭区间,left==right也需要考虑到
int mid = left + ((right - left)/2);//防止数据溢出
if(nums[mid] > target){//数组中间元素大于目标值,说明目标值在中间元素左边,数组为升序排列
right = mid - 1;//target 在左区间,所以[left, mid-1]
}
else if(nums[mid] < target){
left = mid + 1;//target 在右区间,所以[mid+1,right]
}
else{//target == mid
return mid;//直接返回下标
}
}
return -1;
}
};
2.2 左闭右开
class Solution {
public:
int search(vector<int>& nums, int target) {
int left = 0,right = nums.size();
while(left < right){
int mid = left + ((right - left)/2);
if(nums[mid] > target){
right = mid;
}
else if(nums[mid] < target){
left = mid + 1;
}
else {
return mid;
}
}
return -1;
}
};
27.移除元素
思路:
1.暴力
2.双指针法
定义两个指针,在一个for循环中执行
快指针:遍历数组元素,并生成新数组;
慢指针:只想更新数组的下标
快慢指针初始化都为0,for循环快指针遍历数组元素,并与目标值比较,若不相等,元素成为新数组的一个元素,快慢指针各递加1;若相等,就要去除,将快指针指到的元素赋值给慢指针指到的元素,快指针加1;
class Solution {
public:
int removeElement(vector<int>& nums, int val) {
/*暴力
int liu = nums.size();
for(int i = 0; i < liu; i++){
if(nums[i] == val){
for(int j = i + 1;j < liu; j++){
nums[j - 1] = nums[j];
}
i--;
liu--;
}
}
return liu;*/
//双指针
int slow = 0;
for(int fast = 0; fast < nums.size(); fast++){
if(val != nums[fast]){
nums[slow] = nums[fast];
slow++;
}
}
return slow;
}
};