704.二分查找
对于二分查找法
始终要抓住两个主要矛盾, 1、是 left < right 还是 left <= right ;2、是 right =mid 还是 right = mid -1。对于该问题,就要看二分查找所给出的区间是左闭右闭还是左闭右开。
对于左闭右闭,就使用 left <= right,因为 left==right 在 [left,right] 是有意义的;而且使用 right = mid -1,因为对于左左闭右闭情况,如果 right=mid,而nums[mid]一定是不在target的寻找范围之内的,所以 right=mid 不行,要用 right = mid -1。
同理,对于左闭右开,就要使用 left < right 和 right =mid了。
题目解答(添加了自己的一些代码以便能在编译器上运行)
#include<iostream>
#include<vector>
using namespace std;
//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) / 2;//相当于(left + right0)/2,但是可以防止溢出!!
if (target > nums[mid]) {
left = mid + 1;
}
else if (target < nums[mid]) {
right = mid - 1;
}
else return mid;
}
return -1;
}
};
int main() {
vector<int> nums;
int a, target;
while (cin >> a && a != -1) nums.push_back(a);
cin >> target;
Solution s1;
int result = s1.search(nums, target);
cout << result;
return 0;
}
注意事项
int mid = left + (right - left) / 2; //相当于(left + right0)/2,但是可以防止溢出!!
27.移除元素
(1)题目的两个解答
class Solution {
public:
//暴力解法
int removeElement1(int val, vector<int>& nums) {
int size = nums.size();
for (int i = 0; i < size; i++) {
if (nums[i] == val) {
for (int j = i + 1; j < size; j ++) {
nums[j - 1] = nums[j];
}
i--;//因为i后面的数都向前移动了一位,所以i也向前移动一位,如【2 2】2
size--;
}
}
return size;
}
//双指针解法
int removeElement2(int val, vector<int>& nums) {
int size = nums.size();
int j = 0;
for (int i = 0; i < size; i++) {
if (nums[i] != val) nums[j++] = nums[i];
}
return j;
}
};
(2)暴力解法注意事项
每次将部分数组前移后一定要进行 i--,因为i后面的数都向前移动了一位,所以i也向前移动一位,譬如[2, 2],移除的元素为2,如果不进行i--,那么返回的值就为1,所以要进行i--。
(3)双指针解法注意事项
定义的快指针来判断数组值是否为val,而慢指针用来记录非val的个数。