day01二分查找_移除元素
//二分查找704
// 时间复杂度 O(log n)
// 空间复杂度 O(1)
class Solution {
public:
int search(vector<int>& nums, int target) {
int left = 0;
int right = nums.size() - 1; // 定义target在左闭右闭的区间里,[left, right]
while (left <= right) { // 当left==right,区间[left, right]依然有效,所以用 <=
int middle = left + ((right - left) / 2); // 防止溢出 等同于(left + right)/2
if (target < nums[middle]) {
right = middle - 1; // target 在左区间,所以[left, middle - 1]
}
else if (target > nums[middle]) {
left = middle + 1; // target 在右区间,所以[middle + 1, right]
}
else { // nums[middle] == target
return middle; // 数组中找到目标值,直接返回下标
}
}
// 未找到目标值
return -1;
}
};
//移除元素27
//暴力解法
// 时间复杂度 O(n*n)
// 空间复杂度 O(1)
class Solution1 {
public:
int removeElement(vector<int>& nums, int val) {
int size = nums.size() - 1;
for (int i = 0; i < size; i++) { // 遍历整个数组
if (nums[i] == val) { // 发现有值为val,将后面的值向前覆盖
for (int j = i + 1; j < size; j++) {
nums[j - 1] = nums[j];
}
i--; // 后面的值都向前移了一个 相当于i--
size--;
}
}
return size;
}
};
//双指针法
// 时间复杂度 O(n)
// 空间复杂度 O(1)
class Solution2 {
public:
int removeElement(vector<int>& nums, int val) {
int slowIndex = 0; // 设置快慢指针,先判断快指针
for (int fastIndex = 0; fastIndex < nums.size(); fastIndex++) { // 如果快指针不为val,将快指针值 赋给 慢指针
if (nums[fastIndex] != val) { // 快指针为val, 无操作,快指针继续向前
nums[slowIndex++] = nums[fastIndex];
}
}
return slowIndex;
}
};
// 相向双指针
// 时间复杂度 O(n)
// 空间复杂度 O(1)
class Solution {
public:
int removeElement(vector<int>& nums, int val) {
int leftIndex = 0;
int rightIndex = nums.size() - 1;
while (leftIndex <= rightIndex) {
// 找左边的val
while(leftIndex <= rightIndex && nums[leftIndex] != val) {
++leftIndex;
}
// 找右边的 非val
while(leftIndex <= rightIndex && nums[rightIndex] == val) {
--rightIndex;
}
//左右指针找到值之后 交换
if(leftIndex < rightIndex) {
nums[leftIndex++] = nums[rightIndex--];
}
}
return leftIndex;
}
};