标签:整数 track 方法 复杂 二分查找 return tor code range
题目例如以下:
给定一个升序的整数数组。查找某一个值在数组中出现的索引號。比如。输入数组2,3。3,4,4。5;查找的数是3,则返回1,2。
时间复杂度要求为O(logN)。
初次拿到这个题目能够马上想到用二分查找来做。先比較中间的数和要查找的数。假设keyword(要查找的数)小于中间的数,那么在数组的左半部分继续查找。假设keyword大于中间的数。那么在数组的右半部分继续查找,假设keyword和中间的数相等。那么先比較中间数字的前一个数字是否和keyword相等,假设相等。继续用keyword和前一个数字的前一个数字比較,假设不等,那么当前数字就是要查找的数字。其所在的索引就是第一次出现的地方。对于结束的索引,能够用相似的方法来做,先比較中间数字的后一个数字是否和keyword相等,假设相等。继续用keyword和后一个数字的后一个数字比較,假设不等,那么当前数字就是要查找的数字,其所在的索引就是最后一次出现的地方。
可是这样做,最坏的情况下。时间复杂度会退化为O(N),即当数组是同一个数的时候。所以这样的方法不是时间上最优的。
事实上,本题目是二分查找的变种,我们能够分为两步来做,第一步,求得该数字第一次出现的索引,第二步,求得该数字最后一次出现的索引。
首先来看第一次出现的索引怎么来求。首先比較中间的数和要查找的数。假设keyword(要查找的数)小于中间的数,那么在数组的左半部分继续查找。假设keyword大于中间的数,那么在数组的右半部分继续查找,假设keyword和中间的数相等。那么比較中间数字的前一个数字是否和keyword相等。假设不相等,那么当前的中间索引就是第一次出现的索引。假设相等,那么继续在前半部分查找。详细的实现代码例如以下:
//寻找開始索引
int GetFirstTarget(int A[], int n, int target,int nStart,int nEnd)
{
if (nStart > nEnd)
{
return -1;
}
//中间索引
int nMid = nStart + ( (nEnd-nStart) >> 1);
int nMidData = A[nMid];
while (nStart <= nEnd)
{
if (target > nMidData)
{
nStart = nMid+1;
}
else if (target < nMidData)
{
nEnd = nMid-1;
}
else if (target == nMidData)
{
if ((target != A[nMid-1] && nMid > 0) || nMid == 0)
{
return nMid;
}
else
nEnd = nMid-1;
}
//更新中间值得索引和值
nMid = nStart + ( (nEnd-nStart) >> 1);
nMidData = A[nMid];
}
return -1;
}//寻找结束索引
int GetSecondTarget(int A[], int n, int target,int nStart,int nEnd)
{
if (nStart > nEnd)
{
return -1;
}
//中间索引
int nMid = nStart + ( (nEnd-nStart) >> 1);
int nMidData = A[nMid];
while (nStart <= nEnd)
{
if (target > nMidData)
{
nStart = nMid+1;
}
else if (target < nMidData)
{
nEnd = nMid-1;
}
else if (target == nMidData)
{
if ((target != A[nMid+1] && nMid < n) || nMid == n-1)
{
return nMid;
}
else
nStart = nMid+1;
}
//更新中间值得索引和值
nMid = nStart + ( (nEnd-nStart) >> 1);
nMidData = A[nMid];
}
return -1;
}vector<int> searchRange(int A[], int n, int target)
{
std::vector<int> vecIndex;
vecIndex.resize(2);
vecIndex[0] = -1;
vecIndex[1] = -1;
if (A == NULL || n <= 0)
{
return vecIndex;
}
vecIndex[0] = GetFirstTarget(A,n,target,0,n-1);
vecIndex[1] = GetSecondTarget(A,n,target,0,n-1);
return vecIndex;
}两次查找的时间复杂度都是O(logN),所以总的时间复杂度就是O(logN)。
最后。这个题目还有另外一个变种就是数字在排序数组中出现的次数标签:整数 track 方法 复杂 二分查找 return tor code range
原文地址:http://www.cnblogs.com/jzssuanfa/p/6934714.html