<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Mehran Ghamaty</title>
    <description>The latest articles on DEV Community by Mehran Ghamaty (@mehran_ghamaty).</description>
    <link>https://dev.to/mehran_ghamaty</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F2794345%2Fd8c7524f-ab31-46c5-a1fa-8a86eff9ad8a.jpg</url>
      <title>DEV Community: Mehran Ghamaty</title>
      <link>https://dev.to/mehran_ghamaty</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/mehran_ghamaty"/>
    <language>en</language>
    <item>
      <title>Search Space: Interview Problem Survey</title>
      <dc:creator>Mehran Ghamaty</dc:creator>
      <pubDate>Tue, 04 Mar 2025 01:34:17 +0000</pubDate>
      <link>https://dev.to/mehran_ghamaty/search-space-interview-problem-survey-1ibl</link>
      <guid>https://dev.to/mehran_ghamaty/search-space-interview-problem-survey-1ibl</guid>
      <description>&lt;p&gt;classic binary search is used to solve many problems like &lt;a href="https://leetcode.com/problems/search-insert-position/description/?envType=problem-list-v2&amp;amp;envId=binary-search" rel="noopener noreferrer"&gt;leetcode 35&lt;/a&gt;.  Where we would like to find the position we insert a given value into an already sorted list.&lt;/p&gt;

