LeetCode每日一題(二)
統計一個數字在排序數組中出現的次數。
示例 1:
輸入: nums = [5,7,7,8,8,10], target = 8
輸出: 2
示例 2:
輸入: nums = [5,7,7,8,8,10], target = 6
輸出: 0
限制:
0 <= 數組長度 <= 50000
題目中出現了排序,那我們首要選擇二分法查找
二分法的通用寫法:
// nums爲數組,target爲目標值
int left = 0;
int right = nums.length-1;
while(left <= right){
//這裏有兩種寫法
//第一種,int mid = (right - left)/2;
//第二種,int mid = left + (right-left)/2 ,因爲我們的數組可能會很大,導致left+right會超過int型的最大值2147483647,我們選擇使用 int mid = left + (right-left)/2
int mid = left + (right-left)/2;
if(nums[mid] == target){
// 找到目標值
}else if(nums[mid] < target){
// 中間值小於目標值,證明需要尋找的目標值的區間一定在 mid+1 ~ right這個區間裏
left = mid+1;
}else if(nums[mid] > target){
//中間值大於目標值,證明需要尋找的值得區間一定是 left ~ mid-1 這個區間裏
right = mid-1;
}
}
我們回過頭來看這道題,提供的數組nums裏可能會有重複值,但是這個數組是個排序數組,我們依然可以使用二分法查找
public int search(int[] nums, int target) {
// nums爲數組,target爲目標值
if (nums.length == 0) return 0;
int res = 0;
int left = 0;
int right = nums.length - 1;
while (left <= right) {
//這裏有兩種寫法
//第一種,int mid = (right - left)/2;
//第二種,int mid = left + (right-left)/2 ,因爲我們的數組可能會很大,導致left+right會超過int型的最大值2147483647,我們選擇使用 int mid = left + (right-left)/2
int mid = left + (right - left) / 2;
if (nums[mid] > target) {
// 中間值小於目標值,證明需要尋找的目標值的區間一定在 mid+1 ~ right這個區間裏
right = mid - 1;
} else if (nums[mid] < target) {
// 中間值小於目標值,證明需要尋找的目標值的區間一定在 mid+1 ~ right這個區間裏
left = mid + 1;
} else if (nums[mid] == target) {
res++;
int tempLeft = mid;
while (tempLeft-- > 0 && nums[tempLeft] == target) {
res++;
}
int tempRight = mid;
while (tempRight++ < nums.length - 1 && nums[tempRight] == target) {
res++;
}
return res;
}
}
}
前面幾個判斷都和通用的一樣,只有我們找到目標值這裏有一些變化,單獨拿出來看一下
else if (nums[mid] == target) {
res++;
int tempLeft = mid;
while (tempLeft-- > 0 && nums[tempLeft] == target) {
res++;
}
int tempRight = mid;
while (tempRight++ < nums.length - 1 && nums[tempRight] == target) {
res++;
}
return res;
}
- 首先,我們找到了目標值,但是目標值在數組裏可能不是一個,可能會有多個,但是,這幾個相同的數一定的相鄰的,畢竟是排序數組嘛,所以,我們從mid這個位置向前,向後尋找和nums[mid]相同的值,就可以把所有出現的個數都找到了。
- 向前尋找,對比mid和mid-1,如果不相等,證明mid的左邊沒有和taget相等的數,如果相等,結果+1,mid-1,繼續循環,要注意邊界,如果mid==0,那mid-1就會超出邊界。
- 向後尋找,對比mid和mid+1,如果不相等,證明mid的右邊沒有和taget相等的數,如果相等,結果+1,mid+1,繼續循環,同樣也要注意邊界,mid+1要小於等於nums.length -1
- 循環結束,直接return