Skip to content

Commit c1e76e4

Browse files
committed
Day-59 Max Subarray prob and CTCI prob 2
1 parent e15e21f commit c1e76e4

File tree

3 files changed

+303
-3
lines changed

3 files changed

+303
-3
lines changed

README.md

+5-3
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,9 @@
66

77
| Current Status| Stats |
88
| :------------: | :----------: |
9-
| Total Problems | 82 |
10-
| Current Streak | 58 |
11-
| Longest Streak | 58 ( August 17, 2015 - October 13, 2015 ) |
9+
| Total Problems | 84 |
10+
| Current Streak | 59 days |
11+
| Longest Streak | 59 ( August 17, 2015 - October 14, 2015 ) |
1212

1313
</center>
1414

@@ -83,12 +83,14 @@ Include contains single header implementation of data structures and some algori
8383
| Problem 1-8: Write an algorithm such that if an element of MxN matrix is 0, its entire row and column is set to 0. | [1-8-zero-matrix.cpp](cracking_the_coding_interview_problems/1-8-zero-matrix.cpp)|
8484
| Problem 1-9: Given two strings s1 and s2, determine s2 is rotation of s1 using only one call to a function which checks whether one string is rotation of another.|[1-9-string-rotation.cpp](cracking_the_coding_interview_problems/1-9-string-rotation.cpp)|
8585
| Problem 2-1: Remove duplicates from an *unsorted* linked list. What if no temporary buffer is allowed.|[2-1-remove-dups.cpp](cracking_the_coding_interview_problems/2-1-remove-dups.cpp)|
86+
| Problem 2-2: Determine k<sup>th</sup> node from the last of a singly linked list. (Iterative and Recursive Approaches) | [2-2-kthToLast.cpp](cracking_the_coding_interview_problems/2-2-kthToLast.cpp)|
8687

