目录
数组相关知识
- 数组是存放在连续内存空间上的相同类型数据的集合
- 在删除或者增添元素的时候,需要依次移动其他元素的地址
- C++ vector
//定义变量类型为int的容器nums vector<int>& nums //获得容器内元素个数 nums.size()
704.二分查找
题目 704.二分查找
文档 代码随想录-二分法
视频 二分法 | 二分查找法 | 二分搜索法 | LeetCode:704. 二分查找_哔哩哔哩_bilibili
状态 可以自己做出来,但思路比较模糊;学完后有清楚的逻辑
-
初始思路:在一个升序排列且无重复值的数组中查找目标值,适合使用二分查找。定义左侧边界和右侧边界。多次迭代,每次迭代时取当前的中间元素,如果等于目标值则返回中间元素的下标,大于目标值则重设右边界,小于目标值则重设左边界,直至找到目标元素。
-
重点:分清使用的是左闭右开还是左闭右闭。
左闭右开 左闭右闭 区间取值 [low,high) [low,high] 初始值 high = nums.size() high = nums.size()-1 迭代停止条件 low<=high low<high 更新右边界 high = mid high = mid-1 当使用左闭右开时,low=high无意义,因为[low,high)没有取值。即当迭代到low=high时还未返回,说明无法取到目标值
-
代码
- 左闭右闭写法
class Solution { public: int search(vector<int>& nums, int target) { int low = 0, high = nums.size()-1; while(low<=high) { int mid = low + (high-low)/2; if(nums[mid]==target) return mid; else if(nums[mid]<target) low = mid+1; else high = mid-1; } return -1; } };
- 左闭右开写法
class Solution { public: int search(vector<int>& nums, int target) { int low = 0, high = nums.size(); while(low<high) { int mid = low + (high-low)/2; if(nums[mid]==target) return mid; else if(nums[mid]<target) low = mid+1; else high = mid; } return -1; } };
写成 int mid = low + (high-low)/2; 可以防止(high+low>2147483647)超限
34. 在排序数组中查找元素的第一个和最后一个位置
1.思路:两次二分查找,分别寻找开始位置和结束位置,注意当nums[mid]==target时与简单的查找的区别。
2.代码
class Solution {
public:
vector<int> searchRange(vector<int>& nums, int target) {
int low1=0,low2=0, high1=nums.size()-1,high2=nums.size()-1;
int left=-1,right=-1;
while(low1<=high1){
int mid = (low1+high1)/2;
if(nums[mid]==target&&(mid==0?1:(nums[mid-1]<nums[mid]))) {
left=mid;
break;
}
else if(nums[mid]>target) high1 = mid-1;
else if(nums[mid]<target) low1 = mid+1;
else high1 = mid-1;
}
while(low2<=high2){
int mid = (high2+low2)/2;
if(nums[mid]==target&&(mid==nums.size()-1?1:(nums[mid+1]>nums[mid]))){
right = mid;
break;
}
else if(nums[mid]>target) high2 = mid-1;
else if(nums[mid]<target) low2 = mid+1;
else low2 = mid+1;
}
return {left,right};
}
};
35.搜索插入位置
1.思路:使用左闭右闭的二分查找,存在时返回找到的下标值,不存在时返回迭代结束后的low值,即待插入位置。
2.代码
class Solution {
public:
int searchInsert(vector<int>& nums, int target) {
int low = 0, high = nums.size()-1;
while(low<=high)
{
int mid = low + (high-low)/2;
if(nums[mid]==target) return mid;
else if (nums[mid]<target) low = mid+1;
else high = mid-1;
}
return low;
}
};
27.移除元素
题目 27.移除元素
文档 代码随想录
视频 数组中移除元素并不容易! | LeetCode:27. 移除元素_哔哩哔哩_bilibili
状态 自己能写暴力写法;掌握了双指针法
1.初始思路:暴力求解,可以使用双循环,外层循环找等于val的元素下标,内层循环从找到的下标开始调整后边的元素地址,时间复杂度为O(n2)
2.重点:使用双指针法求解。
- 慢指针slowIndex:指向数组下次更新位置
- 快指针fastIndex:寻找新数组应有的元素(即不等于val的元素)
一次循环。依次用快指针找到需要保留的元素,并覆盖至慢指针指向的位置,O(n)
3.代码
暴力求解
class Solution {
public:
int removeElement(vector<int>& nums, int val) {
int len = nums.size();
int index = 0;
while(index<len)
{
if(nums[index]!=val) index++;
else{
len--;
for(int j = index;j<nums.size()-1;j++)
nums[j]=nums[j+1];
}
}
return len;
}
};
双指针法
class Solution {
public:
int removeElement(vector<int>& nums, int val) {
int slowIndex = 0;
for(int fastIndex = 0; fastIndex < nums.size(); fastIndex++)
{
if(nums[fastIndex]!=val){
nums[slowIndex] = nums[fastIndex];
slowIndex++;
}
}
return slowIndex;
}
};
今日收获
逐步掌握知识的过程!一个好的开始...