Leetcode704.二分查找
题目链接:
思路:
- 坚持用左闭右闭的思路
- 和高中学的二分估计类似 类比起来很好理解
class Solution {
public:
int search(vector<int>& nums, int target) {
int i = 0, j = nums.size() - 1;
while(i<=j)
{
int mid =(i+j)/2;
if(nums[mid]<target)
{
i=mid+1;
}
else if(nums[mid]>target){
j=mid-1;
}
else{
return mid;
}
}
return -1;
}
};
注意:使用前提条件是数组有序且无重复
Leetcode35.搜索插入位置
题目链接:
思路:
- 大体思路与二分法完全一致
- 区别查找不到时无需返回-1,须返回正确位置的下标
- 举几个例子推导发现,只需在查找不到时返回左侧指针即可
class Solution {
public:
int searchInsert(vector<int>& nums, int target) {
int i=0;
int j=nums.size()-1;
while(i<=j)
{
int mid = (i+j)/2;
if(nums[mid]<target)
{
i=mid+1;
}
else if(nums[mid]>target)
{
j=mid-1;
}else{
return mid;
}
}
return i;
}
};
Leetcode34. 在排序数组中查找元素的第一个和最后一个位置
题目链接:
[34. 在排序数组中查找元素的第一个和最后一个位置 - 力扣(Leetcode)]
思路:
- 若不用二分法,思路是从头遍历一遍找到target,从尾遍历一遍找到target
- 二分法
- 目标变为找到第一个小于target的元素和第一个大于target的元素
- 第一个大于(即有边界)此时二分注意分为nums[mid]>target与nums[mid]<=target(因为寻找有边界,左边无所谓)
- 左边界同理
class Solution {
public:
vector<int> searchRange(vector<int>& nums, int target) {
int leftRange=getLeftRange(nums,target);
int rightRange=getRightRange(nums,target);
if(leftRange==-2 || rightRange==-2)//出现边界为-2说明找不到
return {-1,-1};
else if(rightRange- leftRange>1)
return {leftRange+1,rightRange-1};
else
return {-1,-1};
}
int getRightRange(vector<int>& nums, int target)
{
int i=0,j=nums.size()-1;
int rightRange=-2;
while(i<=j)
{
int mid = (i+j)/2;
if(nums[mid]>target)
{
j=mid-1;
}else{
i=mid+1;
rightRange=i;
}
}
return rightRange;
}
int getLeftRange(vector<int>& nums, int target)
{
int i=0,j=nums.size()-1;
int leftRange=-2;
while(i<=j)
{
int mid = (i+j)/2;
if(nums[mid]<target)
{
i=mid+1;
}else{
j=mid-1;
leftRange = j;
}
}
return leftRange;
}
};
Leetcode27. 移除元素
题目链接:
思路:
- 暴力法很容易思考,两层循环遍历,遇到val删除后面元素前移
- 双指针法
- 理解为快指针探路,慢指针存储最后满足的数组
- 快指针遇见val不把值传给慢指针继续前进,直至结束
法一:暴力
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--;
size--;
}
}
return size;
}
};
法二:双指针
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];
slow++;
}
}
return slow;
}
};
总结
由于之前刷过一次 思路很清晰很好理解
34与27收获更大