package BisectionMethod; /** * 二分法精髓就是每次努力扔掉一半 * 81.搜索旋转排序数组 II * 已知存在一个按非降序排列的整数数组 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,4,4,5,6,6,7] 在下标 5 处经旋转后可能变为 [4,5,6,6,7,0,1,2,4,4] 。 * 给你 旋转后 的数组 nums 和一个整数 target ,请你编写一个函数来判断给定的目标值是否存在于数组中。如果 nums 中存在这个目标值 target ,则返回 true ,否则返回 false 。 * 你必须尽可能减少整个操作步骤。 * */ /** * 这题难点在于怎么判断不符合条件的一半, 如果不能扔掉一半, 起码要不断地缩小空间. * 每次拿到一个mid后, 如果它不等于target, 那么它可以将整个区间分为左侧[left, mid) 和右侧(mid, right), * 而且整个两个区间值总有一个是有序的, 我们只有判断target是不是在有序的区间内, 是的话就可以把另外一半扔掉, 不在这有序的区间内的话, 就扔掉有序的这一半. * * 每一次二分后: 如果target已经找到, 可以直接返回, * 否则剩余区间可以分为2个部分[left, mid) 和 (mid, right); * 情况1: nums[mid] > nums[left] : 暗示[left, mid) 有序的, (mid, right)则是螺旋的 * 判断target 是不是在[left, mid), 如果是则right = mid, 不在这个区间的话, 那么肯定在(mid, right), left = mid + 1;* * 情况2: nums[mid] < nums[left] : 暗示(mid, right) 是有序的 * 判断target 是不是在(mid, right) 中, 如果是则left = mid +1, 不在这个区间的话, 那么肯定在[left, mid), right = mid;* * 情况3: nums[mid] == nums[left], 无法区分,但是由于nums[mid] != target, 可以left++; * */ public class SearchInRotatedSortedArray2 { public static void main(String[] args) { int [] arr = {0,1,2,4,4,4,5,6,6,7}; int target = 4; boolean flag = search(arr,target); System.out.println(flag); } public static boolean search(int[] nums, int target) { int left = 0; int right = nums.length - 1; while (left <= right) { int mid = left + (right - left) / 2; if (nums[mid] == target) { return true; } // 1. if (nums[mid] > nums[left]) { if (target >= nums[left] && target < nums[mid]) { right = mid - 1; } else { left = mid; } } // 2. else if (nums[mid] < nums[left]) { if (target <= nums[right] && target > nums[mid]) { left = mid + 1; } else { right = mid; } } // 3. else { left++; } } return false; } }
标签:right,target,nums,int,SearchInRotatedSortedArray2,mid,left From: https://www.cnblogs.com/lipinbigdata/p/17294524.html