算法分析:
思路一:遍历计数法
此题可以变为求:有序数组A的长度是m,有序数组B的长度是n,返回A和B合并后的第k个值。
通过遍历两个有序数组,采用计数的方法,当计数到第k个值时,返回数组合并后的第k个值。时间复杂度为O(m+n),空间复杂度为O(1)。
c++代码如下
//aBuffer:有序数组a
//aLen:有序数据a的长度
//bBuufer:有序数组b
//bLen:有序数组b的长度
//k:第k个值
//kValue:返回k位置的值
int GetKthByMerge(int* aBuffer,int aLen,int* bBuffer,int bLen,int k,int& kValue)
{
if(aBuffer == NULL || bBuffer == NULL)
{
return -1;
}
if(aLen == 0 || bLen == 0)
{
return -1;
}
if(k <=0 || k > aLen+bLen)
{
return -1;
}
//特殊情况
if(k == 1)
{
kValue = aBuffer[0] > bBuffer[0] ? bBuffer[0]:aBuffer[0];
return kValue;
}
if(k == aLen+bLen)
{
kValue = aBuffer[aLen-1] > bBuffer[bLen-1] ? aBuffer[aLen-1]:bBuffer[bLen-1];
return 0;
}
int ai = 0;
int bi = 0;
while(ai < aLen && bi < bLen && k > 0)
{
if(aBuffer[ai] < bBuffer[bi])
{
kValue = aBuffer[ai];
ai++;
}
else
{
kValue = bBuffer[bi];
bi++;
}
k--;
}
if(k > 0 && ai < aLen)
{
kValue = aBuffer[ai+k-1];
}
if(k > 0 && bi < bLen)
{
kValue = bBuffer[bi+k-1];
}
return 0;
}
思路二:充分利用排序数组的特性,采用二分递归的方法,时间复杂度是O(m+n)
c++代码如下
//aBuffer: 有序数组a
//bBuffer: 有序数组b
//aStart: a数组起始位置
//aEnd: a数组结束位置
//bStart: b数组起始位置
//bEnd: b数组结束位置
//k:k值
static int FindKValue(int* aBuffer,int* bBuffer,int aStart,int aEnd,int bStart,int bEnd,int k)
{
int aLen = aEnd - aStart + 1;
int bLen = bEnd - bStart + 1;
//递归结束的条件
if(aLen == 0)
{
return bBuffer[bStart + k];
}
if(bLen == 0)
{
return aBuffer[aStart + k];
}
if(k == 0)
{
return bBuffer[bStart] > aBuffer[aStart] ? aBuffer[aStart] : bBuffer[bStart];
}
if(k == aLen+bLen-1)
{
return bBuffer[bEnd] > aBuffer[aEnd] ? bBuffer[bEnd] : aBuffer[aEnd];
}
//ka+kb=k+1;
int ka = (k+1)*aLen/(aLen+bLen);
int kb = (k+1) - ka;
ka = ka + aStart;
kb = kb + bStart;
//递归
if(aBuffer[ka] > bBuffer[kb])
{
//重新调整k值
k = k - (kb-bStart);
//k值不在 bStart~kb之间
bStart = kb;
//k值不在ka~aEnd之间
aEnd = ka;
}
else
{
//重新调整k值
k = k - (ka-aStart);
//k值不在 aStart~ka之间
aStart = ka;
//k值不在kb~bEnd之间
bEnd = kb;
}
return FindKValue(aBuffer,bBuffer,aStart,aEnd,bStart,bEnd,k);
}
此算法只适合算中值,对于任意的K值还有待修正
***未完待续*******