&lt;p&gt;Example instance;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[1,3,5,6], 5
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Example solution;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Example code;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function searchInsert(vector&amp;lt;int&amp;gt; list, int to_insert) {
  int pivot, left = 0; right = list.length()-1;
  while(left &amp;lt;= right) {
    pivot = (left+right) &amp;gt;&amp;gt; 2;
    if(list[pivot] == to_insert) {
      return pivot;
    }
    if(to_insert &amp;gt; list[pivot]) {
      left = pivot + 1;
    } else {
      right = pivot - 1;
    }
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Similar to depth-first search or breadth-first search. This algorithm can be used as a sub-routine when search in a space if the space is already structured.&lt;/p&gt;

&lt;p&gt;Lets look at &lt;a href="https://leetcode.com/problems/swim-in-rising-water/description/" rel="noopener noreferrer"&gt;leetcode 778&lt;/a&gt; Where we are given a slowly filling pool and must swim from one end of the pool to the next. Where we use binary search to guess our constraint; time. Then perform traditional depth-first search to reach the end.&lt;/p&gt;

&lt;p&gt;Example instance;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[[0,2],[1,3]]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Example solution;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;3
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Example code;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class Solution {
private:
  bool possible(int time, vector&amp;lt;vector&amp;lt;int&amp;gt;&amp;gt; grid, int i, int j) 
  {
    int RN = grid.size();
    int CN = grid.at(0).size();

    if(i == RN-1 &amp;amp;&amp;amp; j == CN-1) return true;

    if(i + 1 &amp;lt; RN &amp;amp;&amp;amp; grid.at(i+1).at(j) &amp;lt; time) {
      return possible(time, grid, i+1, j);
    }
    if(i - 1 &amp;gt;= 0 &amp;amp;&amp;amp; grid.at(i-1).at(j) &amp;lt; time) {
      return possible(time, grid, i-1, j);
    }
    if(j + 1 &amp;lt; CN &amp;amp;&amp;amp; grid.at(i).at(j+1) &amp;lt; time) {
      return possible(time, grid, i, j+1);
    }
    if(j - 1 &amp;gt;= 0 &amp;amp;&amp;amp; grid.at(i).at(j-1) &amp;lt; time) {
      return possible(time, grid, i, j-1);
    }
    return false;
  }
public:
  int swimInWater(vector&amp;lt;vector&amp;lt;int&amp;gt;&amp;gt; grid) {
    int L = 1, H = grid.size() * grid.at(0).size();
    while(start &amp;lt; max_time) {
      int M = (L+H) &amp;gt;&amp;gt; 1;
      if(!possible(M, grid, 0, 0)) {
        L = M+1;
      } else {
        H = M-1;
      }
    }
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This problem can also be solved with Dijkstra's algorithm and Union-Find. The intuition behind Dijkstra's being to first identify Optimal Sub-structure &lt;/p&gt;

&lt;p&gt;Example Dijkstra's;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;struct V {
  int v, x, y
  V(int v_, int x_, int y_) : v(v_), x(x_), y(y_) {}
  bool operator&amp;lt; (const V &amp;amp;c) const { return this.v &amp;gt; c.v; } 
}

class Solution {
private:
  priority_queue&amp;lt;V&amp;gt; pq;
  int M;
  int N;  
public:
  int swimInWater(vector&amp;lt;vector&amp;lt;int&amp;gt;&amp;gt; grid) {
    M = grid.size();
    N = grid.at(0).size();

    pq.push(V(grid[0][0], 0,0));
    vector&amp;lt;vector&amp;lt;bool&amp;gt;&amp;gt; seen(M, vector&amp;lt;int&amp;gt;(N));
    int res = 0;
    seen[0][0] = true;

    while(!pq.empty()) {
      V p = pq.top(); 
      pq.pop();
      res = max(res, p.v);
      if(p.x == M - 1 &amp;amp;&amp;amp; p.y == N - 1) {
        return res;
      }
      if(p.x + 1 &amp;lt; M &amp;amp;&amp;amp; !seen[p.x+1][p.y]) {
        seen[p.x+1][p.y] = true;
        pq.push(V(grid[p.x+1][p.y], p.x, p.y);
      }
      if(p.x - 1 &amp;lt; M &amp;amp;&amp;amp; !seen[p.x-1][p.y]) {
        seen[p.x-1][p.y] = true;
        pq.push(V(grid[p.x-1][p.y], p.x, p.y);
      }
      if(p.y + 1 &amp;lt; M &amp;amp;&amp;amp; !seen[p.x][p.y+1]) {
        seen[p.x][p.y+1] = true;
        pq.push(V(grid[p.x][p.y+1], p.x, p.y);
      }
      if(p.y - 1 &amp;lt; M &amp;amp;&amp;amp; !seen[p.x][p.y-1]) {
        seen[p.x][p.y-1] = true;
        pq.push(V(grid[p.x][p.y-1], p.x, p.y);
      }
    }
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This differences between this question and &lt;a href="https://dev.to/mehran_ghamaty/optimal-substructure-interview-problem-survey-4ok1"&gt;network delay&lt;/a&gt; where we already used Dijsktra's is that we only care about reaching the end node, so instead of keep track of the largest ingress to the node we check if we have seen the node before.&lt;/p&gt;

&lt;p&gt;Another method being union-find, which more directly answers the question is the groups which connect the start to end node.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Optimal Substructure: Interview Problem Survey</title>
      <dc:creator>Mehran Ghamaty</dc:creator>
      <pubDate>Sat, 01 Mar 2025 19:28:13 +0000</pubDate>
      <link>https://dev.to/mehran_ghamaty/optimal-substructure-interview-problem-survey-4ok1</link>
      <guid>https://dev.to/mehran_ghamaty/optimal-substructure-interview-problem-survey-4ok1</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;In computer science, a problem is said to have optimal substructure if an optimal solution can be constructed from optimal solutions of its subproblems. This property is used to determine the usefulness of greedy algorithms for a problem.&lt;a href="https://en.wikipedia.org/wiki/Optimal_substructure" rel="noopener noreferrer"&gt;Wikipedia&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In other words optimal solutions to sub-problems form the overall optimal solution.&lt;/p&gt;

&lt;p&gt;Here we can use the property of optimal sub-structure to explore the space of all possible entries into a phone pad leetcode [&lt;a href="https://leetcode.com/problems/letter-combinations-of-a-phone-number/" rel="noopener noreferrer"&gt;17&lt;/a&gt;].&lt;/p&gt;

&lt;p&gt;example instance;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"232"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;example solution;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;["ada","adb","adc","aea","aeb","aec","afa","afb","afc","bda","bdb","bdc","bea","beb","bec","bfa","bfb","bfc","cda","cdb","cdc","cea","ceb","cec","cfa","cfb","cfc"]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;example code;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class Solver {
  unordered_map&amp;lt;char, string&amp;gt; operators = {
    {'2', "abc"}, {'3', "def"}, {'4', "ghi"},
    {'4', "ghi"}, {'5', "jkl"}, {'6', "mno"},
    {'7', "pqrs"}, {'8', "tuv"}, {'9', "wxyz"}
  }
  vector&amp;lt;string&amp;gt; SOLUTION;
  string packetNumber;

  //in order depth-first-search
  void depthFirstSearch(int index, string path) {
    if(path.length() == packet_number.length()) {
      solution.push_back(path);
      return
    }

    map&amp;lt;char, string&amp;gt;::iterator letters_iterator = operators.find(string[index]);
    for(char c : letters_iterator.second) {
      path.push_back(c);
      depthFirstSearch(index+1, path);
      path.pop_back();
    }
  }
public:
  vector&amp;lt;string&amp;gt; letterCombinations(string digits) {
    if(digits.length() == 0) {
      return SOLUTION;
    }
    packetNumber = digits;
    depthFirstSearch("", 0);
    return SOLUTION;
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here the solution requires going through all possible state changes and should be seen as a graph where the number of nodes are 2^4*n where n is the number of digits in the input and we know and it's safe to assume n &amp;lt; "a relatively small constant" so we can bound or algorithm to be constant. &lt;/p&gt;

&lt;p&gt;In this type of question we care about "revealing the search space" which should include a paper-napkin style verification the space is calculable.  &lt;/p&gt;

&lt;p&gt;next we can take a leetcode &lt;a href="https://leetcode.com/problems/network-delay-time/description/?envType=problem-list-v2&amp;amp;envId=53js48ke" rel="noopener noreferrer"&gt;[743]&lt;/a&gt; which can be solved using Dijkstra's algorithm.&lt;/p&gt;

&lt;p&gt;This is one of the properties in the ever famous Dijkstra's short path algorithm having optimal substructure we can take advantage of to not search the entire space of traversing the graph, the neat thing of Dijkstra's is we get to keep the structure to re-use.&lt;/p&gt;

&lt;p&gt;Here the example being calculating Network Delay from one node to another.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class Solver {
private:
  struct comp { 
    bool operator()(const pair&amp;lt;int, int&amp;gt;&amp;amp; a, const pair&amp;lt;int, int&amp;gt; b) {
      return a.second &amp;gt; b.second;
    }
  }
public:
  networkDelayTime(vector&amp;lt;vector&amp;lt;int&amp;gt;&amp;gt;&amp;amp; times, int n, int k) {
    vector&amp;lt;vector&amp;lt;pair&amp;lt;int,int&amp;gt;&amp;gt;&amp;gt; graph(n+1);
    for(auto&amp;amp; t : times) {
      graph[t[0]].emplace_back(make_pair(t[1], t[2]));
    }

    vector&amp;lt;int&amp;gt; total_cost_to_travel(n+1, INT_MAX);
    priority_queue&amp;lt;pair&amp;lt;int, int&amp;gt;, vector&amp;lt;pair&amp;lt;int,int&amp;gt;&amp;gt;, comp&amp;gt; pq;

    pq.push(make_pair(k, 0));
    total_cost_to_travel[k] = 0;

    int vertex_count = 0, maximum_delay = -1;
    while(not pq.empty()) {
      pair&amp;lt;int, int&amp;gt; edgeIn = pq.top(); pq.pop();
      if(total_cost_to_travel[edgeIn.first] &amp;lt; edgeIn.second) {
        continue;
      }
      ++vertex_count;
      maximum_delay = max(maximum_delay, total_cost_to_travel[edgeIn.first]);

      for(pair&amp;lt;int, int&amp;gt; edgeOut : graph[edgeIn.first]) {
        int edgeWeight = total_cost_to_travel[edgeOut.first];
        if(edgeWeight &amp;gt; edgeOut.second + edgeWeight) {
          total_cost_to_travel[edgeOut.first] = edgeOut.second + edgeWeight;
          pq.push(make_pair(edgeOut.first, tc[edgeOut.first]));
        }
      }
    } 
    return vertex_count == n ? maximum_delay : -1;
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
    </item>
    <item>
      <title>Subroutines: Interview Problem Survey</title>
      <dc:creator>Mehran Ghamaty</dc:creator>
      <pubDate>Fri, 28 Feb 2025 20:46:31 +0000</pubDate>
      <link>https://dev.to/mehran_ghamaty/subroutines-interview-problem-survey-386g</link>
      <guid>https://dev.to/mehran_ghamaty/subroutines-interview-problem-survey-386g</guid>
      <description>&lt;p&gt;Lets say we have an algorithm which performs a check if a string is a palindrome.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;bool isPalindrome(string s) {
  for(int i = 0; i &amp;lt; s.length()/2; i++) {
    if(s.at(i) != s.at(s.length()-i-1)) {
      return false;
    }
  }
  return true;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This type of solution can be a subroutine to many questions; which may require pre-processing before calling &lt;code&gt;isPalindrome()&lt;/code&gt;. An example may be removing spaces and alphanumeric characters.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;bool cleanString(string s) {
  string cleanedstr = "";
  for(char c : s) {
    if(isalnum(c)) {
      cleanedstr += tolower(c);
    }
  }
  return cleanedstr;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To better use the isPalindrome as a subroutine we can add additional parameters. This can help answering questions like leetcode 680; where at most one character can be deleted.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;bool isPalindrome(string s, int i, int j) {
  for(;i&amp;lt;j;i++,j++) {
    if(s.at(i) != s.at(j)) {
      return false;
    }
  }
  return true;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and the parent function handles the case where we may have up to one deleted character.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;bool atMostOneMissingPalendrome() {
  int i = 0;
  int j = s.length() -1;
  for(int i = 0, j = s.length()-1; i&amp;lt;j; i++,j++) {
    if(s.at(i) != s.at(j)) {
      return isPalendrome(s, i, j-1) || isPalendrome(s, i+1, j);
    }
  }
  return true;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now a more common scenario during an interview is having to use depth-first search or breadth first search. One question where this appears is connected-components or connected islands style questions; where you are given a matrix and asked to find the number of islands or the biggest island where a '1' denotes sand presence and '0' denotes water.&lt;/p&gt;

&lt;p&gt;example instance;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;111000
100011
001010
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;example solution;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;4
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;example code;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;int depth_first_search(vector&amp;lt;vector&amp;lt;int&amp;gt;&amp;gt; matrix, int i, int j) {
  if(matrix.at(i).at(j) == 0) {
    return 0;
  }

  int total = 1;
  if(i+1 &amp;lt; matrix.size()) 
    total += depth_first_search(matrix, i+1, j);
  if(i-1 &amp;gt;= 0) 
    total += depth_first_search(matrix, i-1, j);
  if(j+1 &amp;lt; matrix.at(0).size()) 
    total += depth_first_search(matrix, i, j+1);
  if(j-1 &amp;gt;= 0) 
    total += depth_first_search(matrix, i, j-1);
  return total;
}

int find_largest_island_size(vector&amp;lt;vector&amp;lt;int&amp;gt;&amp;gt; matrix) {
  int max_island = 0;
  for(int i = 0; i &amp;lt; matix.size(); i++) {
    for(int j = 0; j &amp;lt; matrix.at(0).size(); j++) {
       max_island = max(max_island, depth_first_search(matrix, i, j));
    }
  }
  return max_island
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we may have scenarios where instead of the classic up, down, left, right search options we have more complex operators such as in leetcode 282. Where we are given a String of numbers and a target number and can introduce binary operators which result in the expression resolving to the target number. The goal is to find all such expressions&lt;/p&gt;

&lt;p&gt;example instance;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"332" 8
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;example solution;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;3+3+2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;example code;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class Solver {
private:
  vector&amp;lt;string&amp;gt; ans;
  int target;
  string number;
  void dfs(string path, int idx, 
    long long curr, long long prev) {

    if(idx == num.size()) {
      if(curr == target)
        ans.push_back(path);
      return;
    }

    for(int i = idx; i &amp;lt; num.size(); i++) {
      if(i != idx &amp;amp;&amp;amp; num[idx] == '0')
        break;
      string snumber = num.substr(idx, i - idx+1)
      long long number = stoll(snumber);
      //initially we have no choice but to take the number
      if(idx == 0) {
        dfs(path+snumber, i+1, number, number);
      } else {

        dfs(path+"+"+snumber, i+1, curr+number, number);
        dfs(path+"-"+snumber, i+1, curr-number, -number); 
        // during the scenario we multiply we have to remove the
        // the previous value from our running sum
        dfs(path+"*"+snumber, i+1, curr-prev+(prev*number), prev * number);
      }
    }
  }
public:
  vector&amp;lt;string&amp;gt; getExpressions(string num, int target) {
    this-&amp;gt;target = target;
    this-&amp;gt;num = num;
    dfs("", 0,0,0);
    return ans;
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
    </item>
    <item>
      <title>Trees: Interview Problem Survey</title>
      <dc:creator>Mehran Ghamaty</dc:creator>
      <pubDate>Wed, 26 Feb 2025 22:14:36 +0000</pubDate>
      <link>https://dev.to/mehran_ghamaty/trees-interview-problem-survey-484p</link>
      <guid>https://dev.to/mehran_ghamaty/trees-interview-problem-survey-484p</guid>
      <description>&lt;p&gt;Learning how to traverse a tree can answer a huge number of interview questions; At the high level there are two main ways of traversing a Tree depth first search and breadth first search. &lt;/p&gt;

&lt;p&gt;To give some meat to our article let's give our Nodes a definition;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;template&amp;lt;typename T&amp;gt;
struct MyTreeNode {
  unique_ptr&amp;lt;T&amp;gt; value;
  shared_ptr&amp;lt;MyTreeNode&amp;gt; left;
  shared_ptr&amp;lt;MyTreeNode&amp;gt; right;
  MyTreeNode(): val(make_ptr(nullptr)), left(make_ptr(nullptr)), right(make_ptr(nullptr)) {}
  MyTreeNode(T val): val(make_ptr(pulltr), left(make_ptr(nullptr)), right(make_ptr(nullptr)) {}
  MyTreeNode(T val, MyTreeNode left, MyTreeNode right): val(make_ptr(pulltr), left(make_ptr(left)), right(make_ptr(right)) {}
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Lets start with breadth-first search since this non-recursive solution is sometimes easier to debug during a stressful interview, even if it's slightly more difficult to remember.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;template&amp;lt;typename T&amp;gt;
void breadth_first_search(shared_ptr&amp;lt;MyTreeNode&amp;gt; root,
    const std::function&amp;lt;void(T)&amp;gt;&amp;amp; predicate) {
  if(root.get() == nullptr()) {
    return;
  }

  vector&amp;lt;shared_ptr&amp;lt;MyTreeNode&amp;gt;&amp;gt; queue;
  queue.push(root);

  while(!queue.empty()) {
#ifdef pre-order
    predicate(queue.front().value.get());
    queue.pop();
#endif

    if(root.left.get() != nullptr) {
      queue.push(root.left);
    }

#ifdef in-order
    predicate(queue.front().value.get());
    queue.pop();
#endif

    if(root.right.get() != nullptr) {
      queue.push(root.right);
    }

#ifdef post-order
    predicate(queue.front().value.get());
    queue.pop()
#endif
  }

}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next example would be depth-first search;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;template&amp;lt;typename T&amp;gt;
void depth_first_search(shared_ptr&amp;lt;MyTreeNode&amp;gt; root,
    const std::function&amp;lt;void(T)&amp;gt;&amp;amp; predicate) {'
  if(root.get() != nullptr) {
    return;
  }

  // if pre-order
#ifdef pre-order
  predicate(root.value.get());
#endif
  if(root.left.get() != nullptr) {
    depth_first_search(root.left);
  }  

#ifdef in-order
  predicate(root.value.get());
#endif

  if(root.right.get() != nullptr) {
    depth_first_search(root.right);
  }

#ifdef post-order
  predicate(root.value.get());
#endif

}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now these two algorithm serve as the basis for many problems.&lt;/p&gt;

</description>
    </item>
  </channel>
</rss>
