题目

整数数组nums按升序排列,数组中的值互不相同 。

在传递给函数之前,nums在预先未知的某个下标 k(0 <= k < nums.length)上进行了旋转,使数组变为 [nums[k], nums[k+1], ..., nums[n-1], nums[0], nums[1], ..., nums[k-1]](下标 从 0 开始 计数)。例如,[0,1,2,4,5,6,7]在下标3处经旋转后可能变为[4,5,6,7,0,1,2]

给你旋转后的数组nums和一个整数target,如果nums中存在这个目标值target,则返回它的下标,否则返回-1

示例 1:

  1. 输入:nums = [4,5,6,7,0,1,2], target = 0
  2. 输出:4

示例 2:

  1. 输入:nums = [4,5,6,7,0,1,2], target = 3
  2. 输出:-1

示例 3:

  1. 输入:nums = [1], target = 0
  2. 输出:-1

提示:

  • 1 <= nums.length <= 5000
  • -10^4 <= nums[i] <= 10^4
  • nums 中的每个值都 独一无二
  • 题目数据保证 nums 在预先未知的某个下标上进行了旋转
  • -10^4 <= target <= 10^4

    解题方法

    二分法

    数组分段有序,注意判断二分后左右有序性以及目标值在有序段还是无序段,进而确定边界移动条件。
    时间复杂度O(logn)
    c++代码:

    1. class Solution {
    2. public:
    3. int search(vector<int>& nums, int target) {
    4. int n = nums.size();
    5. if (n==1) {
    6. return target==nums[0] ? 0:-1;
    7. }
    8. int left = 0;
    9. int right = n-1;
    10. while (left<=right) {
    11. int mid = (left+right)/2;
    12. if (target==nums[mid]) return mid;
    13. if (nums[0]<=nums[mid]) {
    14. if (target>=nums[0] && target<nums[mid]) right = mid-1;
    15. else left = mid+1;
    16. }
    17. else {
    18. if (target>nums[mid] && target<=nums[n-1]) left = mid+1;
    19. else right = mid-1;
    20. }
    21. }
    22. return -1;
    23. }
    24. };