题目

输入一个递增排序的数组和一个数字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. [js高手之路] html5 canvas系列教程 - 线形渐变,径向渐变与阴影设置

    接着上文[js高手之路] html5 canvas系列教程 - 像素操作(反色,黑白,亮度,复古,蒙版,透明)继续. 一.线形渐变 线形渐变指的是一条直线上发生的渐变. 用法: var linear ...

  2. jdk版本查看,以及java -version 和JAVA_HOME不一致问题

    一.jdk版本查看及位数查看 在cmd进入命令行窗口,输入java -version 可以查看安装的jdk版本,如图: 当有64-bit时代表是64位jdk,如果没有则默认是32位的. 二.java ...

  3. hdu1754线段树的单点更新区间查询

    I Hate It Time Limit: 9000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total ...

  4. P1034

    问题 E: P1034 时间限制: 1 Sec  内存限制: 128 MB提交: 29  解决: 22[提交][状态][讨论版] 题目描述 尼克每天上班之前都连接上英特网,接收他的上司发来的邮件,这些 ...

  5. 搭建dubbo+zookeeper+dubboadmin分布式服务框架(windows平台下)

    1.zookeeper注册中心的配置安装 1.1 下载zookeeper包(zookeeper-3.4.6.tar.gz),ZooKeeper是一个分布式的,开放源码的分布式应用程序协调服务,是Goo ...

  6. input中range相关操作

    利用mousover触发函数对range的操作练习 <!DOCTYPE html> <html> <head> <meta charset="utf ...

  7. node-Telnet

    什么是Telnet(window系统) 使用Telnet工具作为客户端对创建的TCP服务器进行会话交流时遇到的问题做一个简单的记录.希望可以帮助到一些同学. 这里看一下百度词条的解释 Telnet协议 ...

  8. swoole 入门

    1. 概述 Swoole是PHP的一个扩展,但是它与普通的扩展不同,普通的扩展知识提供一个库函数,而Swoole扩展在运行后会接管PHP的控制器,进入时间循环.当IO时间发生后,Swoole会自动回调 ...

  9. 解决-Dmaven.multiModuleProjectDirectory system property is not set. Check $M2_HO问题

    原因:因为你的编译工具(eclipse/Myeclipse...)没有添加jdk.添加M2_HOME的环境变量. 解决: ①:window->Preferences->java->I ...

  10. html加载时事件触发顺序

    一般情况下页面的响应加载顺序时,域名解析-加载html-加载js和css-加载图片等其他信息. jq ready()的方法就是Dom Ready,他的作用或者意义就是:在DOM加载完成后就可以可以对D ...