34.Find First and Last Position of Element in Sorted Array---頭條面試題、《劍指offer》38

題目連接數組

題目大意:找出一串升序數組中target值的起始下標和結束下標值,若是不存在則返回{-1,-1}。ide

解法一:用二分查找,找到數組中的target,而後找其左邊和右邊的target下標值。代碼以下(耗時11ms):spa

 1     public int[] searchRange(int[] nums, int target) {
 2         if(nums == null || nums.length == 0) {
 3             int[] r = {-1, -1};
 4             return r;
 5         }
 6         int low = 0, high = nums.length - 1;
 7         int start = -1, end = -1;
 8         while(low <= high) {
 9             int mid = (low + high) / 2;
10             if(nums[mid] < target) {
11                 low = mid + 1;
12             }
13             else if(nums[mid] > target) {
14                 high = mid - 1;
15             }
16             else {
17                 //找左邊起始下標
18                 for(int i = mid; i >= 0; i--) {
19                     if(nums[i] == target) {
20                         start = i;
21                     }
22                     else {
23                         break;
24                     }
25                 }
26                 //找右邊終止下標
27                 for(int i = mid; i < nums.length; i++) {
28                     if(nums[i] == target) {
29                         end = i;
30                     }
31                     else {
32                         break;
33                     }
34                 }
35                 break;
36             }
37         }
38         int[] res = {start, end};
39         return res;
40     }
View Code

解法二:直接暴力,一次遍歷,找重複值。代碼以下(耗時10ms):code

 1     public int[] searchRange(int[] nums, int target) {
 2         int start = -1, end = -1;
 3         boolean mark = false;
 4         for(int i = 0; i < nums.length; i++) {
 5             if(nums[i] == target) {
 6                 if(mark == false) {
 7                     start = end = i;
 8                     mark = true;
 9                 }
10                 else {
11                     end = i;
12                 }
13             }
14         }
15         int[] res = {start, end};
16         return res;
17     }
View Code

 解法三:真正的二分查找。法一其實複雜度仍是o(n)。應該先對起始下標進行二分查找,而後再對結束下標進行二分查找。代碼以下(耗時5ms):blog

 1     public int[] searchRange(int[] nums, int target) {
 2         int left = 0, right = nums.length - 1;
 3         int[] res = {-1, -1};
 4         if(nums.length == 0) {
 5             return res;
 6         }
 7         //二分找到起始下標
 8         while(left < right) {
 9             int mid = (left + right) / 2;
10             //這裏比較左值,若是<,則left更新,不然left不會更新
11             //因此left不更新有兩種狀況:>或=
12             if(nums[mid] < target) {
13                 left = mid + 1;
14             }
15             //這裏通通修改右值
16             else {
17                 right = mid;
18             }
19         }
20         if(nums[left] != target) {
21             return res;
22         }
23         res[0] = left;
24         left = 0;
25         right = nums.length - 1;
26         //二分找到結束下標
27         while(left < right) {
28             //這裏要+1,不然會出錯
29             int mid = (left + right) / 2 + 1;
30             //比較右值,若是>,則right更新
31             if(nums[mid] > target) {
32                 right = mid - 1;
33             }
34             //修改Left
35             else {
36                 left = mid;
37             }
38         }
39         res[1] = right;
40         return res;
41     }
View Code
相關文章
相關標籤/搜索