Compare commits

...

3 Commits

7 changed files with 284 additions and 24 deletions

View File

@@ -44,13 +44,13 @@ To run the tests:
#+end_src #+end_src
* Plan * Plan
** Arrays [2/6] ** Arrays [3/6]
- [X] Is Unique (CTCI: 1.1) - [X] Is Unique (CTCI: 1.1)
- [X] Check permutation (CTCI: 1.2) - [X] Check permutation (CTCI: 1.2)
- [ ] String Compression (CTCI: 1.6) - [ ] String Compression (CTCI: 1.6)
- [ ] Rotate Matrix (CTCI: 1.7) - [ ] Rotate Matrix (CTCI: 1.7)
- [ ] Zero Matrix (CTCI: 1.8) - [ ] Zero Matrix (CTCI: 1.8)
- [ ] Sliding Window ([[https://www.geeksforgeeks.org/window-sliding-technique/][GfG: Sliding Window Technique]]) - [X] Sliding Window ([[https://www.geeksforgeeks.org/window-sliding-technique/][GfG: Sliding Window Technique]])
** Linked Lists [1/6] ** Linked Lists [1/6]
- [X] Remove Duplicates (CTCI: 2.1) - [X] Remove Duplicates (CTCI: 2.1)
- [ ] Return Kth to Last (CTCI: 2.2) - [ ] Return Kth to Last (CTCI: 2.2)
@@ -60,15 +60,15 @@ To run the tests:
** Stacks and Queues [0/2] ** Stacks and Queues [0/2]
- [ ] Stack Min (CTCI: 3.1) - [ ] Stack Min (CTCI: 3.1)
- [ ] Sort Stack (CTCI: 3.5) - [ ] Sort Stack (CTCI: 3.5)
** Trees and Graphs [4/9] ** Trees and Graphs [7/9]
- [X] Implement binary tree object - [X] Implement binary tree object
- Insert breadth first - Insert breadth first
- [X] Recursive Pre-order traversal - [X] Recursive Pre-order traversal
- [X] Recursive In-order traversal - [X] Recursive In-order traversal
- [X] Recursive Post-order traversal - [X] Recursive Post-order traversal
- [ ] Non-Recursive Pre-order traversal - [X] Non-Recursive Pre-order traversal
- [ ] Non-Recursive In-order traversal - [X] Non-Recursive In-order traversal
- [ ] Non-Recursive Post-order traversal - [X] Non-Recursive Post-order traversal
- [ ] Min Heap - [ ] Min Heap
- [ ] Binary Search - [ ] Binary Search
** C/C++ [2/5] ** C/C++ [2/5]

View File

@@ -4,3 +4,5 @@
bool IsUnique(const char* s, int len); bool IsUnique(const char* s, int len);
bool CheckPermutation(const char* s1, const char* s2, size_t s1_len, size_t s2_len); bool CheckPermutation(const char* s1, const char* s2, size_t s1_len, size_t s2_len);
int sliding_window_max_sum(int* array, int len, int k_len);
int sliding_window_shortest_subarray(int* array,int len, int x);

View File

@@ -1,5 +1,6 @@
chapter1_sources = ['is_unique.cpp', 'check_permutation.cpp'] chapter1_sources = ['is_unique.cpp', 'check_permutation.cpp',
'sliding_window.cpp']
chapter1_lib = static_library('chapter1', chapter1_lib = static_library('chapter1',
chapter1_sources) chapter1_sources)

View File

@@ -0,0 +1,82 @@
#include "chapter1.hpp"
/**
* \brief sliding_window_max_sum
*
* Detailed description
*
* \param array The input array
* \param len The length of the input array
* \param k_len The length of the subarray
* \return return int The maximum found in the subarray
*/
int sliding_window_max_sum(int* array, int len, int k_len){
int current_max = 0;
int* window_beg = array;
int* window_end = (array + k_len);
int previous_beg = 0;
// initial sum
for (int i = 0; i < k_len; i++){
current_max += array[i];
}
previous_beg = *window_beg;
window_beg += 1;
window_end += 1;
// iterate window
int current_sum = current_max;
while(window_end != (array + len - 1)){
current_sum = current_sum - previous_beg + *window_end;
if (current_sum > current_max){
current_max = current_sum;
}
previous_beg = *window_beg;
window_beg += 1;
window_end += 1;
}
return current_max;
}
/**
* \brief sliding_window_shortest_subarray
*
* Find the shortest subarray that is greater than or equal to x.
*
* \param array The intput array
* \param len The length of the input array
* \param x The threshold to compare to
* \return return the length of the shortest subarray
*/
int sliding_window_shortest_subarray(int* array,int len, int x){
int* window_beg = &array[0];
int* window_end = &array[1];
int current_sum = array[0] + array[1];
int min_len = len;
int sub_array_len = len;
while(window_beg != (array + len - 1)){
if(current_sum < x){
window_end += 1;
current_sum += *window_end;
}
if (current_sum >= x){
sub_array_len = window_end - window_beg + 1;
if(sub_array_len < min_len){
min_len = sub_array_len;
}
current_sum -= *window_beg;
window_beg += 1;
if(window_beg > window_end){
window_end += 1;
current_sum += *window_end;
}
}
}
return min_len;
}

View File

@@ -9,7 +9,7 @@
void reverse_str(char *str){ void reverse_str(char *str){
size_t len = strlen(str); size_t len = strlen(str);
char *tmp = reinterpret_cast<char*>(malloc(len)); char *tmp = reinterpret_cast<char*>(malloc(len + 1));
strcpy(tmp, str); strcpy(tmp, str);
for(unsigned int offset = 0; offset < len; ++offset){ for(unsigned int offset = 0; offset < len; ++offset){
str[offset] = tmp[len-offset-1]; str[offset] = tmp[len-offset-1];

View File

@@ -1,6 +1,12 @@
#pragma once #pragma once
#include <queue> #include <queue>
#include <stack>
typedef enum AlgoVariant_E{
Recursive,
Iter,
}AlgoVariant;
template <class T> template <class T>
class DopeBinTreeNode{ class DopeBinTreeNode{
@@ -23,6 +29,9 @@ class DopeBinTree{
T* RecPreOrderTraversal(DopeBinTreeNode<T>* node, T* out); T* RecPreOrderTraversal(DopeBinTreeNode<T>* node, T* out);
T* RecInOrderTraversal(DopeBinTreeNode<T>* node, T* out); T* RecInOrderTraversal(DopeBinTreeNode<T>* node, T* out);
T* RecPostOrderTraversal(DopeBinTreeNode<T>* node, T* out); T* RecPostOrderTraversal(DopeBinTreeNode<T>* node, T* out);
void IterPreOrderTraversal(DopeBinTreeNode<T>* node, T* out);
void IterInOrderTraversal(DopeBinTreeNode<T>* node, T* out);
void IterPostOrderTraversal(DopeBinTreeNode<T>* node, T* out);
public: public:
DopeBinTree(T data); DopeBinTree(T data);
DopeBinTree(); DopeBinTree();
@@ -30,9 +39,9 @@ public:
void insert(T data); void insert(T data);
bool isEmpty(); bool isEmpty();
DopeBinTreeNode<T>* getRoot(){return root;} DopeBinTreeNode<T>* getRoot(){return root;}
void RecPreOrderTraversalArray(T* array); void PreOrderTraversal2Array(T* array, AlgoVariant variant);
void RecInOrderTraversalArray(T* array); void InOrderTraversal2Array(T* array, AlgoVariant variant);
void RecPostOrderTraversalArray(T* array); void PostOrderTraversal2Array(T* array, AlgoVariant variant);
}; };
// Implementations ___________________________________________________ // Implementations ___________________________________________________
@@ -147,26 +156,145 @@ T* DopeBinTree<T>::RecPostOrderTraversal(DopeBinTreeNode<T>* node, T* out){
} }
template <class T> template <class T>
void DopeBinTree<T>::RecPreOrderTraversalArray(T* array){ void DopeBinTree<T>::IterPreOrderTraversal(DopeBinTreeNode<T>* node, T* out){
std::stack<DopeBinTreeNode<T>*> s = {};
s.push(node);
while(s.empty() == false){
node = s.top();
s.pop();
*out = node->GetData();
out++;
if(node->GetRight()){
s.push(node->GetRight());
}
if(node->GetLeft()){
s.push(node->GetLeft());
}
}
}
template <class T>
void DopeBinTree<T>::IterInOrderTraversal(DopeBinTreeNode<T>* node, T* out){
std::stack<DopeBinTreeNode<T>*> s = {};
while (!s.empty() || node){
while(node != nullptr){
s.push(node);
node = node->GetLeft();
}
node = s.top();
s.pop();
*out = node->GetData();
out++;
node = node->GetRight();
}
}
template <class T>
void DopeBinTree<T>::IterPostOrderTraversal(DopeBinTreeNode<T>* node, T* out){
std::stack<DopeBinTreeNode<T>*> s_tmp = {};
std::stack<DopeBinTreeNode<T>*> s_fin = {};
s_tmp.push(node);
while(!s_tmp.empty()){
node = s_tmp.top();
s_tmp.pop();
s_fin.push(node);
if(node->GetLeft()){
s_tmp.push(node->GetLeft());
}
if(node->GetRight()){
s_tmp.push(node->GetRight());
}
}
while(!s_fin.empty()){
node = s_fin.top();
s_fin.pop();
*out = node->GetData();
out++;
}
}
/**
* \brief PreOrderTraversal2Array
*
* Binary tree traversal that visits the root node, then the left
* sub-tree, and then the right-subtree.
*
* \param The output array
* \param The algorithm variant
* \return return type
*/
template <class T>
void DopeBinTree<T>::PreOrderTraversal2Array(T* array, AlgoVariant variant){
int index = 0; int index = 0;
DopeBinTreeNode<T>* node = root; DopeBinTreeNode<T>* node = root;
switch(variant){
case AlgoVariant::Recursive:
RecPreOrderTraversal(node, &array[index]); RecPreOrderTraversal(node, &array[index]);
return;
case AlgoVariant::Iter:
IterPreOrderTraversal(node, &array[index]);
return;
default:
return;
}
} }
/**
* \brief InOrderTraversal2Array
*
* Binary tree traversal that traverses the left sub-tree, then
* visits the root node, then the right-subtree.
*
* \param The output array
* \param The algorithm variant
* \return return type
*/
template <class T> template <class T>
void DopeBinTree<T>::RecInOrderTraversalArray(T* array){ void DopeBinTree<T>::InOrderTraversal2Array(T* array, AlgoVariant variant){
int index = 0; int index = 0;
DopeBinTreeNode<T>* node = root; DopeBinTreeNode<T>* node = root;
switch(variant){
case AlgoVariant::Recursive:
RecInOrderTraversal(node, &array[index]); RecInOrderTraversal(node, &array[index]);
return;
case AlgoVariant::Iter:
IterInOrderTraversal(node, &array[index]);
return;
default:
return;
}
} }
/**
* \brief PostOrderTraversal2Array
*
* Binary tree traversal that visits left-subtree, right subtree, and
* then the root node.
*
* \param The output array
* \param The algorithm variant
* \return return type
*/
template <class T> template <class T>
void DopeBinTree<T>::RecPostOrderTraversalArray(T* array){ void DopeBinTree<T>::PostOrderTraversal2Array(T* array, AlgoVariant variant){
int index = 0; int index = 0;
DopeBinTreeNode<T>* node = root; DopeBinTreeNode<T>* node = root;
switch(variant){
case AlgoVariant::Recursive:
RecPostOrderTraversal(node, &array[index]); RecPostOrderTraversal(node, &array[index]);
return;
case AlgoVariant::Iter:
IterPostOrderTraversal(node, &array[index]);
return;
default:
return;
}
} }

View File

@@ -32,6 +32,20 @@ TEST(ChapterOne, CheckPermutations){
} }
TEST(ChapterOne, SubArraySum){
// Not actually in CTCI but is related to arrays
// Prompt: Given an array, find the sum of all subarrays of length K
// (fixed sliding window)
int a1[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
CHECK_EQUAL(27, sliding_window_max_sum(a1, 11, 3));
// Prompt: Find the shortest subarray with a sum greater than or
// equal to X (dynamic sliding window)
int a2[] = {0, 1, 2, 3, 4, 5, 6, 7, 8};
CHECK_EQUAL(1, sliding_window_shortest_subarray(a2, 9, 7));
}
// Chapter 2: Linked Lists ___________________________________________ // Chapter 2: Linked Lists ___________________________________________
TEST_GROUP(ChapterTwo){}; TEST_GROUP(ChapterTwo){};
@@ -136,7 +150,7 @@ TEST(ChapterFour, TreeTraversal){
int array[10] = {}; int array[10] = {};
btree.RecPreOrderTraversalArray(array); btree.PreOrderTraversal2Array(array, AlgoVariant::Recursive);
CHECK_EQUAL(1, array[0]); CHECK_EQUAL(1, array[0]);
CHECK_EQUAL(2, array[1]); CHECK_EQUAL(2, array[1]);
CHECK_EQUAL(4, array[2]); CHECK_EQUAL(4, array[2]);
@@ -147,7 +161,7 @@ TEST(ChapterFour, TreeTraversal){
std::fill(array, array+10, 0); std::fill(array, array+10, 0);
btree.RecInOrderTraversalArray(array); btree.InOrderTraversal2Array(array, AlgoVariant::Recursive);
CHECK_EQUAL(4, array[0]); CHECK_EQUAL(4, array[0]);
CHECK_EQUAL(2, array[1]); CHECK_EQUAL(2, array[1]);
CHECK_EQUAL(5, array[2]); CHECK_EQUAL(5, array[2]);
@@ -158,7 +172,40 @@ TEST(ChapterFour, TreeTraversal){
std::fill(array, array+10, 0); std::fill(array, array+10, 0);
btree.RecPostOrderTraversalArray(array); btree.PostOrderTraversal2Array(array, AlgoVariant::Recursive);
CHECK_EQUAL(4, array[0]);
CHECK_EQUAL(5, array[1]);
CHECK_EQUAL(2, array[2]);
CHECK_EQUAL(6, array[3]);
CHECK_EQUAL(7, array[4]);
CHECK_EQUAL(3, array[5]);
CHECK_EQUAL(1, array[6]);
std::fill(array, array+10, 0);
btree.PreOrderTraversal2Array(array, AlgoVariant::Iter);
CHECK_EQUAL(1, array[0]);
CHECK_EQUAL(2, array[1]);
CHECK_EQUAL(4, array[2]);
CHECK_EQUAL(5, array[3]);
CHECK_EQUAL(3, array[4]);
CHECK_EQUAL(6, array[5]);
CHECK_EQUAL(7, array[6]);
std::fill(array, array+10, 0);
btree.InOrderTraversal2Array(array, AlgoVariant::Iter);
CHECK_EQUAL(4, array[0]);
CHECK_EQUAL(2, array[1]);
CHECK_EQUAL(5, array[2]);
CHECK_EQUAL(1, array[3]);
CHECK_EQUAL(6, array[4]);
CHECK_EQUAL(3, array[5]);
CHECK_EQUAL(7, array[6]);
std::fill(array, array+10, 0);
btree.PostOrderTraversal2Array(array, AlgoVariant::Iter);
CHECK_EQUAL(4, array[0]); CHECK_EQUAL(4, array[0]);
CHECK_EQUAL(5, array[1]); CHECK_EQUAL(5, array[1]);
CHECK_EQUAL(2, array[2]); CHECK_EQUAL(2, array[2]);