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,可以了。

posted @ 2018-12-26 17:47  大胖子球花  阅读(90)  评论(0)    收藏  举报