023 和为S的两个数字(keep it up)

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

每个测试案例包括两行:

第一行包含一个整数n和k,n表示数组中的元素个数,k表示两数之和。其中1 <= n <= 10^6,k为int

第二行包含n个整数,每个数组均为int类型。

输出:
对应每个测试案例,输出两个数,小的先输出。如果找不到,则输出“-1 -1”
样例输入:
6 15
1 2 4 7 11 15
样例输出:
4 11

看到这题首先想到的是暴力解决,可是N的大小为100万,暴力算法可能超时,有没有o(n)的算法呢?

题目中输入的数据时有序递增的,而且是找两个数,很快想到快速排序的算法,一般这种有序的数都可以借鉴排序算法(三个while循环):

1首先我们判断array[low] + array[height] < k,那么low就一直加1,并且保证low < height

2然后判断array[low]+array[height] > k,那么height就一直减1,并且保证 low < height

3判段 array[low] + array[height] == k,等于就返回1,表示找到了,否则继续

呵呵,是不是和快排的思想一样。

下面是代码:

#include <stdio.h>
#include <stdlib.h>

#define MaxSize 1000000
int Array[MaxSize];

int findMinTwoNumber(int vK, int vN, int *vLeft, int *vRight)
{
	if (vN < 2) return 0;

	int Low, Hight;

	Low   = 0;
	Hight = vN-1;

	while (Low < Hight)
	{
		while (Array[Low] + Array[Hight] < vK && Low < Hight) ++Low;
		while (Array[Low] + Array[Hight] > vK && Low < Hight) --Hight;

		if (Array[Low] + Array[Hight] == vK && Low < Hight)
		{
			*vLeft  = Low;
			*vRight = Hight;
			return 1;
		}
	}

	return 0;
}

int main()
{
	int K, N, i, Ret, Left, Right;

	while (scanf("%d %d", &N, &K) != EOF)
	{
		for (i = 0; i < N; ++i)
		{
			scanf("%d", &Array[i]);
		}

		Ret = findMinTwoNumber(K, N, &Left, &Right);

		if (Ret)
		{
			printf("%d %d\n", Array[Left], Array[Right]);
		}
		else
		{
			printf("-1 -1\n");
		}
	}

	//system("pause");

	return 0;
}

http://blog.csdn.net/xiaoliangsky/article/details/40901373

http://ac.jobdu.com/problem.php?pid=1352

时间: 2024-08-05 23:12:38

023 和为S的两个数字(keep it up)的相关文章

使用SHELL完成两个数字的大小比较

简要说明: 提示用户输入两个数字: 判断输入的内容是否都为数字: 数字做计算并反馈结果: 计算完毕后询问客户是否继续使用: 给用户提供随时退出的方法. [[email protected] scripts]# cat jisuan2.sh #!/bin/bash ###thank_oldboy ###2016/3/6 ###i wish you all the best. . /etc/init.d/functions ### read number. function read_number(

程序员面试100题之十:快速找出一个数组中的两个数字,让这两个数字之和等于一个给定的值(转)

能否快速找出一个数组中的两个数字,让这两个数字之和等于一个给定的值,为了简化起见,我们假设这个数组中肯定存在至少一组符合要求的解. 假如有如下的两个数组,如图所示: 5,6,1,4,7,9,8 给定Sum= 10 1,5,6,7,8,9 给定Sum= 10 分析与解法 这个题目不是很难,也很容易理解.但是要得出高效率的解法,还是需要一番思考的. 解法一 一个直接的解法就是穷举:从数组中任意取出两个数字,计算两者之和是否为给定的数字. 显然其时间复杂度为N(N-1)/2即O(N^2).这个算法很简

和为s的两个数字

牛客上要求返回乘积最小的,实际上不用麻烦去写另外一个函数,第一次找到两个数字的乘积就一定是最小的. 在调试程序时也遇到两个问题: 1.既然用到了vector容器,头文件就应该声明#include<vector> 2.vector的初始化的一种方式: int b[] = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20};    vector<int> base(b,b+20); class Solution { public:

编程算法 - 和为s的两个数字 代码(C)

和为s的两个数字 代码(C) 本文地址: http://blog.csdn.net/caroline_wendy 题目: 输入一个递增排序的数组和一个数字s, 在数组中查找两个数, 使得它们的和正好是s. 假设有多对数字的和等于s, 输出随意一对就可以. 排序数组, 则能够从两端(即最大值, 最小值)開始进行查找, 当和大于时, 则降低前端, 当和小于时, 则递增尾端. 时间复杂度O(n). 代码: /* * main.cpp * * Created on: 2014.6.12 * Author

golang取两个数字之间的随机数

//取两个数字之间的随机数int64 func RandInt64(min, max int64) int64 { if min > max { return max } return rand.New(rand.NewSource(min)).Int63n(max) }

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

题目:输入一个递增排序的数组和一个数字s,在数组中查找两个数,使得它们的和正好是s.如果有多对数字的和等于s,输出任意一对即可. 思路:最初我们找到数组的第一个数字和最后一个数字.首先定义两个指针,第一个指针指向数组的第一个(也就是最小的)数字,第二个指针指向数组的最后一个(也就是最大的)数字.当两个数字的和大于输入的数字时,把较大的数字往前移动:当两个数字的和小于数字时,把较小的数字往后移动:当相等时,打完收工.这样扫描的顺序是从数组的两端向数组的中间扫描. #include "stdafx.

为什么计算机只有0和1两个数字啊?

为什么计算机只有0和1两个数字啊? 当前的计算机系统使用的基本上是二进制系统,数据在计算机中主要是以补码的形式存储的.计算机中的二进制则是一个非常微小的开关,用“开”来表示1,“关”来表示0. 在数字世界里没有电影.没有杂志.没有一首首的乐曲,只有一个个的数字“1”和“0”.以前人们对于数字世界中的这两个数字还不知道如何命名,直到现1946年普林斯顿大学的统计学家约翰.土吉(john turkey)把它定为进制,才有了比特(Bit)这一术语.比特是电脑当中最小的单位(0或1),1MB=1024K

经典算法学习——快速找出数组中两个数字,相加等于某特定值

这个算法题的描述如下:快速找出一个数组中的两个数字,让这两个数字之和等于一个给定的值.目前我假设数组中的都是各不相等的整数.这道题是我在一次面试中被问到的,由于各种原因,我没回答上来,十分尴尬.其实这道题十分简单,我们使用相对巧妙的方法来实现下.注意不使用两层循环的元素遍历.示例代码上传至:https://github.com/chenyufeng1991/SumTo100 . 算法描述如下: (0)首先对原数组进行排序,成为递增数组: (1)对排序后的数组头部i [0]和数组尾部j [n-1]

Python算法题----在列表中找到和为s的两个数字

列表data的值为[1, 3, 4, 5, 8, 9, 11],找出这个列表中和为13的两个数字的所有组合.这个好找,上过幼儿园大班的,估计都能找出来.4+9=13, 5+8=13.如何用python写一个函数来实现呢. 解法一: 超级大循环 最容易想到的就是遍历啊.嵌套循环,外层循环遍历全部列表,内层循环遍历当前元素位置之后的所有元素.内层循环中将两个数字相加,等于13就break.妥妥找到. def equalSum01(data=None, twosum=13):     result =