和为S的两个数

题目描述

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

输出描述

对应每个测试案例,输出两个数,小的先输出。

求解过程

  • 首先注意题目要求,数组是有序,其次要求和相同的要乘积最小那么根据这两个信息可以得到一些东西。
  • 数组有序可以考虑二分(减少时间复杂度),和相同要乘积最小那么可以举个例子来考虑,加如我们需要的和为10,那么可以组成10的数字分别是1/9,2/8,3/7等等,从这些数据中可以看出1/9乘积最小满足题目中所述,那么可以推导出两个数的和相同,乘积最小的两个数字是相隔最远的两个数
  • 根据上面得出的结论可以考虑从有序数组第一个元素开始对数组遍历,只要找到第一对数那必然是最后的结果。从下标0开始,此时我们假设当前array[i]就是我们要求的结果中的一个数,那么另一个数就应该是target=sum-array[i],现在要做的事就是从下标low+1到数组最后找到是否存在这样一个数,存在那么就解决了,不存在那就要继续遍历,是不是经典的二分查找了(有序数组,下标,target)
  • 此时还需要考虑当我们从左往右遍历的时候那么右边的数字会随着low下标增大,high下标的范围会缩小(因为和是固定的),那么我们二分查找的范围就可以固定到low+1-high之间查找target并返回对应下标如果查找不成功就返回二分查找中最后的高位下标作为下一次循环的high(下面解释为什么这么做)
  • 如果查找成功那么返回了命中下标直接存储结果就可以跳出循环了,但是如果查找失败我们就会进入下一次小的数固定查找,根据二分查找失败的条件是低位索引高于了高位索引都没有命中,那也就是说当前查找失败的高位索引一定是最靠近target的值,此时我们将高位索引返回虽然会比target小一些,但是因为下一次循环会增大较小的值,较大的值根据和不变也会减小,所以刚好符合要求,将此时二分查找的高位索引作为下一次的high可以加快搜索减少时间复杂度

解题源代码

import java.util.ArrayList;
public class Solution {
    public ArrayList<Integer> FindNumbersWithSum(int [] array,int sum) {
        ArrayList<Integer> result = new ArrayList<>();
        if (array==null || array.length==0) return result;
        int low = 0;
        int high = array.length-1;
        while (low<high) {
            int rest = sum - array[low];
            high = getTarget(array, low+1, high, rest);
            if (array[high]!=rest) low++;
            else {
                result.add(array[low]);
                result.add(array[high]);
                break;
            }
        }
        return result;
    }
    
    private static int getTarget(int[] array, int start, int end, int target) {
        int low = start;
        int high = end;
        while (low<=high) {
            int mid = low + (high-low)/2;
            if (array[mid]==target) return mid;
            else if (array[mid] > target) high = mid-1;
            else low = mid+1;
        }
        //未找到,将较小的下标值返回
        return high;
    }
}
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • 和为s的两个数 要求数组要排序 和为s的连续的正整数 小明很喜欢数学,有一天他在做数学作业时,要求计算出9~16的...
    稀饭粥95阅读 1,270评论 0 0
  • 问题描述给出一个递增数组和一个目标值s,找出和为s的两个数问题解法定义两个指针start,end,分别指向头与尾。...
    NetCedar阅读 2,383评论 0 0
  • 1. 找出数组中重复的数字 题目:在一个长度为n的数组里的所有数字都在0到n-1的范围内。数组中某些数字是重复的,...
    BookThief阅读 5,902评论 0 2
  • 一些概念 数据结构就是研究数据的逻辑结构和物理结构以及它们之间相互关系,并对这种结构定义相应的运算,而且确保经过这...
    Winterfell_Z阅读 11,479评论 0 13
  • 原文出处:http://www.cnblogs.com/maybe2030/p/4715035.html引文出处:...
    明教de教主阅读 13,012评论 0 7

友情链接更多精彩内容