題目: 給定一個 n 個元素有序的(升序)整型陣列 nums 和一個目標值 target ,寫一個函式搜尋 nums 中的 target,如果目標值存在返回下標,否則返回 -1。
解法一:左閉右閉區間。(left = 0, right = nums.length - 1)
思路:對於這種問題,捕捉到資料型別是陣列並且陣列中元素是有序的並且是查詢類首先想到使用二分查詢來解決。首先找到陣列的中間值,使用中間值與target進行比較,假如target小於nums[mid]代表target在中間值的左側,所以我們排除掉一半的資料。之後繼續重複之前的做法,逼近target即可。
在左閉右閉的條件下,左邊界和右邊界都是存在意義的,所以在迴圈條件中left在小於等於right的情況下都是有意義的。在target小於nums[mid]的情況下,移動右側邊界,right = mid - 1; 因為right是有意義的嘛,nums[mid]已經確實不是target的情況下要使用,right = mid - 1;來縮小範圍。反之同理。
程式碼如下:
點選檢視程式碼
class Solution {
public int search(int[] nums, int target) {
if(nums[nums.length - 1] < target || nums[0] > target) {
return -1;
}
int left = 0;
int right = nums.length - 1;
while(left <= right) {
int mid = (left + right) / 2;
if(nums[mid] == target){
return mid;
}else if(nums[mid] > target) {
right = mid - 1;
}else {
left = mid +1;
}
}
return -1;
}
}
解法二:左閉右開區間。(left = 0, right = nums.length)
思路:總體思路同解法一,但是right變成了開區間。使得mid也變成了開區間,在縮小邊界賦值mid時不必對right - 1,使用right就可以了。在迴圈條件中left也始終小於right.
程式碼如下:
點選檢視程式碼
class Solution {
public int search(int[] nums, int target) {
if (nums[nums.length - 1] < target || nums[0] > target) {
return -1;
}
int left = 0;
int right = nums.length;
while (left < right) {
int mid = (left + right) / 2;
if (nums[mid] == target) {
return mid;
} else if (nums[mid] > target) {
right = mid;
} else {
left = mid + 1;
}
}
return -1;
}
}