代码随想录地址
是学习过程中的笔记!图来自代码随想录。
文章目录
- 理论
- 题目
- 704. 二分查找
- 35. 搜索插入位置
- 34. 在排序数组中查找元素的第一个和最后一个位置
- 69. x 的平方根
- 367.有效的完全平方数
理论
数组是存放在连续内存空间上的相同类型数据的集合。
- 数组下标都是从0开始的。
- 数组内存空间的地址是连续的。
因此,我们在添加和删除元素的时候要移动数组内的其他元素。
注意:关于C++的vector,它是容器,不是数组——数组里的元素只能覆盖,不能删除。
二维数组在内存的空间地址也是连续的。
题目
704. 二分查找
704. 二分查找
这里有两种方法:左闭右闭区间 和 左闭右开区间。
个人感觉可以左闭右开,也就是右区间取不到的原因是除法是向下取整的,所以要保持右区间大一些。
左闭右闭相关理论:
class Solution {
public:
int search(vector<int>& nums, int target) {
int l=0,r=nums.size()-1;
int mid;
while(l<=r)
{
mid=(l+r)/2;
if(nums[mid]>target) r=mid-1;//不在mid处
else if(nums[mid]<target) l=mid+1;
else return mid;//等于且找到了
}
return -1;
}
};
左闭右开相关理论:
class Solution {
public:
int search(vector<int>& nums, int target) {
int l=0,r=nums.size();
int mid;
while(l<r)
{
mid=(l+r)/2;
if(nums[mid]>target) r=mid;//不在mid处,但右区间取不到,所以等于mid
else if(nums[mid]<target) l=mid+1;//不在mid处,左区间可以取到,所以等于mid+1
else return mid;//等于且找到了
}
return -1;
}
};
一些更难的二分拓展
35. 搜索插入位置
class Solution {
public:
int searchInsert(vector<int>& nums, int target) {
int l=0,r=nums.size()-1;
int mid;
while(l<=r)
{
mid=(l+r)/2;
if(nums[mid]>target) r=mid-1;
else if(nums[mid]<target) l=mid+1;
else return mid;//找到了
}
//没找到:应该的位置是l的位置:分为r主动往左走(t太小)和l主动往右走的情况(t太大)
//r往左走,nums[r]<t,是第一个小于t的位置——所以答案是l所在的位置
//l往右走,nums[l]>t,是第一个大于t的位置——所以答案是l所在的位置
return l;
}
};
34. 在排序数组中查找元素的第一个和最后一个位置
34. 在排序数组中查找元素的第一个和最后一个位置
class Solution {
public:
vector<int> searchRange(vector<int>& nums, int target) {
//找第一个等于t的位置和最后一个等于t的位置
vector<int>ans;
//数组为空&&左右边界
if(nums.size()==0||nums.back()<target||nums[0]>target) return {-1,-1};
//找最后一个小于t
int ans1,ans2;
int l=0,r=nums.size()-1,mid,temp=0;
while(l<=r)
{
mid=(l+r)/2;
if(nums[mid]>=target) r=mid-1;
else l=mid+1; //这里mid+1不怕超过 因为每次存的答案是r
ans1=r;
temp++;
}
if(!temp) return {-1,-1};
//找第一个大于t
l=0,r=nums.size()-1,temp=0;
while(l<=r)
{
mid=(l+r)/2;
if(nums[mid]<=target) l=mid+1;
else r=mid-1;
ans2=l;
temp++;
}
if(!temp) return {-1,-1};
if(ans2-ans1>1) return {ans1+1,ans2-1};
return {-1,-1};
}
};
69. x 的平方根
69. x 的平方根
class Solution {
public:
int mySqrt(int x) {
int l=0,r=46342;
int mid;
while(l<r)
{
mid=(l+r)/2;
if((long long)mid*mid>x) r=mid;
else if((long long)mid*mid<x) l=mid;
else return mid;
if(r-l==1) return l;
}
return 0;//其实绝对不会到这一步
}
};
367.有效的完全平方数
367.有效的完全平方数
方法一:二分
class Solution {
public:
bool isPerfectSquare(int num) {
int l=1,r=46342;
int mid;
while(l<=r)
{
mid=(l+r)/2;
if((long long)mid*mid>num) r=mid-1;
else if((long long)mid*mid<num) l=mid+1;
else return true;
}
return false;
}
};
方法二:数学。
(n+1)2=n2+2n+1
class Solution {
public:
bool isPerfectSquare(int num) {
if(num==1) return true;
int x=1;
num--;
while(num>0)
{
num-=2*x+1;
x++;
}
if(num==0) return true;
else return false;
}
};