704.二分查找
文章链接:704.二分查找
视频链接:手把手带你撕出正确的二分法 | 二分查找法 | 二分搜索法 | LeetCode:704. 二分查找
题目描述
704.二分查找
题解
- 数组为有序数组,且不包含重复元素,故采用二分查找法。
二分查找法即定义搜索区间。令target与数组中间值mid进行比较,若target等于mid,则target下标即为mid;若target小于mid,则target处于数组左半区间,置right为左半区间右边界值;若target大于mid,则target处于数组右半区间,置left为右半区间左边界值,以此类推,直至left > right,即区间不合法,返回-1。 - 定义区间。
① 区间为左闭右闭区间[left, right],即right处于搜索区间内。
class Solution {
public:
int search(vector<int>& nums, int target) {
// 定义区间为:[left, right](左闭右闭区间)
int left = 0, right = nums.size() - 1;
while(left <= right) {
int mid = (right - left) / 2 + left;
int num = nums[mid];
if(num == target) {
return mid;
} else if(num < target) {
left = mid + 1;
} else {
right = mid - 1;
}
}
return -1;
}
};
时间复杂度:O(log n)
空间复杂度:O(1)
② 区间为左闭右开区间[left, right),即right不处于搜索区间内。
class Solution {
public:
int search(vector<int>& nums, int target) {
// 定义区间为:[left, right)(左闭右开区间)。
int left = 0, right = nums.size();
while(left < right) {
int mid = (right - left)/2 + left;
int num = nums[mid];
if(num == target) {
return mid;
} else if(num < target) {
left = mid + 1;
} else if(num > target) {
right = mid;
}
}
return -1;
}
};
时间复杂度:O(log n)
空间复杂度:O(1)
27.移除元素
文章链接:27.移除元素
视频链接:数组中移除元素并不容易! | LeetCode:27. 移除元素
题目描述
27.移除元素
题解
解法一:暴力法
数组元素连续存放于内存地址,因此数组无法删除元素,只能将该元素的后续元素逐一向前移一位对其进行覆盖操作。
class Solution {
public:
int removeElement(vector<int>& nums, int val) {
int len = nums.size();
for(int i = 0; i < len; i++) {
if(nums[i] == val) {
for(int j = i + 1; j < len; j++) {
nums[j - 1] = nums[j];
}
i--;
len--;
}
}
return len;
}
};
时间复杂度:O(n^2)
空间复杂度:O(1)
另:
- LeeCode解答错误代码及其错误原因。
class Solution {
public:
int removeElement(vector<int>& nums, int val) {
int len = nums.size();
for(int i = 0; i < len; i++) {
if(nums[i] == val) {
for(int j = i; j < len; j++) {
nums[j] = nums[j + 1];
// 当j = len - 1时,nums[j + 1]越界。执行失败。
}
// 遗漏“i--;”,未检查所有元素(即原与val相等元素的下一个元素)是否等于val。
len--;
}
}
return len;
}
};
- vector常用库函数
库函数 | 用法及注意事项 |
---|---|
v.size() | 返回v数组元素个数。使用erase()后v.size()自动减一。 |
v.erase(iterator pos) | 移除数组元素。实际执行覆盖操作,故时间复杂度为O(n)。 |
解法二:双指针法
快指针,用于获取新数组元素(即旧数组内不等于val的元素)。
慢指针,用于获取新数组元素目标位置。
快指针遍历旧数组各元素,并将新数组元素覆盖至目标位置。
class Solution {
public:
int removeElement(vector<int>& nums, int val) {
int fast = 0, slow = 0;
int len = nums.size();
for(; fast < len; fast++) {
if(nums[fast] != val) {
nums[slow] = nums[fast];
slow++;
}
}
return slow;
}
};
时间复杂度:O(n)
空间复杂度:O(1)
后记
好像没想象中那么难!希望能跟上呢。:)