题目

输入一个递增排序的数组和一个数字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. DIY智能家居——零基础入门篇

    概要 本文主要根据笔者从零开始接触硬件,以小白视角开启IoT探索,根据相关资料DIY一个温湿度传感器.后经过探索发现新大陆--Home Assistant&Homebridge,最终实现了一个 ...

  2. UI自动化测试简介及Selenium工具的介绍和环境搭建

    自动化测试简介 1.1何为自动化测试? 是把以人为驱动的测试转化为机器执行的一种过程,它是一种以程序测试程序的过程.换言之,就是以程序实现的方式来代替手工测试. 1.2自动化测试分类 分为功能自动化测 ...

  3. hdu 4090--GemAnd Prince(搜索)

    题目链接 Problem Description Nowadays princess Claire wants one more guard and posts the ads throughout ...

  4. ClassLoader类加载机制&&JVM内存管理

    一.ClassLoader类加载机制 在java中类加载是遵循委派双亲加载的:通过调用loadClass方法逐级往上传递委派加载请求,当找不到父ClassLoader时调用其findClass方法尝试 ...

  5. android6.0 SerialPort 服务

    上一篇博客描述了一个简单的串口应用程序和驱动程序,了解了应用程序访问串口的基本操作,如打开串口,设置串口,写串口,读串口,关闭串口等.和Linux串口驱动的基本框架.这里将了解Android下的串口系 ...

  6. Golang:使用 httprouter 构建 API 服务器

    https://medium.com/@gauravsingharoy/build-your-first-api-server-with-httprouter-in-golang-732b7b01f6 ...

  7. 25.Linux-Nor Flash驱动(详解)

    1.nor硬件介绍: 从原理图中我们能看到NOR FLASH有地址线,有数据线,它和我们的SDRAM接口相似,能直接读取数据,但是不能像SDRAM直接写入数据,需要有命令才行 1.1其中我们2440的 ...

  8. 探索equals()和hashCode()方法

    探索equals()和hashCode()方法 在根类Object中,实现了equals()和hashCode()这两个方法,默认: equals()是对两个对象的地址值进行的比较(即比较引用是否相同 ...

  9. MySql采用GROUP_CONCAT合并多条数据显示的方法

    情况分析: 1. 表course id     name 1      课程一 ================= 2.表course_teacher id   course_id  teacher_ ...

  10. LeetCode 572. Subtree of Another Tree (是否是另一个树的子树)

    Given two non-empty binary trees s and t, check whether tree t has exactly the same structure and no ...