力扣33【搜索旋转排序数组】

在这里插入图片描述

  • 解题思路
    原始数组是个升序数组,这道题其实就是在一个数组上查找某个元素是否存在,如果存在返回索引值;但是难点在于已知的数组B是在数组A的基础上变换而来,题目又要求我们返回target在数组A
    中的位置;

通过得到数组A的某位置在数组B中的位置,就可以在数组A上完成二分查找;因为二分查找需要根据区间左右值于target的大小关系来更新区间;所以找到数组A与数组B的元素对应关系,就可以知道数组A中某位置的元素大小;

  • code
    三部分
  1. 寻找数组A的首元素在数组B中的位置,为计算两个位置的映射做准备

    trick
    使用二分法来查找起始元素,当mid大于数组B的末尾元素是,选择左半区间

  2. 根据元素m在数组A中的位置,得到在数组B的位置;转换关系如下:
    在这里插入图片描述

3)二分查找

#include<iostream>
#include<vector>
#include<string>
#include<algorithm>
#include<map>
using namespace std;


class Solution {
public:
    int search(vector<int>& nums, int target) {
        int Len = nums.size();
        int start = find_start(nums, 0, Len - 1);

        //根据原始数组索引二分法查找target
        int L = 0;
        int R = nums.size() - 1;

        while (L <= R)
        {
            int old_mid = (L + R) >> 1;//原始数组中的位置
            int mid = change_idx(Len, start, (L + R) >> 1);//现在数组中的位置
            if (nums[mid] == target)
                return mid;
            else if (nums[mid] > target)
                R = old_mid - 1;//更新在原来数组中位置
            else
                L = old_mid + 1;
        }
        return -1;
    }

    //start表示原始数组中的起始元素在转换后数组的那个位置
    //比如[5,1,3]原始数组为[1,3,5],那么原始数组的首元素在现在数组的位置1
    //old_mid表示数组中的索引,在原始数组中使用二分法查找目标值

    //原始数组中元素位置与输入数组中的位置变换
    //输入数组[2,3,5,1],原始数组[1,2,3,5],那么原始数组的索引2在输入数组中为索引1
    int change_idx(int Len, int start, int old_mid)
    {
        if (old_mid < Len - start)
        {
            return old_mid + start;
        }
        else
        {
            return old_mid - (Len - start);
        }
    }
    //返回变换数组中代表原始数组首元素的索引
    int find_start(vector<int>& nums, int L, int R)
    {
        while (L <= R)
        {
            int mid = (L + R) >> 1;

            if (mid >= 1 && mid + 1 < nums.size() && nums[mid] < nums[mid + 1] && nums[mid] < nums[mid - 1] || nums[mid] == nums[nums.size() - 1])
            {
                return mid;
            }
            //重点
            //与最后一个元素比较
            else
            {
                if (nums[mid] > nums[nums.size() - 1])
                    L = mid + 1;
                else
                    R = mid - 1;
            }
        }
        return 0;
    }
};
int main()
{
    vector<int> Arr = {3,1 };
    int target = 0;
    Solution S;
    cout<<S.search(Arr, target)<<endl;
    
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

星光技术人

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值