-
Notifications
You must be signed in to change notification settings - Fork 1.3k
/
max_subsequence.cpp
137 lines (121 loc) · 3.61 KB
/
max_subsequence.cpp
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
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
/**
* Maximum Value Contiguous Subsequence
* Given an array of n numbers, give an algorithm for finding a contigous
* subsequence A(i)...A(j) for which the sum of elements is maximum.
* Example - { -2, 11, -4, 13, -5, 2} --> 20 i.e. { 11, -4, 13}
* Example - { 1, -3, 4, -2, -1, 6} --> 7 { 4, -2, -1, 6}
*
* Approach :
* For selecting an ith element, we have to make a decision
* - Add it to the old sum M(i-1) + A[i]
* - or start the new window with one element A[i]
*
* We will use above approach in solving it with O(n) space and with O(1) space (Kadane's approach).
* Special Case:
* If all the elements are positive then, we the Maximum Value Contigous Subsequence would be the entire set
*
*/
#include <iostream>
#include <vector>
#include <algorithm>
#include <limits>
//approach one using O(n) space.
int max_contigous_subsequence_sum( const std::vector<int> & v ) {
//special case when all the elements are negative.
bool allNegativeOrZero = true;
int maxSum = std::numeric_limits<int>::min();
for ( size_t i = 0; i < v.size(); ++i ) {
if ( v[i] > 0 ) {
allNegativeOrZero = false;
}
if (v[i] > maxSum) {
maxSum = v[i];
}
}
if (allNegativeOrZero) {
return maxSum;
}
maxSum = 0;
std::vector<int> M(v.size(), 0);
if (v[0] > 0) {
M[0] = v[0];
}
for (size_t i = 1; i < v.size(); ++i) {
if ( M[i-1] + v[i] > 0 ) {
M[i] = M[i-1] + v[i];
} else {
M[i] = 0;
}
}
for ( size_t i = 0; i < v.size(); ++i ) {
if (M[i] > maxSum) {
maxSum = M[i];
}
}
return maxSum;
}
//approach two
// Kadane's algorithm.
// Since we care about sum till i-1 for calculating i
// and we need to pick the maximum of all the sums eventully,
// We don't really need an array to store sums.
// We have to take care of special case when array contains only negative nums.
int max_contigous_subsequence_sum2( std::vector<int> & v ) {
int max_so_far = std::numeric_limits<int>::min();
int sum_so_far = 0;
//special case all negative or zero
bool allNegativeOrZero = true;
for ( size_t i = 0; i < v.size(); ++i ) {
if ( v[i] > 0 ) {
allNegativeOrZero = false;
}
if ( v[i] > max_so_far ) {
max_so_far = v[i];
}
}
if (allNegativeOrZero) {
return max_so_far;
}
//case 2 normal case;
max_so_far = 0;
for ( size_t i = 0; i < v.size(); ++i ) {
sum_so_far += v[i];
if ( sum_so_far < 0 ) {
sum_so_far = 0;
}
if ( max_so_far < sum_so_far ) {
max_so_far = sum_so_far;
}
}
return max_so_far;
}
void printVec(const std::vector<int> & vec) {
for(auto x : vec) {
std::cout << x << " ";
}
std::cout << std::endl;
}
int main()
{
std::vector<int> vec{ -2, 11, -4, 13, -5, 2};
std::cout << "Vector: ";
printVec(vec);
std::cout << "Sum of Maximum Contiguous Subarray for above vector is : "
<< max_contigous_subsequence_sum(vec) << std::endl;
std::vector<int> vec1{ -2, -1, -4, -3, -5, -2};
std::cout << " Special Vector: ";
printVec(vec1);
std::cout << "Sum of Maximum Contiguous Subarray for above vector is : "
<< max_contigous_subsequence_sum(vec1) << std::endl;
std::vector<int> vec2{ -200, -100, -50, -70, -500, -51};
std::cout << " Special Vector: ";
printVec(vec2);
std::cout << "Sum of Maximum Contiguous Subarray for above vector is : "
<< max_contigous_subsequence_sum(vec2) << std::endl;
std::vector<int> vec3{ 1, -3, 4, -2, -1, 6 };
std::cout << "Vector: ";
printVec(vec3);
std::cout << "Sum of Maximum Contiguous Subarray for above vector is : "
<< max_contigous_subsequence_sum(vec3) << std::endl;
return 0;
}