1. 概述

假设按照升序排序的数组在预先未知的某个点上进行了旋转。 ( 例如,数组 [0,0,1,2,2,5,6] 可能变为 [2,5,6,0,0,1,2] )。

编写一个函数来判断给定的目标值是否存在于数组中。若存在返回 true,否则返回 false。

示例 1:

输入: nums = [2,5,6,0,0,1,2], target = 0

输出: true

示例 2:

输入: nums = [2,5,6,0,0,1,2], target = 3

输出: false

2. 解题

  1. <?php
  2. class Solution
  3. {
  4. private $exchange = [
  5. 'mid' => -1,
  6. 'left' => -1,
  7. 'right' => -1,
  8. ];
  9. /**
  10. * @param Integer[] $nums
  11. * @param Integer $target
  12. * @return Boolean
  13. */
  14. public function search($nums, $target)
  15. {
  16. $left = 0;
  17. $right = count($nums) - 1;
  18. // 二分法,先检查正确排序的一边,再找乱序一边(乱序先找左,再找右)
  19. while (!$ret = $this->do($nums, $target, $left, $right)) {
  20. $mid = $this->exchange['mid'];
  21. if ($mid == -1 || 0 > $mid || $mid > count($nums) - 1) {
  22. break;
  23. }
  24. $this->exchange['mid'] = -1;
  25. $left = $mid + 1;
  26. $right = $this->exchange['right'];
  27. }
  28. return $ret;
  29. }
  30. /**
  31. * @param array $nums
  32. * @param int $target
  33. * @param int $left
  34. * @param int $right
  35. * @return bool
  36. */
  37. private function do(array $nums, int $target, int $left, int $right)
  38. {
  39. while ($left <= $right) {
  40. $mid = $left + floor(($right - $left) / 2);
  41. if ($nums[$mid] == $target) {
  42. echo "key: " . $mid . "\n";
  43. return true;
  44. } elseif ($nums[$left] < $nums[$mid]) { // 左升序
  45. if ($nums[$left] <= $target && $target < $nums[$mid]) {
  46. $right = $mid - 1;
  47. } else {
  48. $left = $mid + 1;
  49. }
  50. } elseif ($nums[$mid] < $nums[$right]) { // 右升序
  51. if ($nums[$mid] <= $target && $target < $nums[$right]) {
  52. $left = $mid + 1;
  53. } else {
  54. $right = $mid - 1;
  55. }
  56. } else { // 逆序
  57. if ($this->exchange['mid'] == -1) {
  58. $this->exchange['mid'] = $mid;
  59. $this->exchange['left'] = $left;
  60. $this->exchange['right'] = $right;
  61. }
  62. if ($nums[$mid] == $nums[$left]) {
  63. $right--;
  64. } else {
  65. $left++;
  66. }
  67. }
  68. }
  69. return false;
  70. }
  71. }
  72. $nums = [2,5,6,0,0,1,2];
  73. // $nums = [2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2];
  74. $target = 1;
  75. $cls = new Solution();
  76. $ret = $cls->search($nums, $target);
  77. var_dump($ret);