LeetCode 704.二分查找
注意点
- 区间是否包含右边下标的元素
- 中间元素的选取
代码
左闭右闭解法
class Solution {
public:
int search(vector<int>& nums, int target) {
if(nums.size() == 0) {
return -1;
}
// 左闭右闭区间
int left = 0;
int right = nums.size() - 1;
int middle = 0;
while(left <= right) {
// middle = (left + right) / 2;
middle = left + (right - left) / 2;
if(target < nums[middle]) {
right = middle - 1;
} else if (target > nums[middle]) {
left = middle + 1;
} else {
return middle;
}
}
return -1;
}
};
左闭右开解法
class Solution {
public:
int search(vector<int>& nums, int target) {
if(nums.size() == 0) {
return -1;
}
// 左闭右开区间
int left = 0;
int right = nums.size();
int middle = 0;
while(left < right) {
middle = left + (right - left) / 2;
if(target < nums[middle]) {
right = middle;
} else if(target > nums[middle]) {
left = middle + 1;
} else {
return middle;
}
}
return -1;
}
};
LeetCode 27.移除元素
解法1:双重循环暴力解
class Solution {
public:
int removeElement(vector<int>& nums, int val) {
// 暴力解 - 每发现一个, 就把这个删除,并且把后面的元素全部前移
int size = nums.size(); // 记录nums的原始长度
for(int i = 0; i < size; i ++) {
if(val != nums[i]) {
// 如果当前元素并不是我们需要找的数,则终止此次循环,继续向下比较
continue;
}
// 到这里,说明当前下标元素正是我们要找的val,则进行元素的删除以及前移
// int temp = nusm[i];
for(int j = i; j < size - 1; j ++) {
nums[j] = nums[j + 1];
}
// 因为每次删除后,需要重新考虑i的值
i --;
size --;
}
return size;
}
};
解法2:双指针之单向指针
class Solution {
public:
int removeElement(vector<int>& nums, int val) {
// 双指针法: 采用fast指针和slow指针,初始都指向nums的第一个元素
// 每次都判断fast所执行的元素值是否和val相等,若相等,则将fast后移,判断fast当前所指向的值,若与val相等,则继续后移,若不等,则将slow指针所指向的元素值修改为fast所指向的值,然后同时后移两个指针。
// 若不等,则同时后移两个指针
int fast = 0;
int slow = 0;
while(fast != nums.size()) {
if(nums[fast] != val) {
nums[slow ++] = nums[fast ++];
} else {
fast ++;
}
}
return slow;
}
};
解法3:双指针之相向双指针
class Solution {
public:
int removeElement(vector<int>& nums, int val) {
// 双指针优化:相向指针,改变原先数组元素的位置,但是可以使移动次数减少
// 从左边开始找第一个等于val的元素下标,从右边开始找第一个不等于val的元素下标,然后让nums[left] = nums[right],然后使left往后移动,right往前移动,直到left大于right停止,此时left所指向的元素下标即是我们所要求的数组长度
int left = 0;
int right = nums.size() - 1;
while(left <= right) {
// 为什么left <= right 放在后面会报错
while(left <= right && nums[left] != val) { // 防止left大于right,产生错误
// 从左边开始
left ++;
}
while(left <= right && nums[right] == val) {
// 从右边开始
right --;
}
if(left < right) {
nums[left ++] = nums[right --];
}
}
return left;
}
};
由于某些原因时间较紧,未作详细注解,后续会补充