求一个有序数组中两个值相加为k的数字,返回这两个数字的下标。(腾讯面试题)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/hehongonghh/article/details/82663726

算法分析:有序的数组(假设非降序),采取双向遍历,一个从前往后,一个从后往前,当前数字相加如果相等则返回,如果小于k则前面的继续往后,如果大于k则后面的继续往前
代码如下:
typedef struct Pairs
{
    int x;//第一个数的下标
    int y;//第二个数的下标
}Pairs;

//求一个有序数组中两个值相加为k的数字,返回这两个数字的下标。
//找到返回正常的下标,查找失败返回-1
Pairs SumToK(int *arr,int len,int k)//时间复杂度O(n),空间复制度O(1)
{
    Pairs pa = {-1,-1};
    int low = 0;        //从前往后遍历
    int high = len-1;//从后往前遍历
    int sum;

    while(low <= high)
    {
        sum = arr[low] + arr[high];
        if(sum < k)
        {
            low++;
        }
        else if(sum > k)
        {
            high--;
        }
        else
        {
            pa.x = low;
            pa.y = high;
            break;
        }
    }
    return pa;
}

int main()
{
    int arr[] = {1,3,5,6,17,18,29,33,44,55,89};
    int k = 9;
    Pairs pa = SumToK(arr,sizeof(arr)/sizeof(arr[0]),k);
    if(pa.x == -1)
        printf("没有两数相加等于%d\n",k);
    else
        printf("相加等于%d的为%d,%d下标的值\n",k,pa.x,pa.y);

    k = 50;
    pa = SumToK(arr,sizeof(arr)/sizeof(arr[0]),k);
    if(pa.x == -1)
        printf("没有两数相加等于%d\n",k);
    else
        printf("相加等于%d的为%d,%d下标的值\n",k,pa.x,pa.y);

    k = 4;
    pa = SumToK(arr,sizeof(arr)/sizeof(arr[0]),k);
    if(pa.x == -1)
        printf("没有两数相加等于%d\n",k);
    else
        printf("相加等于%d的为%d,%d下标的值\n",k,pa.x,pa.y);

    k = 1;
    pa = SumToK(arr,sizeof(arr)/sizeof(arr[0]),k);
    if(pa.x == -1)
        printf("没有两数相加等于%d\n",k);
    else
        printf("相加等于%d的为%d,%d下标的值\n",k,pa.x,pa.y);
}
//TODO,如果相加为k的有多组,上面的算法并没有实现,例如k=50,有6+44,17+33

//2.2,如果是无序的数组呢?
//算法分析:1.如果都是非负的数字,则可以建立一个k长度的哈希表,哈希表中每个元素保存值和下标,遍历整个数组一遍把大于k的值直接丢弃(相加不可能为k)小于等于k的值保存到哈希表,然后利用上面的算法遍历哈希表即可.

猜你喜欢

转载自blog.csdn.net/hehongonghh/article/details/82663726
今日推荐