023 和爲S的兩個數字(keep it up)

劍指offer中題目:http://ac.jobdu.com/problem.php?pid=1352

題目描述:

輸入一個遞增排序的數組和一個數字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





發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章