Compare commits
2 Commits
54c2054bf2
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
| c2bdd92ec4 | |||
| 65996765d1 |
12
Readme.org
12
Readme.org
@@ -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]
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
82
libs/chapter1/sliding_window.cpp
Normal file
82
libs/chapter1/sliding_window.cpp
Normal 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;
|
||||||
|
}
|
||||||
@@ -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){
|
||||||
int index = 0;
|
std::stack<DopeBinTreeNode<T>*> s = {};
|
||||||
DopeBinTreeNode<T>* node = root;
|
s.push(node);
|
||||||
|
|
||||||
RecPreOrderTraversal(node, &array[index]);
|
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>
|
template <class T>
|
||||||
void DopeBinTree<T>::RecInOrderTraversalArray(T* array){
|
void DopeBinTree<T>::IterPostOrderTraversal(DopeBinTreeNode<T>* node, T* out){
|
||||||
int index = 0;
|
std::stack<DopeBinTreeNode<T>*> s_tmp = {};
|
||||||
DopeBinTreeNode<T>* node = root;
|
std::stack<DopeBinTreeNode<T>*> s_fin = {};
|
||||||
|
|
||||||
RecInOrderTraversal(node, &array[index]);
|
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>
|
template <class T>
|
||||||
void DopeBinTree<T>::RecPostOrderTraversalArray(T* array){
|
void DopeBinTree<T>::PreOrderTraversal2Array(T* array, AlgoVariant variant){
|
||||||
|
int index = 0;
|
||||||
|
DopeBinTreeNode<T>* node = root;
|
||||||
|
switch(variant){
|
||||||
|
case AlgoVariant::Recursive:
|
||||||
|
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>
|
||||||
|
void DopeBinTree<T>::InOrderTraversal2Array(T* array, AlgoVariant variant){
|
||||||
|
int index = 0;
|
||||||
|
DopeBinTreeNode<T>* node = root;
|
||||||
|
switch(variant){
|
||||||
|
case AlgoVariant::Recursive:
|
||||||
|
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>
|
||||||
|
void DopeBinTree<T>::PostOrderTraversal2Array(T* array, AlgoVariant variant){
|
||||||
int index = 0;
|
int index = 0;
|
||||||
DopeBinTreeNode<T>* node = root;
|
DopeBinTreeNode<T>* node = root;
|
||||||
|
|
||||||
RecPostOrderTraversal(node, &array[index]);
|
switch(variant){
|
||||||
|
case AlgoVariant::Recursive:
|
||||||
|
RecPostOrderTraversal(node, &array[index]);
|
||||||
|
return;
|
||||||
|
case AlgoVariant::Iter:
|
||||||
|
IterPostOrderTraversal(node, &array[index]);
|
||||||
|
return;
|
||||||
|
default:
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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]);
|
||||||
|
|||||||
Reference in New Issue
Block a user