Leetcode34. Find First and Last Position of Element in Sorted Array
暴力思路肯定是遍历一遍,O(n)。
要求O(logn)而且想到有序数列查找,就应该想到二分查找。
开始的想法,二分查找,但是遇到target不返回,而是继续往两边找,那么就需要用递归。如下:
1 class Solution { 2 public int[] searchRange(int[] nums, int target) { 3 // int[] ans = new int[2]; 4 // ans[0]=-1;ans[1]=nums.length; 5 int[] ans = {nums.length,-1}; 6 if(nums==null) return ans; 7 search(nums,target,0,nums.length-1,ans); 8 if(ans[0]==nums.length) ans[0]=-1; 9 return ans; 10 11 } 12 private void search(int[] nums,int target,int s,int e,int[] ans){ 13 if(s>e) return; 14 int m = (s+e)/2; 15 if(target==nums[m]){ 16 ans[0]=Math.min(ans[0],m); 17 ans[1]=Math.max(ans[1],m); 18 search(nums,target,s,m-1,ans); 19 search(nums,target,m+1,e,ans); 20 } 21 else if(target>nums[m]) 22 search(nums,target,m+1,e,ans); 23 else 24 search(nums,target,s,m-1,ans); 25 26 } 27 }
6ms,24.40%.
优化了一下,还是6ms。
1 class Solution { 2 public int[] searchRange(int[] nums, int target) { 3 int[] ans = {-1,-1}; 4 if(nums==null) return ans; 5 int s=0,e=nums.length-1; 6 int m = -1; 7 boolean isFound = false; 8 while(s<=e){ 9 m = (s+e)/2; 10 if(target==nums[m]){ 11 isFound = true; 12 break; 13 } 14 else if(target>nums[m]){ 15 s=m+1; 16 } 17 else 18 e = m-1; 19 } 20 if(isFound){ 21 int p=m-1; 22 while(p>=0&&nums[p]==nums[m]){ 23 p--; 24 } 25 ans[0]=p+1; 26 p=m+1; 27 while(p<=nums.length-1&&nums[p]==nums[m]){ 28 p++; 29 } 30 ans[1]=p-1; 31 } 32 return ans; 33 } 34 }
想想也是,我这样如果对testcase 8,8,8,8,8
那么时间复杂度就是O(n)了,并不是O(logn)。
看了3ms答案:
1 class Solution { 2 public int[] searchRange(int[] nums, int target) { 3 int[] res = new int[]{-1, -1}; 4 if (nums == null || nums.length == 0) { 5 return res; 6 } 7 8 int left = findFirst(nums, target); 9 int right = findLast(nums, target); 10 res[0] = left; 11 res[1] = right; 12 13 return res; 14 } 15 16 private int findFirst(int[] nums, int target) { 17 int left = 0, right = nums.length-1; 18 int idx = -1; 19 20 while (left <= right) { 21 int mid = left + (right - left)/2; 22 23 if (nums[mid] >= target) { 24 right = mid - 1; 25 } else { 26 left = mid + 1; 27 } 28 29 if (nums[mid] == target) { 30 idx = mid; 31 } 32 } 33 34 return idx; 35 } 36 37 private int findLast(int[] nums, int target) { 38 int left = 0, right = nums.length - 1; 39 int idx = -1; 40 41 while (left <= right) { 42 int mid = left + (right - left)/2; 43 44 if (nums[mid] <= target) { 45 left = mid + 1; 46 } else { 47 right = mid - 1; 48 } 49 50 if (nums[mid] == target) { 51 idx = mid; 52 } 53 } 54 55 return idx; 56 } 57 }
3-6ms,可以了。

浙公网安备 33010602011771号