题目

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

输出描述:

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

思考

  • 注意题目的条件:有序数组

    • 对于此题的条件,我们可以将 有序 的条件充分利用起来,是用双向指针解决
  • 扩展,对于一般的无序数组:
    • 是用 hash 表减小查找的复杂度,空间换时间,时间复杂度为 O(n)
    • 可以先将数组排序然后是用双向指针求解,时间复杂度依赖于排序算法,因此最好的情况为 O(nlog(n))

code


#include <iostream>
#include <vector>
#include <algorithm>
#include <unordered_set>
#include <limits>

using namespace std;

class Solution{
public:
    vector<int> FindNumbersWithSum(vector<int> array, int sum){
        //return FindNumbersWithSumHash(array, sum);
        return FindNumbersWithSumSortedArray(array, sum);
    }

    // time-O(n), space-O(1)
    // Note: the array must be sorted array.
    vector<int> FindNumbersWithSumSortedArray(vector<int> array, int sum){

        int left = 0, right = array.size()-1;
        long long minimum = numeric_limits<int>::max();
        int cond1, cond2;
        while(left < right){
            int curSum = array[left] + array[right];
            if(curSum > sum)
                right--;
            if(curSum < sum)
                left++;
            if(curSum == sum){
                long long mul = array[left] * array[right];
                if(mul < minimum){
                    minimum = mul;
                    cond1 = array[left];
                    cond2 = array[right];
                }
                left++; // note: escape the duplication to avoid the infinite loop
            }
        }

        if(minimum == numeric_limits<int>::max()){
            return vector<int>();
        }else{
            vector<int> ans(2);
            ans[0] = cond1;
            ans[1] = cond2;
            return ans;
        }
    }

    // time-O(n) , space-O(n)
    vector<int> FindNumbersWithSumHash(vector<int> array, int sum){
        unordered_set<int> setNums;
        long long minimum = numeric_limits<long long>::max();
        int cond1, cond2;
        for(int n : array){
            int another = sum - n;
            if(setNums.find(another) != setNums.end()){
                if(another * n < minimum){
                    cond1 = n;
                    cond2 = another;
                    minimum = another*n;
                }
            }
            setNums.insert(n);
        }

        if(minimum == numeric_limits<long long>::max()){
            return vector<int>();
        }else{
            if(cond2 < cond1)
                swap(cond1, cond2);
            vector<int> ans(2);
            ans[0] = cond1;
            ans[1] = cond2;
            return ans;
        }

    }
};

int main()
{
    return 0;
}

