1. 题目描述

https://leetcode.cn/problems/search-in-rotated-sorted-array/
整数数组 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:
输入:nums = [4,5,6,7,0,1,2], target = 0
输出:4
示例 2:
输入:nums = [4,5,6,7,0,1,2], target = 3
输出:-1
示例 3:
输入:nums = [1], target = 0
输出:-1

提示:

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


    进阶:你可以设计一个时间复杂度为 O(log n) 的解决方案吗?

    2. 题解

    2022-05-04 AC, 二分查找
    题解的写法是2边都二分, 我一开始想的就是把左边的移到右边去形成一整个有序的数组, 再二分
    这个解法因为要找到旋转点, 那么最坏的情况就是最后一个是旋转点, 时间复杂度就是O(n)
    O(logn)解法那就是直接和nums[0]比较, 来确定在左边还是在右边 ```php <?php /**

class Solution {

  1. /**
  2. * @param Integer[] $nums
  3. * @param Integer $target
  4. * @return Integer
  5. */
  6. function search($nums, $target)
  7. {
  8. if (count($nums) == 1 && $nums[0] !== $target) {
  9. return -1;
  10. }
  11. $count = count($nums);
  12. $x = 0;
  13. for ($i = 1; $i < $count; $i++) {
  14. if ($nums[$i] < $nums[$i - 1]) {
  15. $x = $i;
  16. break;
  17. }
  18. }
  19. $nums = array_merge($nums, array_slice($nums, 0, $x));

// echo implode(‘, ‘, $nums) . PHP_EOL; $a = $this->binary_search($nums, $target, $x); return $a % $count;

// 这样貌似更好一些 // int ans = binary_search(nums, 0, idx, target); // if (ans != -1) return ans; // if (idx + 1 < n) ans = find(nums, idx + 1, n - 1, target); // return ans; }

function binary_search(&$nums, $target, $l)
{
    $r = count($nums) - 1;
    while ($l <= $r) {
        $mid = intval(($l + $r) / 2);
        $v = $nums[$mid];
        if ($target == $v) {
            return $mid;
        }
        if ($v > $target) {
            $r = $mid - 1;
        }
        if ($v < $target) {
            $l = $mid + 1;
        }
    }
    return -1;
}

// Java O(logn)解法 // public int search(int[] nums, int target) { // int n = nums.length; // if (n == 0) { // return -1; // } // // if (n == 1) { // return nums[0] == target ? 0 : -1; // } // int l = 0, r = n - 1; // while (l <= r) { // int mid = (l + r) / 2; // if (nums[mid] == target) { // return mid; // } // if (nums[0] <= nums[mid]) { // if (nums[0] <= target && target < nums[mid]) { // r = mid - 1; // } else { // l = mid + 1; // } // } else { // if (nums[mid] < target && target <= nums[n - 1]) { // l = mid + 1; // } else { // r = mid - 1; // } // } // } // return -1; // } }

var_dump((new Solution)->search([4, 5, 6, 7, 0, 1, 2], 0)); var_dump((new Solution)->search([4, 5, 6, 7, 0, 1, 2], 5)); var_dump((new Solution)->search([3, 5, 1], 3)); var_dump((new Solution)->search([1], 0));

/**

  • 执行用时:8 ms, 在所有 PHP 提交中击败了84.54%的用户
  • 内存消耗:18.8 MB, 在所有 PHP 提交中击败了86.60%的用户
  • 通过测试用例:195 / 195 */ ```