33.二分查找在旋转数组
题目描述
给你一个整数数组 nums ,和一个整数 target 。 该整数数组原本是按升序排列,但输入时在预先未知的某个点上进行了旋转。(例如,数组 [0,1,2,4,5,6,7] 可能变为 [4,5,6,7,0,1,2] )。 请你在数组中搜索 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
code1:
static int SearchInRotatedSortedArray(int array[], int low, int high, int target) {if (array.length == 0) return -1;if (array.length == 1) return array[0] == target ? 0 : -1;int p = findT(array);if (p == -1) {p = findP(array, 0, array.length - 1, target);} else if (array[0] <= target) {p = findP(array, 0, p, target);} else {p = findP(array, p + 1, array.length - 1, target);}return array[p] == target ? p : -1;}static int findP(int[] nums, int l, int h, int t) {int m = 0;while (l < h) {m = l + (h - l) / 2; //中间数if (nums[m] < t) {l = m + 1;} else {h = m;}}return l;}static int findT(int[] nums) {if (nums[0] < nums[nums.length - 1]) return -1;int l = 0, h = nums.length - 1, m = 0;while (l < h) {m = l + (h - l + 1) / 2;if (nums[m] < nums[0]) {h = m - 1;} else {l = m;}}return l;}
code2:
首先进行查找,找到旋转的位置,然后根据那个位置分成两部分,进行二分查找
//进行两次二分查找,static int SearchInRotatedSortedArray(int array[], int low, int high, int target) {if (array == null || array.length == 0) {return -1;}if(array.length==1) return array[0] == target ? 0 : -1;//首先进行查找变化值, 然后根据两部分进行二分查找int cutoff = 0;for (int i = 0; i < array.length-1; i++) {if(array[i] > array[i+1] ){cutoff=i;break;}}//进行二分查找int left = binarySearch(array, 0, cutoff, target);int right = binarySearch(array, cutoff+1, array.length-1, target);return left == -1 ? right : left;}//进行二分查找static int binarySearch(int[] arr, int left, int right, int target) {while (left <= right) { //二分朝招int mid = left - (left-right) /2;if (arr[mid] == target) { //等于targetreturn mid;}else if(arr[mid] > target){right = mid -1;}else{left= mid+1;}}return -1;}
code3:
public static void main(String[] args) {int[] arr = {4,5,6,7,0,1,2};System.out.println(search(arr, 0));}//进行两次二分查找//肯定是有一边是有序的static public int search(int[] nums, int target) {int n = nums.length; //获取数组的长度if (n == 0) { //如果数组长度为0 ,直接返回return -1;}if (n == 1) { //如果长度为1 ,只有一个值,判断这个值和target是否相同,如果不相同返回-1return nums[0] == target ? 0 : -1;}//left right左右两个值int l = 0, r = n - 1;while (l <= r) { //左边小于右边int mid = (l + r) / 2;if (nums[mid] == target) { //中间值正好找到return mid;}//wyg 判断哪个是有序的一边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;}
