问题描述:一个有序序列经过反转,得到一个新的序列,查找新序列的某个元素。12345->45123。
算法思想:利用二分查找的思想,都是把要找的目标元素限制在一个小范围的有序序列中。这个题和二分查找的区别是,序列经过mid拆分后,是一个非连续的序列。特别要注意target的上下限问题。因为是非连续,所以要考虑上下限,而二分查找,序列式连续的,只用考虑单限。有递归算法和迭代算法。
递归算法:
1 public int search(int[] nums, int target) 2 { 3 return binarySearch(nums, 0, nums.length - 1, target); 4 } 5 //递归方法 6 public int binarySearch(int[] nums, int left, int right, int target) 7 { 8 //不要忘了这个边界条件。 9 if(left > right) 10 { 11 return -1; 12 } 13 int mid = (left + right)/2; 14 if(target == nums[mid]) 15 { 16 return mid; 17 } 18 if(nums[left] <= nums[mid])//做连续,要包含"="的情况,否则出错。 19 { 20 if(target >= nums[left] && target < nums[mid])//target上下限都要有 21 { 22 return binarySearch(nums, left, mid - 1, target);//记得return 23 } 24 else 25 { 26 return binarySearch(nums, mid + 1, right, target); 27 } 28 } 29 else 30 { 31 if(target > nums[mid] && target <= nums[right]) 32 { 33 return binarySearch(nums, mid + 1, right, target); 34 } 35 else 36 { 37 return binarySearch(nums, left, mid - 1, target); 38 } 39 } 40 }
迭代算法:
//迭代方法 public int binarySearch2(int[] nums, int left, int right, int target) { while(left <= right) { int mid = (left + right)/2; if(target == nums[mid]) { return mid; } if(nums[left] <= nums[mid]) //左连续,所以要包含=的情况。否则出错。 { if(target >= nums[left] && target < nums[mid]) { right = mid - 1; } else { left = mid + 1; } } else { if(target > nums[mid] && target <= nums[right]) { left = mid + 1; } else { right = mid - 1; } } } return -1; }