一个防止运算中数据溢出的操作
重要思想: 先减后加,先除再乘。
搜索旋转数组
自己的思路 :先找到那个“拐点”,然后分成两个序列,分别找。
class Solution {
public:
int search(vector<int>& nums, int target) {
"Part 0"
"无法合并的痛——数组只有一个元素,特殊情况,特殊处理"
if(nums.size()==1){
if(nums[0]==target)
return 0;
else
return -1;
}
"Part 1 找位置"
"先找到中间的元素,即最大元素"
int left=0,right=nums.size()-1,mid=left+(right-left)/2,flag=0;
"flag用来判断有没有旋转,如果1234旋转4次后还是1234,那么flag的值就是0"
while(left<=right){
"分两种情况讨论"
"情况1:mid的值大于mid后面的值,比如 3 2 4,mid的值是3,mid+1的值是2,那么3就是我要找的点"
if(mid<nums.size()-1&&nums[mid]>nums[mid+1]){
flag=1;
break;
}
"情况2:mid前面的值大于mid的值,比如3 2 4,mid的值是2,mid-1的值是3,那么3就是我要找的点"
else if(mid&&nums[mid]<nums[mid-1]){
flag=1;
mid=mid-1;"这里和情况1不一样,要多加一步"
break;
}
else if(nums[mid]>nums[right])
left=mid+1;
else
right=mid-1;
mid=left+(right-left)/2;
}
"Part 2 搜索"
"如果旋转后没有变化,那么正常搜索就行;"
if(flag==0){
left=0,right=nums.size()-1,mid=left+(right-left)/2;
while(left<=right){
if(nums[mid]==target)
return mid;
else if(nums[mid]>target)
right=mid-1;
else
left=mid+1;
mid=left+(right-left)/2;
}
return -1;
}
"如果旋转后有变化,那么我就以mid为界,分出两个有序数组"
else{
"target的值比mid大,又因为mid是最大的,所以不存在元素==target"
if(target>nums[mid])
return -1;
"如果target==nums[mid],好耶!找到了,返回mid;"
else if(target==nums[mid])
return mid;
"左右搜索"
else{
"左搜索"
if(target>=nums[0]){
left=0,right=mid-1;
mid=left+(right-left)/2;
while(left<=right){
if(nums[mid]==target)
return mid;
else if(target>nums[mid])
left=mid+1;
else
right=mid-1;
mid=left+(right-left)/2;
}
return -1;
}
"右搜索"
else{
left=mid+1,right=nums.size()-1;
mid=left+(right-left)/2;
while(left<=right){
if(nums[mid]==target)
return mid;
else if(target>nums[mid])
left=mid+1;
else
right=mid-1;
mid=left+(right-left)/2;
}
return -1;
}
}
}
}
};
自己写的代码当然很冗长,有些地方的设计思路很不好。
来看看大神的吧。
思路:我一边分序列,一边找节点(相当于把我的两步合并为为一步);
class Solution {
public:
int search(vector<int>& nums, int target) {
int left=0,right=nums.size()-1;
while(left<=right)
{
int mid=(left+right)/2;
if(nums[mid]==target)
return mid;
else if(nums[left]<=nums[mid])
{
if(target<nums[mid]&&target>=nums[left])
right=mid-1;
else
left=mid+1;
}
else
{
if(target<=nums[right]&&target>nums[mid])
left=mid+1;
else
right=mid-1;
}
}
return -1;
}
};