8788
###Dynamic Programming Problems
8889
| Problem | Solution |
8990
| :------------ | :----------: |
9091
| N<sup>th</sup> Fibonacci term using different memoization techniques | [fibonacci.cpp](dynamic_programming_problems/fibonacci.cpp)|
9192
| Longest Common Subsequence Problem | [lcs.cpp](dynamic_programming_problems/lcs.cpp) |
93+
| Maximum Value Contigous Subsequence Problem [wiki](https://en.wikipedia.org/wiki/Maximum_subarray_problem)| [max_subsequence.cpp](dynamic_programming_problems/max_subsequence.cpp)|
9294

9395
### Tree Problems
9496
| Problem | Solution |
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,161 @@
1+
/**
2+
* Cracking the coding interview edition 6
3+
* Problem 2.2
4+
* Return kth to last
5+
* Implement an algorithm to find the kth to last element of a singly linked list.
6+
* We can assume we are not provided the length of the list.
7+
*
8+
* Approaches:
9+
* 1. Iterative:
10+
* Use two pointers
11+
* Move first pointer k places.
12+
* Now move second pointer(from start) and first pointer (from k+1) simultanously.
13+
* When second pointer would have reached end, first pointer would be at kth node.
14+
*
15+
* 2. Recursive:
16+
* Maintain an index to keep track of node.
17+
* Solve the problem for n-1 nodes and add 1 to index.
18+
* Since each parent call is adding 1, when counter reaches k,
19+
* we have reached length-k node from start, which is kth node from last.
20+
*/
21+
22+
#include <iostream>
23+
24+
struct Node {
25+
int data;
26+
Node * next;
27+
Node(int d) : data{ d }, next{ nullptr } { }
28+
};
29+
30+
31+
/**
32+
* Insert to the head of the list
33+
* @param head - Current head of list
34+
* @param data - new node's data
35+
*/
36+
void insert( Node * & head, int data ) {
37+
Node * newNode = new Node(data);
38+
newNode->next = head;
39+
head = newNode;
40+
}
41+
42+
/**
43+
* [deleteList - delete the entire list]
44+
* @param head - head of the list
45+
*/
46+
void deleteList( Node * & head ) {
47+
Node * nextNode;
48+
while(head) {
49+
nextNode = head->next;
50+
delete(head);
51+
head = nextNode;
52+
}
53+
}
54+
55+
/**
56+
* printList - Print the list
57+
* @param head - Current head of the list.
58+
*/
59+
void printList( Node * head ) {
60+
while(head) {
61+
std::cout << head->data << "-->";
62+
head = head->next;
63+
}
64+
std::cout << "null" << std::endl;
65+
}
66+
67+
/**
68+
* [kthToLastHelper - helper routine to find nth node for recursive approach
69+
* @param head - head of the list
70+
* @param k - the k value for finding kth element from last of the list.
71+
* @param i - an index maintained to keep track of current node.
72+
* @return - kth node from last.
73+
*/
74+
Node * kthToLastHelper( Node * head, int k , int & i) {
75+
if ( head == nullptr ) {
76+
return nullptr;
77+
}
78+
79+
Node * node = kthToLastHelper(head->next, k, i);
80+
i = i + 1;
81+
//if we have solved problem k times from last.
82+
if ( i == k ) {
83+
return head;
84+
}
85+
return node;
86+
}
87+
88+
/**
89+
* kthToLastRecursive - Recursive approach for finding kth to last element of list.
90+
* @param head - head of node
91+
* @param k - the k value for finding kth element from last of the list.
92+
* @return - kth node from last.
93+
*/
94+
Node * kthToLastRecursive( Node * head, int k ) {
95+
int i = 0;
96+
return kthToLastHelper(head, k, i);
97+
}
98+
99+
/**
100+
* kthToLastIterative - Iterative approach for finding kth to last element of list.
101+
* @param head - head of node
102+
* @param k - the k value for finding kth element from last of the list.
103+
* @return - kth node from last.
104+
*/
105+
Node * kthToLastIterative( Node * head, int k ) {
106+
if ( head == nullptr ) {
107+
return head;
108+
}
109+
110+
Node * ptr1 = head;
111+
Node * ptr2 = head;
112+
113+
int i = 0;
114+
while( i < k && ptr1 ) {
115+
ptr1 = ptr1->next;
116+
++i;
117+
}
118+
119+
//out of bounds
120+
if ( i < k ) {
121+
return nullptr;
122+
}
123+
124+
while( ptr1 != nullptr ) {
125+
ptr1 = ptr1->next;
126+
ptr2 = ptr2->next;
127+
}
128+
129+
return ptr2;
130+
}
131+
132+
133+
134+
int main() {
135+
Node * head = nullptr;
136+
for ( int i = 7; i > 0; i-- ) {
137+
insert(head, i);
138+
}
139+
std::cout << "List: ";
140+
printList(head);
141+
142+
std::cout << "4th node from last (Recursive) : ";
143+
Node *node4 = kthToLastRecursive(head, 4);
144+
if ( node4 != nullptr ) {
145+
std::cout << node4->data << std::endl;
146+
} else {
147+
std::cout << "NULL NODE\n";
148+
}
149+
150+
std::cout << "4th node from last (Iterative) : ";
151+
node4 = kthToLastIterative(head, 4);
152+
if ( node4 != nullptr ) {
153+
std::cout << node4->data << std::endl;
154+
} else {
155+
std::cout << "NULL NODE\n";
156+
}
157+
158+
deleteList(head);
159+
160+
return 0;
161+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
/**
2+
* Maximum Value Contiguous Subsequence
3+
* Given an array of n numbers, give an algorithm for finding a contigous
4+
* subsequence A(i)...A(j) for which the sum of elements is maximum.
5+
* Example - { -2, 11, -4, 13, -5, 2} --> 20 i.e. { 11, -4, 13}
6+
* Example - { 1, -3, 4, -2, -1, 6} --> 7 { 4, -2, -1, 6}
7+
*
8+
* Approach :
9+
* For selecting an ith element, we have to make a decision
10+
* - Add it to the old sum M(i-1) + A[i]
11+
* - or start the new window with one element A[i]
12+
*
13+
* We will use above approach in solving it with O(n) space and with O(1) space (Kadane's approach).
14+
* Special Case:
15+
* If all the elements are positive then, we the Maximum Value Contigous Subsequence would be the entire set
16+
*
17+
*/
18+
19+
20+
#include <iostream>
21+
#include <vector>
22+
#include <algorithm>
23+
#include <limits>
24+
25+
//approach one using O(n) space.
26+
int max_contigous_subsequence_sum( const std::vector<int> & v ) {
27+
28+
//special case when all the elements are negative.
29+
bool allNegativeOrZero = true;
30+
int maxSum = std::numeric_limits<int>::min();
31+
for ( size_t i = 0; i < v.size(); ++i ) {
32+
if ( v[i] > 0 ) {
33+
allNegativeOrZero = false;
34+
}
35+
if (v[i] > maxSum) {
36+
maxSum = v[i];
37+
}
38+
}
39+
40+
if (allNegativeOrZero) {
41+
return maxSum;
42+
}
43+
44+
maxSum = 0;
45+
46+
std::vector<int> M(v.size(), 0);
47+
if (v[0] > 0) {
48+
M[0] = v[0];
49+
}
50+
for (size_t i = 1; i < v.size(); ++i) {
51+
if ( M[i-1] + v[i] > 0 ) {
52+
M[i] = M[i-1] + v[i];
53+
} else {
54+
M[i] = 0;
55+
}
56+
}
57+
for ( size_t i = 0; i < v.size(); ++i ) {
58+
if (M[i] > maxSum) {
59+
maxSum = M[i];
60+
}
61+
}
62+
return maxSum;
63+
}
64+
65+
//approach two
66+
// Kadane's algorithm.
67+
// Since we care about sum till i-1 for calculating i
68+
// and we need to pick the maximum of all the sums eventully,
69+
// We don't really need an array to store sums.
70+
// We have to take care of special case when array contains only negative nums.
71+
int max_contigous_subsequence_sum2( std::vector<int> & v ) {
72+
int max_so_far = std::numeric_limits<int>::min();
73+
int sum_so_far = 0;
74+
75+
//special case all negative or zero
76+
bool allNegativeOrZero = true;
77+
for ( size_t i = 0; i < v.size(); ++i ) {
78+
if ( v[i] > 0 ) {
79+
allNegativeOrZero = false;
80+
}
81+
if ( v[i] > max_so_far ) {
82+
max_so_far = v[i];
83+
}
84+
}
85+
if (allNegativeOrZero) {
86+
return max_so_far;
87+
}
88+
89+
//case 2 normal case;
90+
max_so_far = 0;
91+
for ( size_t i = 0; i < v.size(); ++i ) {
92+
sum_so_far += v[i];
93+
if ( sum_so_far < 0 ) {
94+
sum_so_far = 0;
95+
}
96+
if ( max_so_far < sum_so_far ) {
97+
max_so_far = sum_so_far;
98+
}
99+
}
100+
return max_so_far;
101+
}
102+
103+
104+
void printVec(const std::vector<int> & vec) {
105+
for(auto x : vec) {
106+
std::cout << x << " ";
107+
}
108+
std::cout << std::endl;
109+
}
110+
111+
int main()
112+
{
113+
std::vector<int> vec{ -2, 11, -4, 13, -5, 2};
114+
std::cout << "Vector: ";
115+
printVec(vec);
116+
std::cout << "Sum of Maximum Contiguous Subarray for above vector is : "
117+
<< max_contigous_subsequence_sum(vec) << std::endl;
118+
119+
std::vector<int> vec1{ -2, -1, -4, -3, -5, -2};
120+
std::cout << " Special Vector: ";
121+
printVec(vec1);
122+
std::cout << "Sum of Maximum Contiguous Subarray for above vector is : "
123+
<< max_contigous_subsequence_sum(vec1) << std::endl;
124+
125+
std::vector<int> vec2{ -200, -100, -50, -70, -500, -51};
126+
std::cout << " Special Vector: ";
127+
printVec(vec2);
128+
std::cout << "Sum of Maximum Contiguous Subarray for above vector is : "
129+
<< max_contigous_subsequence_sum(vec2) << std::endl;
130+
131+
std::vector<int> vec3{ 1, -3, 4, -2, -1, 6 };
132+
std::cout << "Vector: ";
133+
printVec(vec3);
134+
std::cout << "Sum of Maximum Contiguous Subarray for above vector is : "
135+
<< max_contigous_subsequence_sum(vec3) << std::endl;
136+
return 0;
137+
}

0 commit comments

Comments
 (0)