【劍指】57(1).和為s的兩個數字
阿新 • • 發佈:2019-01-04
題目描述
- 輸入一個遞增排序的陣列和一個數字S,在陣列中查詢兩個數,使得他們的和正好是S,如果有多對數字的和等於S,輸出兩個數的乘積最小的。
演算法分析
- 數列滿足遞增,設兩個頭尾兩個指標i和j,
-
若ai + aj == sum,就是答案(相差越遠乘積越小)
-
若ai + aj > sum,aj肯定不是答案之一(前面已得出 i 前面的數已是不可能),j -= 1
-
若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; }