1. arr[i] > arr[i+1] ---> right = mid , 此时mid处可能就是峰值所以不能跳过mid。
2. arr[i] < arr[i+1] ---> left = mid +1 ,此时mid+1处才可能是峰值,因此可以跳过mid。
参考代码:
cpp复制代码
class Solution
{
public:
int findPeakElement(vector<int>& nums)
{
int left = 0;
int right = nums.size()-1;
while(left < right)
{
int mid = left + (right - left ) / 2;
if( nums[mid] < nums[mid+1])
{
left = mid + 1 ;
}
else
right = mid;
}
return left;
}
};
class Solution {
public:
int findMin(vector<int>& nums)
{
int left = 0;
int right = nums.size() - 1;
while(left < right)
{
int mid = left + (right - left) / 2;
if(nums[mid] < nums[right])right = mid;
else left = mid+1;
}
return nums[left];
}
};
思考:我们划分两端区间是以D为参考点,那么我们是否能以A为参考点呢?
1.A~B段是大于等于nums[0](A点)的,而C~D段是严格小于nums[0]的。
2.此时二分流程:
A - B : nums[i]>=nums[0] --> left= mid +1;
C - D : nums[i] < nums[0] --> right = mid;
3.当旋转数组旋转到原来升序时:
此时A点就是最小值,区间不断向右,此时就会丢掉最小值,因此对于这种边界情况我们需要特殊处理。
cpp复制代码
class Solution {
public:
int findMin(vector<int>& nums)
{
int left = 0;
int right = nums.size() - 1;
if(nums[0] < nums[right])
return nums[0];
int x = nums[0]; //以A为参照
while(left < right)
{
int mid = left + (right - left) / 2;
if(nums[mid] >= x )left = mid + 1;
else right = mid;
}
return nums[left];
}
};
class Solution {
public:
int takeAttendance(vector<int>& records)
{
bool flag = false;
int i = 0;
for( i = 0 ; i < records.size();i++)
{
if(i != records[i])
{
flag = true;
break;
}
}
return i;
}
};
class Solution {
public:
int takeAttendance(vector<int>& records)
{
int n = records.size();
int sum = 0;
for(int i = 0 ;i <= n ;i++)
{
sum ^= i;
}
for(int i = 0; i < records.size();i++)
{
sum ^= records[i];
}
return sum;
}
};
class Solution {
public:
int takeAttendance(vector<int>& records)
{
int n = records.size() + 1;
int sum = 0 + (n*(n-1)) / 2;
cout << sum <<endl;
for(int i = 0; i < records.size();i++)
{
sum -= records[i];
}
return sum;
}
};
class Solution {
public:
int takeAttendance(vector<int>& records)
{
int left = 0;
int right = records.size() - 1;
while(left < right)
{
int mid = left + (right - left ) / 2;
if(records[mid] == mid)
left = mid + 1;
else
right = mid;
}
if(records[left] != left) return left;
return left + 1;
}
};