和为S的两个数的更多相关文章

  1. Java数据结构与算法之---求两个数的最大公约数(欧几里得算法)

    一个简单的小算法来获取两个数的最大公约数, public class Test { public static void main(String[] args) { long result = gcd ...

  2. JavaScript获取两个数之间的任意随机数

    通过JavaScript的Math.random()方法可以获取0到1之间的任意随机数,那如何获取任意给定的两个数之间的随机数呢?如获取2和5之间的随机数,5和10之间的随机数等. 由于Math.ra ...

  3. shell实现两个数的相加

    刚开始的时候写,一直写不对:看似简单的功能,但是一定要小心:函数的定义: funciton functionName {.....}在functionName和{之间一定有空格啊! 我就是没加空格,就 ...

  4. [猜数字]把两个数和告诉A,积告诉B,求这两个数是什么

    1-20的两个数把和告诉A,积告诉B,A说不知道是多少,B也说不知道,这时A说我知道了,B接着说我也知道了,问这两个数是多少? 分析: 设和为S,积为M. 首先,A:我不知道. 说明:S可以分解成多个 ...

  5. java课后作业 弹出窗口求两个数的加减乘除

    //计算2个数的加减乘除 谷伟华 2015/10/6package jisuan; import javax.swing.JOptionPane; public class Jiasuan { pub ...

  6. 创建一个LinkedList,然后在其中插入多个值,确保每个值都插入到List中间(偶数中间两个数之一,奇数在正中间)

    这是Thinking in java 中的一道题,下面是我的解决方案: package test; import java.util.LinkedList; import java.util.List ...

  7. 求两个数的最大公约数(Java)

    获得两个随机数(100以内),并放入数组中 public int[] getTwoRandom(){ int[] t = new int[2]; Random rand = new Random(); ...

  8. 和为S的两个数VS和为S的连续正数序列

    其实这个题目如果没有限制时间复杂度的话,那么就很简单了,一遍一遍地扫描吧.时间复杂度肯定就是 O(n2)啰.但是这题目肯定不会这么简单,否则就是小学生的水平了嘛. 其实我刚到这题的时候想到的是用二叉查 ...

  9. C实现辗转相除法求两个数的最大公约数

    什么是辗转相除法? 辗转相除法(又名欧几里德算法),它主要用于求两个正整数的最大公约数.是已知的最古老的算法. 用辗转相除法求132和72的最大公约数的步骤: 132 / 72 = 1 ... 60 ...

  10. java 判断两个数是否异号

    java 整型int占4个字节32位,两个数异或后移动31位判断结果,如果是1则异号,如果是0则同号 public class ShowEnviromentViarible { public stat ...

随机推荐

  1. 【运维】CPU负载

    最近对我的本本(4核8线程)用top命令看系统状况出现了CPU利用率超过200%的情况,非常诧异,查了下相关资料,把这个问题弄清楚了.首先来分析下CPU Load load average: 0.09 ...

  2. 关于高德地图Android开发时地图只显示一次、第二次打开不定位的解决办法

    我按照高德官方Demo改的 第一次是可以定位的,如左图 第二次就不能定位了,如右图 在onDestory中把aMap置为空即可 aMap = null; 修改完如下图: 原理是第二次打开时aMap不为 ...

  3. D. Mysterious Present (看到的一个神奇的DP,也可以说是dfs)

    D. Mysterious Present time limit per test 2 seconds memory limit per test 64 megabytes input standar ...

  4. Judge Route Circle

    Initially, there is a Robot at position (0, 0). Given a sequence of its moves, judge if this robot m ...

  5. 20.Linux-USB鼠标驱动

    在上一章分析完USB总线驱动程序后, 接下来开始写一个USB驱动: 本节目的: 将USB鼠标的左键当作L按键,将USB鼠标的右键当作S按键,中键当作回车按键 参考/drivers/hid/usbhid ...

  6. 系统出现异常: too many values to unpack (expected 2)

    先感谢[ValueError: too many values to unpack](http://leonzhan.iteye.com/blog/1720315)系统出现异常:打开太多值(预期2)这 ...

  7. vs 或 Sql server2012连接Sql server时出现的问题:已成功与服务器建立连接,但在登陆过程中发生错误

    以前连接是正常的,就这两天连不上了.(没有耐心的直接看末尾解决办法) 错误消息如下: 1.尝试读取或写入受保护的内存.这通常指示其他内存已损坏.(System.Data) 2.已成功与服务器建立连接, ...

  8. 详解m4文件

    最近在分析speex代码,发现编译过程中需要的一个speex.m4文件不知道是何方神圣,怀着对未知知识的渴望,跑到 某哥和某基问了一下,算是认识了,为了方便以后经常见面,这里就做个记录吧. M4实际上 ...

  9. DotNetCore跨平台~配置文件与配置代码如何共存

    回到目录 古人云<一山不容二虎>,而进行dotnet core时代之后,我们可以看到这样的一些官方的DEMO,它将数据连接串和其它配置项都直接硬编码在代码里,即在startup中进行定义, ...

  10. 举例:使用XML库的方式,实现RPC通信

    1.先说结论:使用xml-rpc的机制可以很方便的实现服务器间的RPC调用. 2.试验结果如下: 3.源码如下: 服务器端的源代码如下: import operator, math from Simp ...