53.1数字x在排序数组中出现的次数
解法一:遍历数组到X,开始计数,O(N)
解法二:递归使用二分法遍历计数,直至当前分段上下节点出现目标数字K时开始计数
解法三:二分法先查找数字k,再从k开始,往上往下计数 O(logn)
解法四:找出最左一个k和最右一个K,计数 O(logn)
解法三:
int GetNumberOfK_Kth(const int* data, int length, int k)//find Kth
{
if (data == nullptr || length <= 0) return 0;
if (k<data[0] || data[length - 1]<k) return 0;
int cnt = 0;
int L = 0, R = length - 1;
int mid = 0;
while (L<=R)
{
mid = (L + R) >> 1;
if (data[mid] == k)
{
for (int i = mid; i >= L;i--)
{
if (data[i] == k)
cnt++;
else
break;
}
for (int i = mid + 1; i <= R;i++)
{
if (data[i] == k)
cnt++;
else
break;
}
break;
}
else if (data[mid]>k)
R = mid - 1;
else
L = mid + 1;
}
return cnt;
}
解法二:
int GetNumberOfK_binaryCnt(const int* data, int start, int end, int k)//binaryCnt
{
if (start > end || end < start) return 0;
int cnt=0;
int mid = (start + end) >> 1;
if (data[start]==k)
{
for (int i = start; i <= end;i++)
{
if (data[i] == k)
cnt++;
else
break;
}
return cnt;
}
else if (data[end]==k)
{
for (int i = end; i >= start; i--)
{
if (data[i] == k)
cnt++;
else
break;
}
return cnt;
}
else
{
if (data[mid] < k)
cnt += GetNumberOfK_binaryCnt(data, mid + 1, end, k);
else if (data[mid]>k)
cnt += GetNumberOfK_binaryCnt(data, start, mid-1, k);
else
return GetNumberOfK_binaryCnt(data, mid + 1, end, k) + GetNumberOfK_binaryCnt(data, start, mid, k);
}
return cnt;
}
int GetNumberOfK_binaryCnt(const int* data, int length, int k)//binaryCnt
{
if (data == nullptr || length <= 0) return 0;
if (k<data[0] || data[length - 1]<k) return 0;
return GetNumberOfK_binaryCnt(data, 0, length-1, k);
}
解法一
int GetNumberOfK_Bruteforce(const int* data, int length, int k)//diy Brute force
{
if (data == nullptr || length <= 0) return 0;
if (k<data[0] || data[length - 1]<k) return 0;
int cnt = 0;
bool appreared = false;
for (int i = 0; i < length;i++)
{
if (!appreared && data[i] == k)
{
cnt++;
appreared = true;
}
else if (appreared && data[i]==k)
cnt++;
else if (appreared && data[i]!=k)
break;
}
return cnt;
}
53.2 0~n-1中缺失的数字,长度为n-1的递增排序数组,所有数字都是唯一的,且在[0,n-1]内,在0-n-1内有且只有一个数字不在该数组中,找出该数
解法一:找到第一个下标与数字不同的数,返回下标o(n)
解法二:记录所有组的和,计算N个数的和,求差,o(n)
解法三:用二分法,找到第一个下标与数字不同的数字,往左偏移,即如果中位数与下标相等,从右边找;否则往左试探一位,如果下标与数字不等,往坐标找,如果下标与数字相等,该中位数就是那缺失的数字 o(log)
解法三
int GetMissingNumber(const int* numbers, int length)//diy
{
if (numbers == nullptr || length <= 0) return -1;
int L = 0, R = length - 1;
while (L<=R)
{
int mid = (L + R) >> 1;
if (numbers[mid] == mid)
L = mid + 1;
else
{
if (mid - 1 >= L && numbers[mid - 1] == mid - 1)
return numbers[mid]-1;
else if (mid - 1 >= L && numbers[mid - 1] != mid - 1)
R = mid - 1;
else
return numbers[mid]-1;
}
}
if (L > R)
return numbers[length - 1] + 1;
return -1;
}
53.3 在单调递增数组中找到任意一个数值等于其下标的元素,数组中的数可能为负数
下标递增线和值递增线,趋势上可能会有一个相交点
int GetNumberSameAsIndex(const int* numbers, int length) //diy
{
if (numbers == nullptr || length <= 0) return -1;
int L = 0, R = length - 1;
while (L<=R)
{
int mid = (L + R) >> 1;
if (numbers[mid] == mid) return mid;
else if (numbers[mid] > mid)
R = mid - 1;
else
L = mid + 1;
}
return -1;
}