题目描述:
统计一个数字在排序数组中出现的次数。
思路:
最基本的思路就是根据排序数组的特点进行二分法定位,定位会出出现的情况时,K可能是第一个,可能是中间某一位置,也可能在最后一个,所以定位到K后,再往左边遍历直到不为K为止,再从定位位置往右遍历直到不为K为止,这样就能计算出K的总数,除此之外,还有加强版的二分法直接定位到K的边界位置,即第一个或者最后一个K的位置,这样就能直接往一个方向遍历计数K的个数,当找第一个K位置时,当定位到K位置d时,还要确保d-1位置不为K或者小于K或者找最后一个K位置时,当找到K位置d时,还要确保d+1位置不为K。
代码:
/*找到K*/
class solution
{
public:
int GetK(int[] data, int k, int start, int end)
{
int index=0;
int FirstKnum=0;
int mid=(start+end)/2;
while((end-start)>=0)
{
if(data[mid]>k)
{
end=mid;
start=start;
}
else if(data[mid]<k)
{
start=mid;
end=end;
}
else
{
index=mid;
break;
}
//else if(data[mid]==k&&)
mid=(start+end)/2;
}
int num0=index;
int num1=index;
while(data[num0]==k)
{
num0++;
FirstKnum++;
}
while(data[num1]==k)
{
num1--;
FirstKnum++;
}
return FirstKnum;
}
}
/*找到第一个k*/
class solution
{
public:
int GetFirstK(int[] data, int k, int start, int end)
{
int index=0;
int FirstKnum=0;
int mid=(start+end)/2;
while((end-start)>=0)
{
if(data[mid]==k&&data[mid-1]!=k)
{
index=mid;
break;
}
else if(data[mid]==k&&data[mid-1]==k)
{
start=start;
end=mid-1;
}
else if(data[mid]>k)
{
start=start;
end=mid-1;
}
else
{
start=mid+1;
end=end;
}
mid=(start+end)/2;
}
while(data[index++]==k)
{
FirstKnum++;
}
return FirstKnum;
}
}
/*找到最后k位置*/
class solution
{
public:
int GetLastK(int[] data, int k, int start, int end)
{
int index=0;
int FirstKnum=0;
int mid=(start+end)/2;
while((end-start)>=0)
{
if(data[mid]==k&&data[mid+1]!=k)
{
index=mid;
break;
}
else if(data[mid]==k&&data[mid+1]==k)
{
start=mid+1;
end=end;
}
else if(data[mid]>k)
{
start=start;
end=mid-1;
}
else
{
start=mid+1;
end=end;
}
}
while(data[index--]==k)
{
FirstKnum++;
}
return FirstKnum;
}
}