题目描述
统计一个数字在排序数组中出现的次数。
解题思路
排序的数组要马上想到二分,其中二分有求第一个大于等于值的lower_bound算法,也有求第一个大于值的upper_bound算法,最后注意right位置对应的数组值可能正好等于要查找的值,此时right++
Code
- 非递归
class Solution {
public:
int Upper_bound(vector<int> data, int start, int end, int k) {
//返回最后一个大于k的位置
int left = start, right = end;
while(left < right) {
int middle = left+(right-left)/2;
if(data[middle] > k) {
right = middle;
} else {
left = middle+1;
}
}
return left;
}
int Lower_bound(vector<int> data, int start, int end, int k) {
//返回第一个大于等于k的位置
int left = start, right = end;
while(left < right) {
int middle = left + (right-left) / 2;
if(data[middle] >= k) {
right = middle;
} else {
left = middle+1;
}
}
return left;
}
int GetNumberOfK(vector<int> data ,int k) {
int left = Lower_bound(data, 0, data.size()-1, k);
int right = Upper_bound(data, 0, data.size()-1, k);
if(right < data.size() && data[right] == k) right++;
return right-left;
}
};
- 递归
class Solution {
public:
int GetFirstK(vector<int> data, int length, int k, int start, int end) {
if(start > end) {
return -1;
}
int middleIndex = (start+end)/2;
int middleData = data[middleIndex];
if(middleData == k) {
if((middleIndex > 0 && data[middleIndex-1] != k) || middleIndex == 0) {
return middleIndex;
} else {
end = middleIndex-1;
}
} else if(middleData > k) {
end = middleIndex-1;
} else {
start = middleIndex+1;
}
return GetFirstK(data, length, k, start, end);
}
int GetLastK(vector<int> data, int length, int k, int start, int end) {
if(start > end) {
return -1;
}
int middleIndex = start+(end-start)/2;
int middleData = data[middleIndex];
if(middleData == k) {
if((middleIndex < length-1 && data[middleIndex+1] != k) || middleIndex == length-1) {
return middleIndex;
} else {
start = middleIndex+1;
}
} else if(middleData < k) {
start = middleIndex + 1;
} else {
end = middleIndex-1;
}
return GetLastK(data, length, k, start, end);
}
int GetNumberOfK(vector<int> data ,int k) {
int result = 0;
if(data.size()) {
int first = GetFirstK(data, data.size(), k, 0, data.size()-1);
int last = GetLastK(data, data.size(), k, 0, data.size()-1);
if(first > -1 && last > -1) {
result = last-first+1;
}
}
return result;
}
};
- java
public class Solution {
public int lower_bound(int[] array, int k) {
int left = 0, right = array.length - 1;
while(left <= right) {
int mid = (left+right)/2;
if(array[mid] < k) {
left = mid+1;
} else {
right = mid-1;
}
}
return left;
}
public int upper_bound(int[] array, int k) {
int left = 0, right = array.length-1;
while(left <= right) {
int mid = (left+right)/2;
if(array[mid] <= k) {
left = mid+1;
} else {
right = mid-1;
}
}
return right;
}
public int GetNumberOfK(int [] array , int k) {
int result = 0, len = array.length;
if(len > 0) {
int start = lower_bound(array, k);
if(start >= 0 && start < len && array[start] == k) {
int end = upper_bound(array, k);
result = end-start+1;
}
}
return result;
}
}