代码随想录算法训练营第一天| 704. 二分查找、27. 移除元素、26. 删除排序数组中的重复项
题目链接:704二分查找
思路
考虑数组是[left , right],还是[left, right),坚持循环不变量原则。
左闭右闭区间
# 区间为左闭右闭区间
class Solution {
public:
int search(vector<int>& nums, int target) {
int left = 0;
int right = nums.size()-1;
while(left <= right){
int middle = (left +right)/2 ;
if(nums[middle]<target){
left = middle + 1;
}
else if(nums[middle]>target){
right = middle - 1;
}
else{
return middle;
}
}
return -1;
}
};
左闭右开区间
# 区间为左闭右开区间
class Solution {
public:
int search(vector<int>& nums, int target) {
int left = 0;
int right = nums.size();
while(left < right){
int middle = (left +right)/2 ;
if(nums[middle]<target){
left = middle + 1;
}
else if(nums[middle]>target){
right = middle ;
}
else{
return middle;
}
}
return -1;
}
};
题目链接:27移除元素
思路
不能单独删除数组中的某个元素,只能覆盖。
暴力解法
时间复杂度O(n^2),空间复杂度:O(1),通过两层for循环,一个for循环遍历数组元素 ,第二个for循环更新数组。
#暴力解法
class Solution {
public:
int removeElement(vector<int>& nums, int val) {
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也向前移动一位
size--; // 此时数组的大小-1
}
}
return size;
}
};
双指针解法
时间复杂度O(n),空间复杂度:O(1),通过两层for循环,一个for循环遍历数组元素 ,第二个for循环更新数组。
#双指针解法
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];
}
}
return slow;
}
};
题目链接:26删除排序数组中的重复项
思路
由上面的指针指向第二个元素,下面的指针指向第一个元算,判断两数是否相等,若不相等,下指针向后移一位,nums[++bot] =nums[top],最终值返回bot+1。
/*
会造成越界
for(int top = 0;top<nums.size();top++){
if(nums[top]!=nums[top+1])
*/
class Solution {
public:
int removeDuplicates(vector<int>& nums) {
int bot = 0;
for(int top = 1;top<nums.size();top++){
if(nums[top]!=nums[bot]){
nums[++bot] =nums[top];
}
}
return bot+1;
}
};