//第一种;
class Solution {
public:
int search(vector<int>& nums, int target) {
int left=0;
int right=nums.size()-1; //定义target在左闭右闭的区间里,[left, right]
while(left<=right){ //// 当left==right,区间[left, right]依然有效,所以用 <=
int middle=left+(right-left)/2; // 防止溢出
if(nums[middle]==target){
return middle;
}else if(nums[middle]<target){
left=middle+1;
}else if(nums[middle]>target){
right=middle-1;
}
}
return -1;
}
};
class Solution {
public:
int search(vector<int>& nums, int target) {
int left=0;
int right=nums.size(); //[left,right)
while(left<right){
int middle=left+(right-left)/2;
if(nums[middle]==target){
return middle;
}else if(nums[middle]<target){
left=middle+1;
}else if(nums[middle]>target){
right=middle;
}
}
return -1;
}
};
//第一种
class Solution {
public:
int searchInsert(vector<int>& nums, int target) {
int left=0,right=nums.size()-1;
while(left<=right){ //[left,right]
int middle=left+(right-left)/2;
if(target==nums[middle]){
return middle;
}else if(nums[middle]<target){ //左区间 [left,middle-1]
left=middle+1;
}else if(nums[middle]>target){ //右区间 [middle+1,right]
right=middle-1;
}
}
return right+1;
}
};
//第2种
class Solution {
public:
int searchInsert(vector<int>& nums, int target) {
int left=0,right=nums.size();
while(left<right){ //[left,right)
int middle=left+(right-left)/2;
if(target==nums[middle]){
return middle;
}else if(nums[middle]<target){ //左区间 [left,middle-1)
left=middle+1;
}else if(nums[middle]>target){ //右区间 [middle+1,right)
right=middle;
}
}
return right;
}
};
class Solution {
public:
vector<int> searchRange(vector<int>& nums, int target) {
int leftBorder=getLeftBorder(nums,target);
int rightBorder=getRightBorder(nums,target);
if(leftBorder==-2||rightBorder==-2){
return {-1,-1};
}
if(rightBorder-leftBorder>1){
return {leftBorder+1,rightBorder-1}; //注意下标
}
return {-1,-1};
}
//分别寻找左右边界
//寻找左边界
int getLeftBorder(vector<int>& nums, int target){
int left=0,right=nums.size()-1;
int leftBorder=-2;
while(left<=right){
int middle=left+(right-left)/2;
if(nums[middle]>=target){ //锁定左边边界,不断向左收缩
right=middle-1;
leftBorder=right;
}else{
left=middle+1;
}
}
return leftBorder;
}
//寻找右边界
int getRightBorder(vector<int>& nums, int target){
int left=0,right=nums.size()-1;
int rightBorder=-2;
while(left<=right){
int middle=left+(right-left)/2;
if(nums[middle]>target){
right=middle-1;
}else{ //锁定右边边界,不断向右收缩, nums[middle] == target的时候更新left
left=middle+1;
rightBorder=left;
}
}
return rightBorder;
}
};
class Solution {
public:
int mySqrt(int x) {
int left=1,right=(x>>1)+1;
while(left<=right){
int middle=left+((right-left)>>1);
if(middle<x/middle){
left=middle+1;
}else if(middle>x/middle){
right=middle-1;
}else{
return middle;
}
}
return right;
}
};
class Solution {
public:
bool isPerfectSquare(int num) {
int left=1,right=(num>>1)+1;
while(left<=right){
long long middle=left+((right-left)>>1);
long long sum=middle*middle; //有可能溢出,要用长整型来存储
if(sum<num){
left=middle+1;
}else if(sum>num){
right=middle-1;
}else{
return true;
}
}
return false;
}
};
class Solution {
public:
//计算速度为x时能吃完的时间
int calTime(vector<int>& piles, int x){
int hours=0;
for(int i=0;i<piles.size();i++){
hours += piles[i] / x;
if(piles[i]%x>0){
hours++; //有剩余的,hour+1
}
}
return hours;
}
int findMax(vector<int>& piles){
int m_max=piles[0];
for(int i=1;i<piles.size();i++){
if(m_max<piles[i]){
m_max=piles[i];
}
}
return m_max;
}
//找左界
int minEatingSpeed(vector<int>& piles, int h) {
int left=1,right=findMax(piles)+1;
while(left<right){
int middle=left+(right-left)/2;
if(calTime(piles,middle)<=h){ //能吃完,速度小一些
right=middle;
}else if(calTime(piles,middle)>h){ //不能吃完,速度大一些
left=middle+1;
}
}
return left;
}
};
class Solution {
public:
//计算运载能力为x时,需要多少天运完
int getDays(vector<int>& weights, int x){
int days=0;
for(int i=0;i<weights.size();){
int temp=x;
//不一定能装满,装不满时,要往后边继续装
while(i<weights.size()){
if(weights[i]>temp){
break;
}else{
temp-=weights[i];
}
i++;
}
days++;
}
return days;
}
//找左边界
int shipWithinDays(vector<int>& weights, int days) {
//left为最小载重,货物的最大值,right为最大载重,即全部货物一次运完
int left=0,right=1;
for(int i=0;i<weights.size();i++){
left=max(left,weights[i]);
right+=weights[i];
}
while(left<right){
int middle=left+(right-left)/2;
if(getDays(weights,middle)<=days){
right=middle;
}else{
left=middle+1;
}
}
return left;
}
};