1. 程式人生 > >【劍指】57(1).和為s的兩個數字

【劍指】57(1).和為s的兩個數字

題目描述

  • 輸入一個遞增排序的陣列和一個數字S,在陣列中查詢兩個數,使得他們的和正好是S,如果有多對數字的和等於S,輸出兩個數的乘積最小的。

演算法分析

  • 數列滿足遞增,設兩個頭尾兩個指標i和j,
  1. 若ai + aj == sum,就是答案(相差越遠乘積越小)

  2. 若ai + aj > sum,aj肯定不是答案之一(前面已得出 i 前面的數已是不可能),j -= 1

  3. 若ai + aj < sum,ai肯定不是答案之一(前面已得出 j 後面的數已是不可能),i += 1

提交程式碼:

class Solution {
public:
	vector<int> FindNumbersWithSum(vector<int> array, int sum) {
		if (array.empty())
			return vector<int>();

		vector<int> result;
		auto i = array.cbegin();
		auto j = array.cend() - 1;

		while (i < j)
		{
			if ((*i + *j) > sum)
				--j;
			else if ((*i + *j) < sum)
				++i;
			else
			{
				result.push_back(*i);
				result.push_back(*j);
				break;
			}
		}
		return result;
	}
};

測試程式碼:

// ====================測試程式碼====================
void Test(const char* testName, vector<int> data, int sum, vector<int> expected)
{
	if (testName != nullptr)
		printf("%s begins: ", testName);

	Solution s;
	vector<int> result = s.FindNumbersWithSum(data, sum);
	if (result == expected)
	{
		printf("Passed. \n");
	}
	else
		printf("FAILED. \n");
}

// 存在和為s的兩個數字,這兩個數字位於陣列的中間
void Test1()
{
	vector<int> data = { 1, 2, 4, 7, 11, 15 };
	Test("Test1", data, 15, vector<int>{4, 11});
}

// 存在和為s的兩個數字,這兩個數字位於陣列的兩段
void Test2()
{
	vector<int> data = { 1, 2, 4, 7, 11, 16 };
	Test("Test2", data, 17, vector<int>{1, 16});
}

// 不存在和為s的兩個數字
void Test3()
{
	vector<int> data = { 1, 2, 4, 7, 11, 16 };
	Test("Test3", data, 10, vector<int>());
}

// 魯棒性測試
void Test4()
{
	Test("Test4", vector<int>(), 0, vector<int>());
}

// 包含多個符合條件的情況
void Test5()
{
	vector<int> data = { 0, 2, 4, 7, 11, 16 };
	Test("Test5", data, 11, vector<int>{0, 11});
}

int main(int argc, char* argv[])
{
	Test1();
	Test2();
	Test3();
	Test4();
	Test5();

	return 0;
}