-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathFindPairClosestToTargetNumberInSortedArray.cpp
More file actions
105 lines (87 loc) · 3.3 KB
/
FindPairClosestToTargetNumberInSortedArray.cpp
File metadata and controls
105 lines (87 loc) · 3.3 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
// Given a sorted array find the pair of elements
// in the array whose sum is closest to a target number.
//
// Time Complexity: O(n)
// Space Complexity: O(1)
//
// Complier: Visual Studio 2013 (v120)
#include <iostream>
#include <vector>
#include "CppUnitTest.h"
using namespace std;
using namespace Microsoft::VisualStudio::CppUnitTestFramework;
namespace FindPairClosestToTargetNumberInSortedArray {
// O(n^2) Brute force compare all possible pairs until pair with sum nearest to target is found.
pair<int, int> bruteForce(const vector<int>& v, int target) {
int minDiff{ numeric_limits<int>::max() };
pair<int, int> pair;
for (auto i = 0; i < v.size(); i++) {
for (auto j = i + 1; j < v.size(); j++) {
if (abs(v[i] + v[j] - target) < minDiff) {
minDiff = abs(v[i] + v[j] - target);
pair = make_pair(v[i], v[j]);
}
}
}
return pair;
}
// O(n) Linear method to find pairs whose sum is closest to target number
pair<int, int> findPairSumClosestToTarget(const vector<int>& v, int target) {
int left{ 0 };
auto right = v.size() - 1;
int minDiff{ numeric_limits<int>::max() };
pair<int, int> pair;
while (left < right) {
// Check if sum of the current pair is less than the min difference found so far.
if (abs(v[left] + v[right] - target) < minDiff) {
minDiff = abs(v[left] + v[right] - target);
pair = make_pair(v[left], v[right]);
}
if (v[left] + v[right] > target) {
// The sum is greater than the target so try decreasing it by picking a smaller right number.
right--;
} else {
// The sum less than the target so try increasing it by picking a larger left number
left++;
}
}
return pair;
}
TEST_CLASS(FindPairClosestToTargetNumberInSortedArrayTests) {
public:
TEST_METHOD(WhenPairWithNegatives_ExpectClosestSumChosen) {
auto result = findPairSumClosestToTarget({ 1, 3, 5, 10 }, 4);
Assert::AreEqual(1, result.first);
Assert::AreEqual(3, result.second);
}
TEST_METHOD(WhenPair_ExpectClosestSumChosen) {
auto result = findPairSumClosestToTarget({ -100, -50, -30, 0, 15, 25, 50, 100 }, 40);
Assert::AreEqual(15, result.first);
Assert::AreEqual(25, result.second);
}
};
// Console Test Code
//void displayVector(const vector<int>& v) {
// cout << "[ ";
// for (auto const &item : v) { cout << item << " "; }
// cout << "]" << endl;
//}
// Console Test Code
//void displayPairClosestToTarget(const vector<int>& v, int target) {
// displayVector(v);
// auto bruteForceSolution = bruteForce(v, target);
// cout << "Brute Force solution: [ " << bruteForceSolution.first << " " << bruteForceSolution.second << " ]" << endl;
// auto betterSolution = findPairSumClosestToTarget(v, target);
// cout << "Better solution: [ " << betterSolution.first << " " << betterSolution.second << " ]" << endl;
// cout << endl;
//}
}
// Console Test Code
//int main() {
// FindPairClosestToTargetNumberInSortedArray::displayPairClosestToTarget({ 1, 3, 5, 10 }, 4);
// FindPairClosestToTargetNumberInSortedArray::displayPairClosestToTarget({ -100, -50, -30, 0, 15, 25, 50, 100 }, 40);
//
// cout << endl << "[Press enter to exit]" << endl;
// cin.ignore();
// return 0;
//}