学习目标:
- 704. 二分查找
- 27. 移除元素
学习内容:
704. 二分查找
class Solution {
public:
int search(vector<int>& nums, int target) {
// 方法一,左闭右闭
int left = 0;
int right = nums.size() - 1;
while(left <= right){
int mid = left + ((right-left) >> 1);
if(nums[mid]<target){
left = mid + 1;
}
else if (nums[mid]>target){
right = mid - 1;
}
else
{
return mid;
}
}
// 未找到目标值
return -1;
}
};
错误以及注意事项
- middle = left + ((right - left) / 2);// 防止溢出 等同于(left + right)/2
- 由于运算符优先级,>>(右移位)的优先级比加法低,因此实际上int mid = left + (right - left) >> 1等同于mid = (left + (right - left)) >> 1。所以要在右移位的时候加上括号。
- 为什么使用>>(右移位)?右移运算符是将二进制表示向右移动指定的位数,这相当于将整数除以2的n次方,这里是除以1。这是一种比直接除法运算更高效的方式。
class Solution {
public:
int search(vector<int>& nums, int target) {
// 方法2,左闭右开
int left = 0;
int right = nums.size();
while(left < right){
int mid = left + ((right - left) >> 1);
if(nums[mid] < target){
left = mid+1;
}
else if(nums[mid] > target){
right = mid;
}
else{
return mid;
}
}
return -1;
}
};
27. 移除元素
class Solution {
public:
int removeElement(vector<int>& nums, int val) {
//双指针法(快慢指针法)
int slow = 0;
for(int fast = 0 ; fast < nums.size(); fast++ )
{
if(nums[fast] != val)
{
nums[slow] = nums[fast];
slow++;
}
}
return slow;
}
};
错误以及注意事项
- 前缀递增运算符 ++(++leftIndex),先加后用
- 后缀递增运算符 ++(leftIndex++),先用后加
class Solution {
public:
int removeElement(vector<int>& nums, int val) {
//相向双指针方法
int leftIndex = 0;
int rightIndex = nums.size()-1;
while(leftIndex <= rightIndex){
// search not equal to val in right side, and search equal to val in left side.
while(leftIndex <= rightIndex && nums[leftIndex]!=val)
{
++leftIndex;
}
while(leftIndex <= rightIndex && nums[rightIndex]==val)
{
--rightIndex;
}
if(leftIndex < rightIndex)
{
nums[leftIndex] = nums[rightIndex];
++leftIndex;
--rightIndex;
}
}
return leftIndex;
}
};
错误以及注意事项
- 小循环中 while(leftIndex <= rightIndex && nums[leftIndex]!=val) 为什么要加上大循环中已经有的条件leftIndex <= rightIndex?因为这两个自变量在大循环里也会发生变化,所以随时要检查是否满足条件。
学习时间:
2023.11.29 20:00-22:00