剑指Offer——和为s的两个数字

1、题目描述

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

2、代码实现

import java.util.ArrayList;
/*
一种时间复杂度更低 的算法:
我们现在数组中选择两个数,如果这两个数的和等于给定的sum,那么我们就算是找到了这两个数,
情况1:如果两个数的和小于sum,我们肯定希望这两个数的和再大一点,由于数组是已经排好顺序的,
      我们可以考虑选择较小数字后面的数字,因为排在他后面数字比较大一点
情况2:当两个数字的和大于给定的数字sum的时候,我们可以选择较大数字前面的数字因为排在数组前面的数字较小一些
*/

public class Solution {
    public ArrayList<Integer> FindNumbersWithSum(int [] array,int sum) {
         ArrayList<ArrayList<Integer>> listAll = new ArrayList<>();
        ArrayList<Integer> list = new ArrayList<>();
        if (array.length == 0 || array == null) {
            return list;
        }
        //这里设定两个指针初始化的时候分别指向数组的第一个元素和数组的最后一个元素
        int left = 0;
        int right = array.length - 1;
        while (left < right) {
            //当这两个指针所指向的数字之和刚好等于给定的数字sum的时候,保存这两个数字
            if (array[left] + array[right] == sum) {
                ArrayList<Integer> temp = new ArrayList<>();
                temp.add(array[left] * array[right]);
                temp.add(array[left]);
                temp.add(array[right]);
                listAll.add(temp);
                left++;
                right--;
                //当这两个指针所指向的数字之和大于给定的数字sum的时候,右指针要向前移动
            } else if (array[left] + array[right] > sum) {
                right--;
                //当这两个指针所指向的数字之和小于给定的数字sum的时候,左指针要向后移动
            } else {
                left++;
            }
        }
        //经过循环之后链表中没有数据证明该递增数列不存在两个数的和等于sum
        if (listAll.size() == 0) {
            return list;
        }
        //现在要找到乘积最小的那两个数
        int index = 0;
        for (int i = 0; i < listAll.size(); i++) {
            if (listAll.get(index).get(0) > listAll.get(i).get(0)) {
                index = i;
            }
        }
        list.add(listAll.get(index).get(1));
        list.add(listAll.get(index).get(2));
        return list;
    }
}

  

posted @ 2019-07-14 09:45  包子的百草园  阅读(153)  评论(0编辑  收藏  举报