算法与数据结构二叉树之下数据结构和算法分析

剑指Offer-40 有序数组的两数和(首尾逼近法)

2019-01-18  本文已影响0人  北国雪WRG

输入一个递增排序的数组和一个数字S,在数组中查找两个数,使得他们的和正好是S,如果有多对数字的和等于S,输出两个数的乘积最小的。(对应每个测试案例,输出两个数,小的先输出。)

首尾相加法

  1. 用i,j两个指针,分别指向首尾
  2. i从首开始遍历,j从尾开始遍历
  3. 对于每个i,j都需要全部寻找一遍
    public ArrayList<Integer> FindNumbersWithSum(int [] array,int sum) {
        ArrayList<Integer> list = new ArrayList<>();
        for(int i=0;i<array.length;i++){
            for(int j=array.length-1;j>=0;j--){
                if(array[i] + array[j] == sum){
                    list.add(array[i]);
                    list.add(array[j]);
                    return list;
                }
            }
        }
        return list;
    }

这里面存在一个问题,如果a[i] + a[j] < sum,j依然要 j--,并继续遍历,那么接下来的运算没有意义了。时间复杂度O(n2)

首尾逼近法

这是对上一种方法的改进,核心思想还是从首尾开始找,改变的是通过判断a[i] + a[j]sum的大小关系决定是i改变还是j改变。类似于剪纸的思想。

    public ArrayList<Integer> FindNumbersWithSum(int [] array,int sum) {
        ArrayList<Integer> list = new ArrayList<>();
        int i = 0, j = array.length -1;
        while(j >= i){
            int temp = array[i] + array[j];
            if(temp == sum){
                list.add(array[i]);
                list.add(array[j]);
                break;
            }else if(temp > sum){
                j--;
            }else {
                i ++;
            }
        }
        return list;
    }

时间复杂度O(n)

上一篇 下一篇

猜你喜欢

热点阅读