【程序员编程艺术】第五章:寻找满足和为定值的两个或多个数

本文详细介绍了寻找数组中和为定值的两个数的解题思路,包括穷举法、排序优化后的二分查找、构建辅助数组的哈希表方法以及双指针扫描法。讨论了不同方法的时间复杂度和空间复杂度,强调在有序数组中使用双指针扫描法可达到O(N)的时间和O(1)的空间效率。并提出了问题扩展,如寻找和为定值的多个数的解题策略。
摘要由CSDN通过智能技术生成

文章参考:http://blog.csdn.net/v_JULY_v/article/details/6419466

本文是基于上文链接的内容进行裁剪,在自己的理解层次上写出的文章。



第一节:寻找和为定值的两个数

题目描述

输入一个数组和一个数字,在数组中查找两个数,使得它们的和正好是输入的那个数字。
要求时间复杂度是O(N)。如果有多对数字的和等于输入的数字,输出任意一对即可。
例如输入数组1、2、4、7、11、15和数字15。由于4+11=15,因此输出4和11。


思路一:穷举法

从数组中任意选取两个数,判定它们的和是否为输入的那个数字。对每个a[i],查找sum-a[i]是否也在原始序列中,每一次要查找的时间都要花费为O(N),这样下来,最终找到两个数还是需要O(N^2)的复杂度。此举复杂度为O(N^2)。现在这是第一步,得到的最大时间复杂度。紧接着是要用各种方式去优化。


思路二:利用排序去优化

当我们对数组进行排序以后,再去查找,就可以利用各种有效的查找算法。这里,可以利用二分查找。可以将O(N)的查找时间提高到O(logN),这样对于N个a[i],都要花logN的时间去查找相对应的sum-a[i]是否在原始序列中,总的时间复杂度已降为O(N*logN),且空间复杂度为O(1)。

二分查找的实现,有两种定义:算法所操作的区间,是左闭右开区间,还是左闭右闭区间,这个区间,需要在循环初始化,循环体是否终止的判断中,以及每次修改left,right区间值这三个地方保持一致,否则就可能出错。

方式一:左闭右闭( left <= right,right = middle - 1

int search(int array[], int n, int v)
{
    int left, right, middle;
 
    left = 0, right = n - 1;<span style="white-space:pre">	</span>//不同1
    while (left <= right)<span style="white-space:pre">	</span>//不同2
    {
        middle = left + (right-left)/2;   
        if (array[middle] > v)
        {
            right = middle - 1;<span style="white-space:pre">	</span>//不同3
        }
        else if (array[middle] < v)
        {
            left = middle + 1;
        }
        else
        {
            return middle;
        }
    }
    return -1;
}

方式二:左闭右开( left < right,right = middle;

int search(int array[], int n, int v)
{
    int left, right, middle;
 
    left = 0, right = n;
    while (left < right)
    {
        middle = left + (right-lef
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值