33. Search in Rotated Sorted Array
不定期更新leetcode解题java答案。
采用pick one的方式选择题目。
题意为给定移位增序序数组,(增序数组为:0 1 2 4 5 6 7;移位增序数组其中一种可能为:4 5 6 7 0 1 2),搜索给定目标数字,如存在则返回目标位置,否则返回-1。
简单思路为,将目标数组重新移位,变换成原增序数组,再进行二分查找。具体实现代码如下:
1 public class Solution { 2 public int search(int[] nums, int target) { 3 //获取移位个数,location为 数组最小值位置 4 int location = 0; 5 for(int i = 1; i < nums.length; i++){ 6 if(nums[i - 1] > nums[i]){ 7 location = i; 8 break; 9 } 10 } 11 //创建新数组用于存储原增序数组 12 int[] reorderArray = new int[nums.length]; 13 for(int i = 0; i < nums.length; i++) 14 reorderArray[i] = i + location >= nums.length ? nums[i + location - nums.length] : nums[i + location]; 15 //获取目标值在原增序数组的位置 16 int tmpInt = findLocation(target, reorderArray, 0, nums.length - 1); 17 //通过获取的位置进行变换成为移位增序数组的位置 18 return tmpInt == -1 ? -1 : (tmpInt + location >= nums.length ? tmpInt + location - nums.length : tmpInt + location); 19 } 20 21 public int findLocation(int target, int[] nums, int start, int end){ 22 if(start > end) 23 return -1; 24 int mid = (start + end) / 2; 25 if(target == nums[mid]) 26 return mid; 27 28 return target > nums[mid] ? findLocation(target, nums, mid + 1, end) : findLocation(target, nums, start, mid - 1); 29 } 30 }
另有一种方式,采用二分的方式进行搜索,具体实现代码如下:
1 public class Solution { 2 public int search(int[] nums, int target) { 3 return binarySearch(target, nums, 0, nums.length - 1); 4 } 5 6 public int binarySearch(int target, int[] nums, int start, int end){ 7 if(start > end) 8 return -1; 9 int location = -1, mid = (start + end) / 2; 10 if(nums[mid] == target) 11 return mid; 12 location = binarySearch(target, nums, start, mid - 1); 13 if(location == -1) 14 location = binarySearch(target, nums, mid + 1, end); 15 return location; 16 } 17 }
仔细想想,这种方法是利用二分的架子,时间复杂度依旧是O(n),实际上和逐个遍历没有什么太大的区别,于是试着写最原始的遍历搜索的代码,如下:
1 public class Solution { 2 public int search(int[] nums, int target) { 3 for(int i = 0; i < nums.length; i++) 4 if(nums[i] == target) 5 return i; 6 return -1; 7 } 8 }
结果果然是也可以AC,测试时间比第二种稍短。