代码随想录算法训练营第一天
704. 二分查找
题目链接: 704. 二分查找
二分法查找就是过改变边界值缩小搜索区间(集合),减少循环次数,在有序的集合中查找元素都可以考虑是否使用二分法查找。
-
方法一:在升序,元素不重合的左闭右闭区间搜索,需要考虑left = right,因为循环到最后存在单一元素搜索区间(集合):[target]
class Solution { public: int search(vector<int>& nums, int target) { int left = 0; int right = nums.size()-1; //从0开始,最后一个元素下标是size-1 while(right >= left){ int mid = (left+right)/2; if(nums[mid] > target){ right = mid - 1; //下次右边从mid的前一个mid-1开始 }else if(nums[mid]<target){ left = mid + 1 ; }else{ return mid; } } return -1; } };
-
方法二:在升序,元素不重合的左闭又开区间搜索,不需要考虑left = right,因为当区间内只有一个元素时,左闭右开不合法
class Solution { public: int search(vector<int>& nums, int target) { int left = 0; int right = nums.size(); //为保证数组中所有元素都被包括,搜索区间[0,最后一个元素下标+1) while(right > left){ int mid = (left+right)/2; if(nums[mid] > target){ right = mid ; //nums[middle] > target 表明 middle 及其右侧的元素都不可能是 target,因为它们都比目标值大。 //由于区间是左闭右开,更新 right = middle 将 middle 索引处的元素排除在下一次搜索的区间外,即下一个查询区间是 [left, middle),不包括 middle。 }else if(nums[mid]<target){ left = mid + 1 ; }else{ return mid; } } return -1; } };
27. 移除元素
题目链接: 27. 移除元素
数组是连续的,不能移除只能覆盖。
- 暴力解法:遍历数组每遇到目标元素就把目标元素后面所有的元素都前移一位
class Solution { public: int removeElement(vector<int>& nums, int val) { int size = nums.size(); for(int i = 0;i < size;i++){ if(nums[i]==val){ for(int j = i;j<size-1;j++){ nums[j] = nums[j+1]; } size--; i--; } } return size; } };
- 双指针写法:模拟定义一个新数组,将不是目标值的原数组的数赋值给新数组,再把新数组的容量++。
class Solution { public: int removeElement(vector<int>& nums, int val) { int new_p = 0; for(int old_p = 0;old_p < nums.size();old_p++){ if(nums[old_p] != val){ nums[new_p] = nums[old_p]; new_p++; } } return new_p; } };