<?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: Jake Z.</title>
    <description>The latest articles on DEV Community by Jake Z. (@jacobjzhang).</description>
    <link>https://dev.to/jacobjzhang</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.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F147628%2Fa2b1bd84-408b-4155-83b0-cd968a91f5a8.jpg</url>
      <title>DEV Community: Jake Z.</title>
      <link>https://dev.to/jacobjzhang</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/jacobjzhang"/>
    <language>en</language>
    <item>
      <title>What I Didn't Expect to Learn From Running My Side Hustle</title>
      <dc:creator>Jake Z.</dc:creator>
      <pubDate>Thu, 17 Sep 2020 12:37:01 +0000</pubDate>
      <link>https://dev.to/jacobjzhang/what-i-didn-t-expect-to-learn-from-running-my-side-hustle-1hml</link>
      <guid>https://dev.to/jacobjzhang/what-i-didn-t-expect-to-learn-from-running-my-side-hustle-1hml</guid>
      <description>&lt;p&gt;The past few months, my side hustle and technical interview course &lt;a href="https://algodaily.com"&gt;AlgoDaily&lt;/a&gt; hit &lt;strong&gt;$3k USD MRR&lt;/strong&gt;. It's a small amount compared to my software engineering position at a large tech company, but it covers rent and gave me something to work on during COVID. While running this project, I learned a ton of stuff that's been really useful for both the business, as well as for at work. Here's a small sampling.&lt;/p&gt;

&lt;h2&gt;
  
  
  Engineering Quality Does Not Matter
&lt;/h2&gt;

&lt;p&gt;This statement is of course being facetious, but not to a tremendous extent. Many outsiders will think that in a software project, engineering should roughly consume 50% of your time, and marketing/sales/biz dev the other half.&lt;/p&gt;

&lt;p&gt;This is great in theory, but it turns out that marketing/sales brings in 100% of the money-- shocking, right? The old adage rings true: you can literally have the best product in the world, but if no one knows about it, it won't really matter. Likewise, when people are on your site or app, they just care that the button works when it's clicked. Only fellow developers will find it cool that you're using turbolinks or react-dom-router.&lt;/p&gt;

&lt;p&gt;For the first year and a half of running &lt;a href="https://algodaily.com"&gt;AlgoDaily&lt;/a&gt;, I spent nearly all the time improving the product, and refining it technically. I built a &lt;a href="https://algodaily.com/challenges/daily"&gt;daily coding newsletter&lt;/a&gt; and wrote hundreds of long-form, quality solutions. Then added an editor and runtime to the site so folks could execute solutions. Then I hired a team to add solutions in other languages. Then I worked with a team to create hundreds of beautiful visualizations and diagrams. &lt;strong&gt;None of these things improved sales dramatically.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;You know what did work? Telling people about it! Sharing my work with communities (shout out Hacker News and dev.to), asking email subscribers to check out the premium course, getting and sharing testimonials, and spreading the word via social media/youtube/meetups-- getting people's attention was by far the most crucial thing for the sustainability of a small business.&lt;/p&gt;

&lt;h2&gt;
  
  
  Are You a Content or a Platform Play?
&lt;/h2&gt;

&lt;p&gt;One huge mistake I made in the very beginning was mistaking content plays with platform plays. It's too easy for a software product to just be labeled "software", and for its founder/maker to start listening to generalized advice that may not apply.&lt;/p&gt;

&lt;p&gt;For example-- "it needs to be 10x better". Not if you're a content business! An online course, newsletter, or Youtube channel only needs to &lt;a href="https://algodaily.com/subscriptions/new"&gt;be marginally better&lt;/a&gt; to have users make the switch. Think about it-- if I have the option to watch &lt;em&gt;Selling Sunset&lt;/em&gt; or &lt;em&gt;Million Dollar Beachhouse&lt;/em&gt;, I'm picking &lt;em&gt;Selling Sunset&lt;/em&gt; every time even though it's just a minor improvement in quality.&lt;/p&gt;

&lt;p&gt;Another one-- "build an MVP first and iterate". If you're trying to offer articles, tutorials, videos, or podcasts-- an MVP is just episode one. You won't learn much until episode 100 or so!&lt;/p&gt;

&lt;h2&gt;
  
  
  Side Hustles Need Help Too
&lt;/h2&gt;

&lt;p&gt;AlgoDaily really started to take off when I got burned out after the first year for several months. I then started hiring people to help with nearly everything, and only then did it start seeing traction. If you're a solo maker, don't hesitate to hire!&lt;/p&gt;

&lt;p&gt;The term "indie hacker" is kind of bull, largely because there's no such thing as a pure one-person business. Yes, one person may oversee or run things, but the second you need vendors (hosting, forms, newsletter, graphics, design), you've started to build a team. It may be a low-touch team, but if any part of your business &lt;em&gt;depends&lt;/em&gt; on a third-party solution, you're no longer on your own.&lt;/p&gt;

&lt;h2&gt;
  
  
  Less Reading, More Experimenting
&lt;/h2&gt;

&lt;p&gt;I think the majority of entrepeneurial advice/content is largely useless &lt;em&gt;in the moment&lt;/em&gt; that it's being consumed. I now &lt;strong&gt;strongly&lt;/strong&gt; believe in favoring &lt;strong&gt;just in time&lt;/strong&gt; advice versus &lt;strong&gt;just in case&lt;/strong&gt; advice.&lt;/p&gt;

&lt;p&gt;What's the difference? Just-in-case advice is when you peruse indiehackers.com or pick up a business book for entertainment. You'll read a case study to get motivated, or to get inspired, but it's probably not useful to you at that moment. There's nothing wrong with this-- in fact, I'm having a great time reading &lt;a href="https://www.amazon.com/gp/product/1984877860/ref=as_li_qf_asin_il_tl?ie=UTF8&amp;amp;tag=algodaily03-20&amp;amp;creative=9325&amp;amp;linkCode=as2&amp;amp;creativeASIN=1984877860&amp;amp;linkId=712b8bc0cac0b15aa175e6b8bbe411c7"&gt;Reed Hasting's new book on Netflix&lt;/a&gt;-- but I know that it's infotainment.&lt;/p&gt;

&lt;p&gt;Just-in-time advice, on the other hand, is when you don't know how to do something and look up a tutorial. It's when you feel chronic fatigue and see a doctor, or have a specific legal question and seek out a lawyer. I've found business advice to be much more useful here, because it's &lt;em&gt;specific to the problem at hand&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;It's cool to read up on how an ivy league grad launched a multi-billion dollar startup when she was 21, but almost none of what they did or said will ever apply to someone creating a small online course while trying to start a family. Learning about morning routines and what founders read is dope, but what will actually help your hustle is to try everything and learn from failures.&lt;/p&gt;

&lt;h2&gt;
  
  
  Customer Quality Really Does Vary By Price
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;99.9% of AlgoDaily users are lovely&lt;/strong&gt;. I've corresponded with hundreds, if not thousands of you at this point, and for the most part you're all great! I've made several mistakes along the way, and the AD community has been extremely forgiving and encouraging even during big mishaps.&lt;/p&gt;

&lt;p&gt;However-- there really is a correlation between willingness to pay and customer quality. The nastiest emails I've ever gotten have been from folks who've bought a subscription during a sale, paid for a month (the absolute minimum), and then demanded a refund while deriding myself and the product. On the other hand, the folks who pay for the most expensive packages upfront, or stay subscribed for many years, never complain and are usually the first to give testimonials and praise in public.&lt;/p&gt;

&lt;p&gt;I'm not sure what to make of this. I price AlgoDaily at a ridiculously low price. You get a daily coding email, hundreds of illustrations, and video solutions for what amounts to $5-6/month if you pay annually. I do this to try to help folks and give back to the dev community, obviously while also learning some things about running a business-- but why people will be rude and mean while getting so much value (and often completely free content) will never make sense to me. What a fascinating phenomenon.&lt;/p&gt;




&lt;p&gt;As every thought leader now says, hope this brought you some value. If you're preparing for technical interviews, &lt;a href="https://algodaily.com"&gt;consider the best and most accessible course available&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>productivity</category>
      <category>webdev</category>
      <category>career</category>
      <category>motivation</category>
    </item>
    <item>
      <title>Memoization in Dynamic Programming Through Examples</title>
      <dc:creator>Jake Z.</dc:creator>
      <pubDate>Sat, 05 Sep 2020 19:31:13 +0000</pubDate>
      <link>https://dev.to/jacobjzhang/memoization-in-dynamic-programming-through-examples-58ll</link>
      <guid>https://dev.to/jacobjzhang/memoization-in-dynamic-programming-through-examples-58ll</guid>
      <description>&lt;p&gt;&lt;code&gt;Dynamic programming&lt;/code&gt; is a technique for solving problems, whose solution can be expressed recursively in terms of solutions of overlapping sub-problems. A gentle introduction to this can be found in &lt;a href="https://algodaily.com/lessons/how-does-dp-work-dynamic-programming-explained"&gt;How Does DP Work? Dynamic Programming Tutorial&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Memoization&lt;/code&gt; is an optimization process. In simple terms, we store the intermediate results of the solutions of sub-problems, allowing us to speed up the computation of the overall solution.  The improvement can be reduced to an &lt;code&gt;exponential time solution to a polynomial time solution&lt;/code&gt;, with an overhead of using additional memory for storing intermediate results.&lt;/p&gt;

&lt;p&gt;Let's understand how dynamic programming works with memoization with a simple example.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--cPasBDMO--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://storage.googleapis.com/algodailyrandomassets/curriculum/dynamic-programming/dp1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--cPasBDMO--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://storage.googleapis.com/algodailyrandomassets/curriculum/dynamic-programming/dp1.png" alt="Recursion tree for f(5)"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;This lesson was originally published at &lt;a href="https://algodaily.com/lessons/memoization-in-dynamic-programming"&gt;https://algodaily.com&lt;/a&gt;, where I maintain a technical interview course and write think-pieces for ambitious developers.&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Fibonacci Numbers
&lt;/h3&gt;

&lt;p&gt;You have probably heard of &lt;a href="https://algodaily.com/challenges/fibonacci-sequence/"&gt;&lt;code&gt;Fibonacci numbers&lt;/code&gt;&lt;/a&gt; several times in the past, especially regarding recurrence relations or writing recursive functions.  Today we'll see how this simple example gives us a true appreciation of the power of dynamic programming and memoization.&lt;/p&gt;

&lt;h3&gt;
  
  
  Definition of Fibonacci Numbers
&lt;/h3&gt;

&lt;p&gt;The &lt;code&gt;n&lt;/code&gt;th  Fibonacci number &lt;code&gt;f(n)&lt;/code&gt; is defined as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;f(0) = 0                                       // base case
f(1) = 1                                       // base case 
f(n) = f(n-1) + f(n-2)    for n&amp;gt;1              // recursive case
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;The sequence of Fibonacci numbers generated from the above expressions is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;0 1 1 2 3 5 8 13 21 34 ...
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h3&gt;
  
  
  Pseudo-code for Fibonacci Numbers
&lt;/h3&gt;

&lt;p&gt;When implementing the mathematical expression given above, we can use the following recursive pseudo-code attached.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Routine: f(n)
Output: Fibonacci number at the nth place

Base case:
1. if n==0 return 0
2. if n==1 return 1

Recursive case:
1. temp1 = f(n-1)
2. temp2 = f(n-2)
3. return temp1+temp2
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;The recursion tree shown below illustrates how the routine works for computing &lt;code&gt;f(5)&lt;/code&gt; or &lt;code&gt;fibonacci(5)&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;If we look closely at the recursive tree, we can see that the function is computed twice for &lt;code&gt;f(3)&lt;/code&gt;, thrice for &lt;code&gt;f(2)&lt;/code&gt; and many times for the base cases &lt;code&gt;f(1)&lt;/code&gt; and &lt;code&gt;f(0)&lt;/code&gt;.  The overall complexity of this pseudo-code is therefore exponential &lt;code&gt;O(2^n)&lt;/code&gt;.  We can very well see how we can achieve massive speedups by storing the intermediate results and using them when needed.  &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--cPasBDMO--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://storage.googleapis.com/algodailyrandomassets/curriculum/dynamic-programming/dp1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--cPasBDMO--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://storage.googleapis.com/algodailyrandomassets/curriculum/dynamic-programming/dp1.png" alt="Recursion tree for f(5)"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Memoization of Fibonacci Numbers: From Exponential Time Complexity to Linear Time Complexity
&lt;/h3&gt;

&lt;p&gt;To speed things up, let's look at the structure of the problem.  &lt;code&gt;f(n)&lt;/code&gt; is computed from &lt;code&gt;f(n-1)&lt;/code&gt; and &lt;code&gt;f(n-2)&lt;/code&gt;. As such, we only need to store the intermediate result of the function computed for the previous two numbers.  The pseudo-code to achieve this is provided here.&lt;/p&gt;

&lt;p&gt;The figure below shows how the pseudo-code is working for &lt;code&gt;f(5)&lt;/code&gt;.  Notice how a very simple memoization technique that uses two extra memory slots has &lt;strong&gt;reduced our time complexity from exponential to linear (&lt;code&gt;O(n)&lt;/code&gt;)&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--dhLQwEP4--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://storage.googleapis.com/algodailyrandomassets/curriculum/dynamic-programming/dp2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--dhLQwEP4--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://storage.googleapis.com/algodailyrandomassets/curriculum/dynamic-programming/dp2.png" alt="DP for f(5)"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Routine: fibonacciFast
Input: n
Output: Fibonacci number at the nth place
Intermediate storage: n1, n2 to store f(n-1) and f(n-2) respectively

1. if (n==0) return 0
2. if (n==1) return 1
3. n1 = 1
4. n2 = 0
5. for 2 .. n
    a. result = n1+n2           // gives f(n)
    b.   n2 = n1                // set up f(n-2) for next number
    c.   n1 = result            // set up f(n-1) for next number
6. return result


&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h2&gt;
  
  
  Maximizing Rewards While Path Finding Through a Grid
&lt;/h2&gt;

&lt;p&gt;Now that we understand &lt;code&gt;memoization&lt;/code&gt; a little better, let's move on to our next problem.  Suppose we have an &lt;code&gt;m * n&lt;/code&gt; grid, where each cell has a "reward" associated with it.  Let's also assume that there's a robot placed at the starting location, and that it has to find its way to a "goal cell".  While it's doing this, it will be judged by the path it chooses. We want to get to the "goal" via a path that collects the maximum reward.  The only moves allowed are "up" or "right".  &lt;/p&gt;

&lt;h3&gt;
  
  
  Using a Recursive Solution
&lt;/h3&gt;

&lt;p&gt;This awesome &lt;a href="https://algodaily.com/lessons/recursive-backtracking-for-combinatorial-path-finding-and-sudoku-solver-algorithms/enumerating-paths-through-a-square-grid-6"&gt;tutorial on recursion and backtracking&lt;/a&gt; tells you how to enumerate all paths through this grid via &lt;code&gt;backtracking&lt;/code&gt;.  We can use the same technique for collecting the "maximum reward" as well, via the following two steps:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;1. Enumerate all paths on the grid, while computing the reward along each path
2. Select the path with the maximum reward
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Let's look at how this code will work. The below illustration has a &lt;code&gt;3 x 3&lt;/code&gt; grid.  We've kept the grid small because the tree would otherwise be too long and too wide.  The &lt;code&gt;3 x 3&lt;/code&gt; grid only has &lt;code&gt;6&lt;/code&gt; paths, but if you have a &lt;code&gt;4 x 4&lt;/code&gt; grid, you'll end up with &lt;code&gt;20&lt;/code&gt; paths (and for a &lt;code&gt;5 x 5&lt;/code&gt; grid there would be &lt;code&gt;70&lt;/code&gt;):&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ZglRyJ-J--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://storage.googleapis.com/algodailyrandomassets/curriculum/dynamic-programming/dp3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ZglRyJ-J--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://storage.googleapis.com/algodailyrandomassets/curriculum/dynamic-programming/dp3.png" alt="Maximize reward via enumeration"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We can very well see that such a solution has exponential time complexity-- in other words,  &lt;code&gt;O(2^mn)&lt;/code&gt; -- and it's not very smart.&lt;/p&gt;

&lt;h3&gt;
  
  
  Dynamic Programming and Memoization
&lt;/h3&gt;

&lt;p&gt;Let's try to come up with a solution for path-finding while maximizing reward, by using the following observation:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;If the path with the maximum reward passes through cell &lt;code&gt;(r, c)&lt;/code&gt;, then it is also the best path from the start to &lt;code&gt;(r, c)&lt;/code&gt;, and the best path from &lt;code&gt;(r, c)&lt;/code&gt; to goal.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;This is the fundamental principle behind finding the optimum, or best path, that collects the maximum reward.  We have broken down a large problem into two smaller sub-problems:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Best path from start to &lt;code&gt;(r, c)&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Best path from &lt;code&gt;(r, c)&lt;/code&gt; to goal&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Combining the two will give us the overall optimal path.  Since we don't know in advance which cells are a part of the optimal path, we'll want to store the maximum reward accumulated when moving from the start to all cells of the grid.  The accumulated reward of the goal cell gives us the optimal reward.  We'll use a similar technique to find the actual optimal path from start to goal.  &lt;/p&gt;

&lt;p&gt;Let's use a matrix array called &lt;code&gt;reward&lt;/code&gt; that will hold the accumulated maximum reward from the start to each cell.  Hence, we have the following matrices:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// input matrix where:
w[r, c]  = reward for individual cell (r, c)

// intermediate storage where:
reward[r, c] = maximum accumulated reward along the path from the start to cell (r, c)    
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Here is the recursive pseudo-code that finds the maximum reward from the start to the goal cell.  The pseudo-code finds the maximum possible reward when moving up or right on an &lt;code&gt;m x n&lt;/code&gt; grid.  Let's assume that the start cell is &lt;code&gt;(0, 0)&lt;/code&gt; and the goal cell is &lt;code&gt;(m-1, n-1)&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;To get an understanding of the working of this algorithm, look at the figure below.  It shows the maximum possible reward that can be collected when moving from start cell to any cell.  For now, ignore the direction matrix in red.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://storage.googleapis.com/algodailyrandomassets/curriculum/dynamic-programming/dp4.png"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--inqSJLH_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://storage.googleapis.com/algodailyrandomassets/curriculum/dynamic-programming/dp4.png" alt="Path Finding with DP"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Routine: maximizeReward
Start cell coordinates: (0, 0)
Goal cell coordinates: (m-1, n-1)
Input: Reward matrix w of dimensions mxn

Base case 1:
// for cell[0, 0]
reward[0, 0] = w[0, 0]

Base case 2:
// zeroth col.  Can only move up
reward[r, 0] = reward[r-1, 0] + w[r, 0]  for r=1..m-1

Base case 3:
// zeroth row.  Can only move right
reward[0,c] = reward[0, c-1] + w[0, c] for c=1..n-1

Recursive case:
1. for r=1..m-1
    a. for c=1..n-1
        i. reward[r,c] = max(reward[r-1, c],reward[r, c-1]) + w[r, c]
2. return reward[m-1, n-1]           // maximum reward at goal state  
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h3&gt;
  
  
  Finding the Path via Memoization
&lt;/h3&gt;

&lt;p&gt;Finding the actual path is also easy.  All we need is an additional matrix, which stores the &lt;code&gt;predecessor&lt;/code&gt; for each cell &lt;code&gt;(r, c)&lt;/code&gt; when finding the maximum path.  For example, in the figure above, when filling &lt;code&gt;(1, 1)&lt;/code&gt;, the maximum reward would be &lt;code&gt;8+5&lt;/code&gt; when the predecessor in the path is the cell &lt;code&gt;(0, 1)&lt;/code&gt;.  We need one additional matrix &lt;code&gt;d&lt;/code&gt; that gives us the direction of the predecessor:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;d[r,c] = coordinates of the predecessor in the optimal path reaching `[r, c]`. 
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;The pseudo-code for filling the direction matrix is given by the attached pseudocode.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Routine: bestDirection
routine will fill up the direction matrix
Start cell coordinates: (0,0)
Goal cell coordinates: (m-1,n-1)
Input: Reward matrix w

Base case 1:
// for cell[0,0]
d[0,0] = (-1, -1)      //not used

Base case 2:
// zeroth col.  Can only move up
d[r,0] = (r-1, 0)   for r=1..m-1

Base case 3:
// zeroth row.  Can only move right
reward[0, c] = d[0,c-1] for c=1..n-1

Recursive case:
1. for r=1..m-1
    a. for c=1..n-1
        i. if reward[r-1,c] &amp;gt; reward[r,c-1]) 
                then d[r,c] = (r-1, c)
           else
                 d[r,c] = (r, c-1)
2. return d
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Once we have the direction matrix, we can &lt;code&gt;backtrack&lt;/code&gt; to find the best path, starting from the goal cell &lt;code&gt;(m-1, n-1)&lt;/code&gt;.  Each cell's predecessor is stored in the matrix &lt;code&gt;d&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;If we follow this chain of predecessors, we can continue until we reach the start cell &lt;code&gt;(0, 0)&lt;/code&gt;.  Of course, this means we'll get the path elements in the reverse direction.  To solve for this, we can push each item of the path on a stack and &lt;code&gt;pop&lt;/code&gt; them to get the final path. The steps taken by the pseudo-code are shown in the figure below.   &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--6ZSY8IJC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://storage.googleapis.com/algodailyrandomassets/curriculum/dynamic-programming/dp5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--6ZSY8IJC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://storage.googleapis.com/algodailyrandomassets/curriculum/dynamic-programming/dp5.png" alt="Path Finding"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Routine: printPath
Input: direction matrix d
Intermediate storage: stack

// build the stack
1. r = m-1
2. c = n-1
3. push (r, c) on stack
4. while (r!=0 &amp;amp;&amp;amp; c!=0)
    a. (r, c) = d[r, c]
    b. push (r, c) on stack
// print final path by popping stack
5. while (stack is not empty)
    a. (r, c) = stack_top
    b. print (r, c)
    c. pop_stack
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h3&gt;
  
  
  Time Complexity of Path Using Dynamic Programming and Memoization
&lt;/h3&gt;

&lt;p&gt;We can see that using matrices for intermediate storage &lt;strong&gt;drastically reduces the computation time&lt;/strong&gt;.  The &lt;code&gt;maximizeReward&lt;/code&gt; function fills each cell of the matrix only once, so its time complexity is &lt;code&gt;O(m * n)&lt;/code&gt;.  Similarly, the best direction also has a time complexity of &lt;code&gt;O(m * n)&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;printPath&lt;/code&gt; routine would print the entire path in &lt;code&gt;O(m+n)&lt;/code&gt; time. Thus, the overall time complexity of this path finding algorithm is &lt;code&gt;O(m * n)&lt;/code&gt;.  This means we have a drastic reduction in time complexity from &lt;code&gt;O(2^mn)&lt;/code&gt; to &lt;code&gt;O(m + n)&lt;/code&gt;.  This, of course, comes at a &lt;em&gt;cost of additional storage&lt;/em&gt;.  We need additional &lt;code&gt;reward&lt;/code&gt; and &lt;code&gt;direction&lt;/code&gt; matrices of size &lt;code&gt;m * n&lt;/code&gt;, making the space complexity &lt;code&gt;O(m * n)&lt;/code&gt;.  The stack of course uses &lt;code&gt;O(m+n)&lt;/code&gt; space, so the overall space complexity is &lt;code&gt;O(m * n)&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Weighted Interval Scheduling via Dynamic Programming and Memoization
&lt;/h2&gt;

&lt;p&gt;Our last example in exploring the use of &lt;code&gt;memoization&lt;/code&gt; and &lt;code&gt;dynamic programming&lt;/code&gt; is the &lt;strong&gt;weighted interval scheduling problem&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;We are given &lt;code&gt;n&lt;/code&gt; intervals, each having a &lt;code&gt;start&lt;/code&gt; and &lt;code&gt;finish&lt;/code&gt; time, and a weight associated with them.  Some sets of intervals overlap and some sets do not.  The goal is to find a set of &lt;code&gt;non-overlapping&lt;/code&gt; intervals to &lt;code&gt;maximize&lt;/code&gt; the total weight of the selected intervals.  This is a very interesting problem in computer science, as it is used in scheduling CPU tasks, and in manufacturing units to maximize profits and minimize costs.&lt;/p&gt;

&lt;h3&gt;
  
  
  Problem Parameters
&lt;/h3&gt;

&lt;p&gt;The following are the parameters of the problem:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;1. n = total intervals.  We'll use an additional zeroth interval for base case.
2. Each interval has a start time and a finish time.  
    Hence there are two arrays s and f, both of size (n+1)
    s[j] &amp;lt; f[j] for j=1..n and s[0] = f[0] = 0
3. Each interval has a weight w, so we have a weight array w.  w[j] &amp;gt;0  for j=1..n and w[0]=0
4. The interval array is sorted according to finish times.
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Additionally we need a predecessor array &lt;code&gt;p&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;6. p[j] = The non-overlapping interval with highest finish time which is less than f[j].  
            p[j] is the interval that finishes before p[j]
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;To find &lt;code&gt;p[j]&lt;/code&gt;, we only look to the left for the first non-overlapping interval.  The figure below shows all the problem parameters.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--aJ5MjFjk--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://storage.googleapis.com/algodailyrandomassets/curriculum/dynamic-programming/dp6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--aJ5MjFjk--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://storage.googleapis.com/algodailyrandomassets/curriculum/dynamic-programming/dp6.png" alt="Weighted interval scheduling"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  A Recursive Expression for Weighted Interval Scheduling
&lt;/h3&gt;

&lt;p&gt;As mentioned before, &lt;code&gt;dynamic programming&lt;/code&gt; combines the solutions of overlapping sub-problems.  Such a problem, &lt;strong&gt;the interval scheduling for collecting maximum weights&lt;/strong&gt;, is relatively easy.&lt;/p&gt;

&lt;p&gt;For any interval &lt;code&gt;j&lt;/code&gt;, the maximum weight can be computed by either including it or excluding it.  If we include it, then we can compute the sum of weights for &lt;code&gt;p[j]&lt;/code&gt;, as &lt;code&gt;p[j]&lt;/code&gt; is the first non-overlapping interval that finishes before &lt;code&gt;I[j]&lt;/code&gt;.  If we exclude it,  then we can start looking at intervals &lt;code&gt;j-1&lt;/code&gt; and lower.  The attached is the recursive mathematical formulation.&lt;/p&gt;

&lt;p&gt;The below figure shows the recursion tree when &lt;code&gt;T(5)&lt;/code&gt; is run.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--GlzN27Dp--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://storage.googleapis.com/algodailyrandomassets/curriculum/dynamic-programming/dp7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--GlzN27Dp--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://storage.googleapis.com/algodailyrandomassets/curriculum/dynamic-programming/dp7.png" alt="Weighted interval scheduling" width="800"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Routine: T(j)
Input: s, f and w arrays (indices 0..n).  Intervals are sorted according to finish times
Output: Maximum accumulated weight of non-overlapping intervals

Base case:
1. if j==0 return 0

Recursive case T(j):
1. T1 = w[j] + T(p[j])
2. T2 = T(j-1)
3. return max(T1,T2)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h3&gt;
  
  
  Scheduling via Dynamic Programming and Memoization
&lt;/h3&gt;

&lt;p&gt;From the recursion tree, we can see that the pseudo-code for running the &lt;code&gt;T&lt;/code&gt; function has an exponential time complexity of O(2$^n$).  From the tree, we can see how to optimize our code.  There are parameter values for which &lt;code&gt;T&lt;/code&gt; is computed more than once-- examples being &lt;code&gt;T(2)&lt;/code&gt;, &lt;code&gt;T(3)&lt;/code&gt;, etc. We can make it more efficient by storing all intermediate results and using those results when needed, rather than computing them again and again.  Here's the faster version of the pseudo-code, while using an additional array &lt;code&gt;M&lt;/code&gt; for memoization of maximum weights up to &lt;code&gt;n&lt;/code&gt;th interval.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Routine: TFast(j)
Input: f, s and w arrays (indices 0..n).  Intervals sorted according to finish times
Output: Maximum accumulated weight of non-overlapping intervals
Intermediate storage: Array M size (n+1) initialized to -1

Base case:
1. if j==0 
    M[0] = 0;
    return 0

Recursive case Tfast(j):
1. if M[j] != -1            //if result is stored
    return M[j]             //return the stored result
1. T1 = w[j] + TFast[p[j]]
2. T2 = TFast[j-1]
3. M[j] = max(T1, T2)
4. return M[j] 
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;The great thing about this code is that it would only compute &lt;code&gt;TFast&lt;/code&gt; for the required values of &lt;code&gt;j&lt;/code&gt;.  The tree below is the reduced tree when using &lt;code&gt;memoization&lt;/code&gt;.  The values are still propagated from leaf to root, but there is a drastic reduction in the size of this tree.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--3_hMtdI9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://storage.googleapis.com/algodailyrandomassets/curriculum/dynamic-programming/dp7a.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--3_hMtdI9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://storage.googleapis.com/algodailyrandomassets/curriculum/dynamic-programming/dp7a.png" alt="Weighted interval scheduling with memoization"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The figure shows the optimal weight array &lt;code&gt;M&lt;/code&gt;:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ww1Z-5vO--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://storage.googleapis.com/algodailyrandomassets/curriculum/dynamic-programming/dp8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ww1Z-5vO--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://storage.googleapis.com/algodailyrandomassets/curriculum/dynamic-programming/dp8.png" alt="Weighted interval scheduling with memoization"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Finding the Interval Set
&lt;/h3&gt;

&lt;p&gt;There is one thing left to do-- find out which intervals make up the optimal set.  We can use an additional array &lt;code&gt;X&lt;/code&gt;, which is a &lt;code&gt;Boolean&lt;/code&gt; array.  &lt;code&gt;X[j]&lt;/code&gt; indicates whether we included or excluded the interval &lt;code&gt;j&lt;/code&gt;, when computing the max.  We can fill up array &lt;code&gt;X&lt;/code&gt; as we fill up array &lt;code&gt;M&lt;/code&gt;.  Let's change &lt;code&gt;TFast&lt;/code&gt; to a new function &lt;code&gt;TFastX&lt;/code&gt; to do just that.&lt;/p&gt;

&lt;p&gt;We can retrieve the interval set using the predecessor array &lt;code&gt;p&lt;/code&gt; and the &lt;code&gt;X&lt;/code&gt; array.  Below is the pseudo-code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Routine: printIntervals
1. j=n
2. while (j&amp;gt;0)
    a. If X[j] == 1             //Is j to be included?
       i.     print j
       ii.    j = p[j]          //get predecessor of j 
        else
            j = j-1
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;The whole process is illustrated nicely in the figure below.  Note in this case too, the intervals are printed in descending order according to their finish times.  If you want them printed in reverse, then use a &lt;code&gt;stack&lt;/code&gt; like we did in the grid navigation problem.  That change should be trivial to make.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--UC6j1ESk--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://storage.googleapis.com/algodailyrandomassets/curriculum/dynamic-programming/dp9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--UC6j1ESk--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://storage.googleapis.com/algodailyrandomassets/curriculum/dynamic-programming/dp9.png" alt="Weighted interval scheduling array X"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Routine: TFastX(j)
Input: f,s and w arrays (indices 0..n).  Intervals sorted according to finish times
Output: Maximum accumulated weight of non-overlapping intervals
Intermediate storage: Array M size (n+1) initialized to -1,
                      Array X size (n+1) initialized to 0

Base case:
1. if j==0 
M[0] = 0;
X[0] = 0
return 0

Recursive case TfastX(j):
1. if M[j] != -1            // if result is stored
return M[j]                 // return the stored result
1. T1 = w[j] + TFast[p[j]]
2. T2 = TFast[j-1]
3. if (T1 &amp;gt; T2)
        X[j] = 1                    // include jth interval else X[j] remains 0
4. M[j] = max(T1, T2)
5. return M[j]
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h2&gt;
  
  
  Time Complexity of Weighted Interval Scheduling via Memoization
&lt;/h2&gt;

&lt;p&gt;The time complexity of the memoized version is &lt;code&gt;O(n)&lt;/code&gt;.  It is easy to see that each slot in the array is filled only once.  For each element of the array,  there are only two values to choose the maximum from-- thus the overall time complexity is &lt;code&gt;O(n)&lt;/code&gt;.  However, we assume that the intervals are &lt;strong&gt;already sorted&lt;/strong&gt; according to their finish times.  If we have unsorted intervals, then there is an additional overhead of sorting the intervals, which would require &lt;code&gt;O(n log n)&lt;/code&gt; computations.&lt;/p&gt;

&lt;p&gt;Well, that's it for now.  You can look at the &lt;a href="https://algodaily.com/challenges/the-coin-change-problem/description"&gt;Coin Change problem&lt;/a&gt; and &lt;a href="https://algodaily.com/challenges/longest-increasing-subsequence/description"&gt;Longest Increasing Subsequence&lt;/a&gt;  for more examples of dynamic programming.  I hope you enjoyed this tutorial as much as I did creating it!&lt;/p&gt;

&lt;p&gt;&lt;em&gt;This lesson was originally published at &lt;a href="https://algodaily.com/lessons/memoization-in-dynamic-programming"&gt;https://algodaily.com&lt;/a&gt;, where I maintain a technical interview course and write think-pieces for ambitious developers.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>tutorial</category>
      <category>codenewbie</category>
      <category>computerscience</category>
    </item>
    <item>
      <title>How Do We Get a Balanced Binary Tree?</title>
      <dc:creator>Jake Z.</dc:creator>
      <pubDate>Tue, 01 Sep 2020 02:44:13 +0000</pubDate>
      <link>https://dev.to/jacobjzhang/how-do-we-get-a-balanced-binary-tree-259e</link>
      <guid>https://dev.to/jacobjzhang/how-do-we-get-a-balanced-binary-tree-259e</guid>
      <description>&lt;h3&gt;
  
  
  Binary Trees
&lt;/h3&gt;

&lt;p&gt;A &lt;code&gt;binary tree&lt;/code&gt;, as the name suggests, is any &lt;code&gt;tree&lt;/code&gt; in which each node has at the most two child nodes.  A binary tree can be empty, implying zero nodes in the tree.  The cool thing about &lt;code&gt;binary trees&lt;/code&gt; is that they are recursive structures. This means a rule can be applied to the entire tree by applying it turn by turn to all of its subtrees.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ZfQvkxH_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://storage.googleapis.com/algodailyrandomassets/curriculum/trees/balanced-binary-tree-example1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ZfQvkxH_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://storage.googleapis.com/algodailyrandomassets/curriculum/trees/balanced-binary-tree-example1.png" class="img-fluid"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To define a binary tree, we need two data structures.  One would be the overall binary tree structure that keeps track of the root node.  The other would be the node structure that keeps track of the left and right subtrees.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;binaryTree&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;public:&lt;/span&gt;
    &lt;span class="n"&gt;node&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;root&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;//a pointer to the root&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Now let's define the node structure, which would keep track of both left and right child nodes, and contain a piece of data, which in this case we call the key.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;node&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;public:&lt;/span&gt;
    &lt;span class="n"&gt;node&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;left&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;//a pointer to the root of the left subtree&lt;/span&gt;
    &lt;span class="n"&gt;node&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;right&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;//a pointer to the root of the right subtree&lt;/span&gt;
    &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Here, we are assuming that key data type is an &lt;code&gt;integer&lt;/code&gt;, just to keep things simple.  But it should be noted that the &lt;code&gt;key&lt;/code&gt; type can be any data structure which allows comparison operators, i.e.., &amp;lt;, &amp;gt;, &amp;gt;=, &amp;lt;=, ==.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;This lesson was originally published at &lt;a href="https://algodaily.com/lessons/how-do-we-get-a-balanced-binary-tree"&gt;https://algodaily.com&lt;/a&gt;, where I maintain a technical interview course and write think-pieces for ambitious developers.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Binary Search Trees
&lt;/h2&gt;

&lt;p&gt;Binary search trees (or &lt;code&gt;BST&lt;/code&gt; for short) are a special case of binary trees, which have an added constraint on the placement of key values within the tree.  Very simply, a BST is defined by the following rule:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;All nodes in the left subtree have key values less than or equal to the key value of the parent&lt;/li&gt;
&lt;li&gt;All nodes in the right subtree have key values greater than or equal to the key value of the parent&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The figure below shows an example of a binary search tree:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--q2N2iozK--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://storage.googleapis.com/algodailyrandomassets/curriculum/trees/balanced-binary-tree-example2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--q2N2iozK--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://storage.googleapis.com/algodailyrandomassets/curriculum/trees/balanced-binary-tree-example2.png" class="img-fluid"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Balanced BST
&lt;/h2&gt;

&lt;p&gt;A &lt;code&gt;balanced BST&lt;/code&gt; is a BST in which the difference in heights of the left and right subtrees is not more than one (&lt;code&gt;1&lt;/code&gt;).  These example diagrams should make it clear.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--QxKfuU6s--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://storage.googleapis.com/algodailyrandomassets/curriculum/trees/balanced-binary-tree-balancedex1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--QxKfuU6s--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://storage.googleapis.com/algodailyrandomassets/curriculum/trees/balanced-binary-tree-balancedex1.png" class="img-fluid"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--6ONYpqvF--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://storage.googleapis.com/algodailyrandomassets/curriculum/trees/balanced-binary-tree-balancedex2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--6ONYpqvF--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://storage.googleapis.com/algodailyrandomassets/curriculum/trees/balanced-binary-tree-balancedex2.png" class="img-fluid"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  How to Balance a BST
&lt;/h2&gt;

&lt;p&gt;There exist balancing algorithms for a BST, e.g., &lt;code&gt;red black trees&lt;/code&gt; or &lt;code&gt;AVL trees&lt;/code&gt;. In these structures, the insertion and deletion of keys within the BST takes place in such a manner that the tree remains balanced.&lt;/p&gt;

&lt;p&gt;However, when given an &lt;code&gt;unbalanced&lt;/code&gt; tree, how do you convert it to a balanced tree in an efficient manner?  There is one very simple and efficient algorithm to do so by using arrays.  There are two steps involved:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Do an in-order traversal of the BST and store the values in an array.  The array values would be sorted in ascending order.&lt;/li&gt;
&lt;li&gt;Create a balanced BST tree from the sorted array.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;So there's two steps in our plan so far:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 1:&lt;/strong&gt; In-order Traversal&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 2:&lt;/strong&gt; Create a balanced BST&lt;/p&gt;

&lt;p&gt;Let's explore them. Pseudo-code to efficiently create a balanced BST is recursive, and both its base case and recursive case are given below:&lt;/p&gt;

&lt;h3&gt;
  
  
  Base case:
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;If the array is of size zero, then return the &lt;code&gt;null&lt;/code&gt; pointer and stop.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Recursive case:
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Define a &lt;code&gt;build&lt;/code&gt; method.&lt;/li&gt;
&lt;li&gt;Get the middle of the array and make it the root node.&lt;/li&gt;
&lt;li&gt;Call the recursive case &lt;code&gt;build&lt;/code&gt; on the left half of the array.  The root node’s left child is the pointer returned by this recursive call.
&lt;/li&gt;
&lt;li&gt;Call the recursive case &lt;code&gt;build&lt;/code&gt; on the right half of the array.  The root node’s right child is the pointer returned by this recursive call.
&lt;/li&gt;
&lt;li&gt;Return a pointer to the root node that was created in step 1.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The above pseudo-code's elegance stems from the fact that the tree itself is recursive. Thus, we can apply recursive procedures to it.  We apply the same thing over and over again to the left and right subtrees.&lt;/p&gt;

&lt;p&gt;You may be wondering how to get the middle of the array.  The simple formula &lt;code&gt;(size/2)&lt;/code&gt; returns the index of the middle item.  This of course assumes that the index of the array starts from &lt;code&gt;0&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Let's look at some examples to see how the previous pseudo code works.  We'll take a few simple scenarios and then build a more complex one.&lt;/p&gt;

&lt;h4&gt;
  
  
  Array: [30]
&lt;/h4&gt;

&lt;p&gt;First we look at the following array with just one element (i.e. &lt;code&gt;30&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--9ppcXNg2--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://storage.googleapis.com/algodailyrandomassets/curriculum/trees/balanced-binary-tree-bst1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--9ppcXNg2--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://storage.googleapis.com/algodailyrandomassets/curriculum/trees/balanced-binary-tree-bst1.png" class="img-fluid"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Array: [31, 37, 38]
&lt;/h4&gt;

&lt;p&gt;Now let's look at an array of size 3.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--zW2KvfQl--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://storage.googleapis.com/algodailyrandomassets/curriculum/trees/balanced-binary-tree-bst3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--zW2KvfQl--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://storage.googleapis.com/algodailyrandomassets/curriculum/trees/balanced-binary-tree-bst3.png" class="img-fluid"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Array: [10, 11]
&lt;/h4&gt;

&lt;p&gt;Let us now go for an even sized array with two elements.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--yE5iHtct--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://storage.googleapis.com/algodailyrandomassets/curriculum/trees/balanced-binary-tree-bst2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--yE5iHtct--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://storage.googleapis.com/algodailyrandomassets/curriculum/trees/balanced-binary-tree-bst2.png" class="img-fluid"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Array: [10, 11, 17, 19]
&lt;/h4&gt;

&lt;p&gt;We can now extend the example to an even sized array with four elements.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--_GKA1WcV--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://storage.googleapis.com/algodailyrandomassets/curriculum/trees/balanced-binary-tree-bst4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--_GKA1WcV--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://storage.googleapis.com/algodailyrandomassets/curriculum/trees/balanced-binary-tree-bst4.png" class="img-fluid"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Array: [10, 11, 17, 19, 30, 31, 37, 38]
&lt;/h4&gt;

&lt;p&gt;An even sized array with eight elements.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--0HGNK-7k--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://storage.googleapis.com/algodailyrandomassets/curriculum/trees/balanced-binary-tree-bst8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--0HGNK-7k--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://storage.googleapis.com/algodailyrandomassets/curriculum/trees/balanced-binary-tree-bst8.png" class="img-fluid"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now that we understand how balancing works, we can do the fun part, which is coding.  Here is the C++ helper function, which is the recursive routine &lt;code&gt;build&lt;/code&gt; that we had defined earlier.&lt;/p&gt;

&lt;p&gt;The code below shows how you can call the above helper recursive function &lt;code&gt;build&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;build&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;binaryTree&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;tree&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;tree&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;root&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;build&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;





&lt;div class="highlight"&gt;&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="c1"&gt;// build returns a pointer to the root node of the sub-tree&lt;/span&gt;
&lt;span class="c1"&gt;// lower is the lower index of the array&lt;/span&gt;
&lt;span class="c1"&gt;// upper is the upper index of the array&lt;/span&gt;
&lt;span class="n"&gt;node&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nf"&gt;build&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;lower&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;upper&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;size&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;upper&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;lower&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="c1"&gt;// cout &amp;lt;&amp;lt; size; //uncomment in case you want to see how it's working&lt;/span&gt;
  &lt;span class="c1"&gt;// base case: array of size zero&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;size&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="c1"&gt;// recursive case&lt;/span&gt;
  &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;middle&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;size&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;lower&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="c1"&gt;// make sure you add the offset of lower&lt;/span&gt;
  &lt;span class="c1"&gt;//  cout &amp;lt;&amp;lt; arr[middle] &amp;lt;&amp;lt; " "; //uncomment in case you want to see how it's working&lt;/span&gt;
  &lt;span class="n"&gt;node&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;subtreeRoot&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;node&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="n"&gt;subtreeRoot&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;middle&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
  &lt;span class="n"&gt;subtreeRoot&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;left&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;build&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;lower&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;middle&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="n"&gt;subtreeRoot&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;right&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;build&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;middle&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;upper&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;subtreeRoot&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Before trying out the above code, it is always best to sit down with a paper and pen, and conduct a dry run of the code a few times to see how it works.  The previous code has a complexity of &lt;code&gt;O(N)&lt;/code&gt;, where &lt;code&gt;N&lt;/code&gt; is the number of keys in the tree.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Inorder traversal&lt;/code&gt; requires &lt;code&gt;O(N)&lt;/code&gt; time. As we are accessing each element of the array exactly once, the &lt;code&gt;build&lt;/code&gt; method thus also has a time complexity of &lt;code&gt;O(N)&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;This lesson was originally published at &lt;a href="https://algodaily.com/lessons/how-do-we-get-a-balanced-binary-tree"&gt;https://algodaily.com&lt;/a&gt;, where I maintain a technical interview course and write think-pieces for ambitious developers.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>computerscience</category>
      <category>beginners</category>
      <category>career</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Getting Your First Software Job Without Professional Experience</title>
      <dc:creator>Jake Z.</dc:creator>
      <pubDate>Thu, 27 Aug 2020 13:45:47 +0000</pubDate>
      <link>https://dev.to/jacobjzhang/getting-your-first-software-job-without-professional-experience-2dkb</link>
      <guid>https://dev.to/jacobjzhang/getting-your-first-software-job-without-professional-experience-2dkb</guid>
      <description>&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/aPIqpFGF0QI"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;I’ve had a few friends recently ask me about breaking into the software industry. Most have been looking for advice on getting a developer job at a consumer-facing web/internet company-- though places like Tesla and WeWork are also very popular.&lt;/p&gt;

&lt;p&gt;These friends have probably heard about the amazing slew of benefits; like interesting work, smart and passionate colleagues, and free food/snacks/alcohol galore. It doesn’t hurt that compensation is usually above market at these companies, and career prospects are second-to-none for talented technologists.&lt;/p&gt;

&lt;p&gt;There’s already an abundance of information out there on obtaining software engineering jobs, but much of the advice is geared towards people who have experience already. Technical interview prep is important only if you can even get the interview.&lt;/p&gt;

&lt;p&gt;If you've never worked in software, breaking in can be challenging unless approached the right way. Here’s a few tips that are less common that have helped me and others in the past.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;This lesson was originally published at &lt;a href="https://algodaily.com/lessons/getting-your-first-software-job-without-professional-experience"&gt;https://algodaily.com&lt;/a&gt;, where I maintain a technical interview course and write think-pieces for ambitious developers.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s---NUNBU9i--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.stocksnap.io/img-thumbs/960w/B6GYMTH73U.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s---NUNBU9i--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.stocksnap.io/img-thumbs/960w/B6GYMTH73U.jpg" class="img-fluid" alt="Typing away for a better career"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  First: You Don’t Need to Code
&lt;/h2&gt;

&lt;p&gt;Just getting this out of the way: many people forget that you don't need to code to break into the software industry. It’s pretty amazing that there's still the notion that software businesses are just engineers cranking away in text editors. The most successful tech companies usually have talented engineers, but also wonderful managers, sales reps, customer success advocates, product managers, marketing wizards, designers, and writers.&lt;/p&gt;

&lt;p&gt;You may need to cater your craft and experience a bit towards software : for example, focusing a bit more on SEO and digital advertising if you are a person who loves to write. However, know there’s always a place for existing talents.&lt;/p&gt;

&lt;p&gt;But if you're sure you want to pursue software engineering...&lt;/p&gt;

&lt;h2&gt;
  
  
  That First Gig is the Hardest
&lt;/h2&gt;

&lt;p&gt;The most frustrating part for new entrants into tech is the dichotomy in the job search for newcomers versus experienced candidates.&lt;/p&gt;

&lt;p&gt;I said earlier that most articles and blog posts about getting a software engineering job is geared towards those with experience. With the tech job market being so hot, senior candidates usually have several options (or even offers in hand) for where they want to go and what they want to do.&lt;/p&gt;

&lt;p&gt;This obviously isn’t true for one’s first tech job search. There will certainly be some initial pain, and it could take a while. It might be beneficial to note that an amazing aspect of the industry is how fast one can “level up”. It’s defeating to initially be rejected from dozens of entry-level positions, for sure. But once you’re in, a bit of hustle and hard work to cultivate experience will lead to a much easier path down the road.&lt;/p&gt;

&lt;p&gt;Now how to get this experience if you don't have any? Here are some ways.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--RAkOmD6b--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.stocksnap.io/img-thumbs/960w/HQV6HVSTAW.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--RAkOmD6b--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.stocksnap.io/img-thumbs/960w/HQV6HVSTAW.jpg" class="img-fluid" alt="Typing away for a better career"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Get An Internship
&lt;/h2&gt;

&lt;p&gt;If you're in university, the traditional route is to get an internship via your school's recruiting office. The process is almost identical to getting a full time position -- an application, and a few rounds of behavioral and technical interviews. These internships often convert to full-time positions through a return offer.&lt;/p&gt;

&lt;p&gt;However, you probably wouldn't be reading this article if you're in this boat, so how else might you build your resume?&lt;/p&gt;

&lt;h2&gt;
  
  
  Get Experience Via Your Own Projects
&lt;/h2&gt;

&lt;p&gt;One thing a lot of people miss out on is how impressive it is to build a full-fledged application by yourself. If you're able to make a frontend talk to a backend, back it up with a database, and maybe even optimize performance a bit-- you're doing the software engineering work of an entire team!&lt;/p&gt;

&lt;p&gt;The other benefit people don't realize about personal or side projects is this: despite not having your code reviewed by others, you do end up learning a lot of maintainable patterns and good habits.&lt;/p&gt;

&lt;p&gt;This is because it's ultimately &lt;strong&gt;you&lt;/strong&gt; that will need to do the maintenance of the code-- so you quickly learn not to write spaghetti code or do a quick and dirty job. In a sense, you learn the &lt;em&gt;why&lt;/em&gt; behind good naming, shorter methods, clean separation of classes, etc.-- because you end up feeling the pain when you don't stick to good coding standards.&lt;/p&gt;

&lt;p&gt;These projects are great things you can add under your resume as experience-- especially if you are able to generate revenue from it. And if you can grow it to something like &lt;a href="https://www.indiehackers.com/blog/acquired-by-stripe"&gt;IndieHackers.com -- jobs might just come to you&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Do Some Contract Work
&lt;/h2&gt;

&lt;p&gt;Another way is to start consulting and do some contract work. Visit temp agencies and freelance websites. Many of the clientele care less about your resume and more about your portfolio. &lt;/p&gt;

&lt;p&gt;Additionally, it's a great source of income until you land a full-time job-- though you may have to charge less at first. It's also not rare to hear of the client hiring the consultant or contractor via a temp-to-perm role, especially if you demonstrate that you're providing a return on their investment.&lt;/p&gt;

&lt;p&gt;If you've been building stuff for yourself, it may be enough to snag a contracting gig that you can then put on your resume. Many people are drawn to the variety that full-time consulting or contracting offers, and make an entire career out of this.&lt;/p&gt;

&lt;h2&gt;
  
  
  Contribute to Open Source Software
&lt;/h2&gt;

&lt;p&gt;Another underrated way of getting experience is through contributions to open source software. Not only does it integrate you into a software engineering team (allowing you to build collaboration skills) and get generally valuable experience to trade up, but you also get to work on something that you or others use!&lt;/p&gt;

&lt;p&gt;Again, it's also not unheard of-- but certainly not common-- for strong OSS contributors to get hired by a firm after they've worked on the company's software for free. The author of &lt;a href="https://overreacted.io/"&gt;Redux, Dan Abramov, is a good example&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Put Yourself Out There and Meet People
&lt;/h2&gt;

&lt;p&gt;I used to be of the opinion that heads-down good work would always speak for itself. However, much like a good SaaS product needs to focus just as much on marketing/sales as on the product itself, a new technologist needs to make sure that their work is getting recognized and heard about.&lt;/p&gt;

&lt;p&gt;On the job-front side, this means asking people for informational coffees and referrals (most people will say yes!), building a portfolio and asking for feedback, and tracking down every lead and opportunity to show off your talents.&lt;/p&gt;

&lt;p&gt;Conferences and meetups are great for meeting others who are interested in the same thing you are. They often also lead to opportunities if you are a presenter, or even if you simply strike up the right conversation.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Domain Matters
&lt;/h2&gt;

&lt;p&gt;Something to note-- an AdTech (advertising-technology) firm will have different values, cultures, goals, and people than a FinTech (financial-technology). The engineering groups will be especially different in terms of pace of work, culture, and dress code.&lt;/p&gt;

&lt;p&gt;Working at Jane Street is a completely different experience than working at Etsy. Be careful when generalizing the software industry, and look for opportunities aligned to your personality and interests. You can also use this to your advantage. If you are coming to software from a different industry, &lt;em&gt;your past relevant experience is extremely valuable&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Think about it-- a large part of the job of a developer is to translate business requirements into logic. If you already know the requirements; whether it be finance, the law, compliance, medicine, biology, mathematics, or even music; your vantage point will be strongly appreciated as a software engineer.&lt;/p&gt;

&lt;p&gt;If you're coming from finance, look at fintech startups or software engineering roles at banks. Or if you used to make music, Spotify or Pandora might be more willing to give you a interview when you talk about how you built a music collection app in your spare time. At the very least, you'll be able to connect to the product more.&lt;/p&gt;

&lt;h2&gt;
  
  
  It Could Take a While
&lt;/h2&gt;

&lt;p&gt;Friends who are eager to get into a tech company for the first time as developers often overlook how long it takes to succeed. I've worked with brilliant engineers who took a while to get their first job-- unfortunately, with all things, there is an element of luck involved.&lt;/p&gt;

&lt;p&gt;In today's job climate, provided you keep improving your resume, it could take anywhere from one to six months to land something after graduating from school or a bootcamp. If you've been building up your resume with personal projects, contract/consulting work, and OSS projects-- and it takes longer than six months-- you should try to identify what the biggest blocker might be.&lt;/p&gt;

&lt;p&gt;Past that, it takes about a year to get really comfortable with basic syntax and getting things up and running, and three to five years to deeply understand how software systems/architectures work and make important technical decisions. Though these numbers drastically vary, this is what I've seen anecdotally.&lt;/p&gt;

&lt;h2&gt;
  
  
  Always Be Learning (The Fundamentals)
&lt;/h2&gt;

&lt;p&gt;One last thing once you get the first software job-- the change of pace in the industry takes a while to adapt to .&lt;/p&gt;

&lt;p&gt;For an example that afflicts web developers in particular, google “Javascript Fatigue”. However, what you’ll find is that trends tend to come up hard and fast, but most don’t stick.&lt;/p&gt;

&lt;p&gt;If you’re a developer, the core data structures (lists, stacks, graphs, etc.), the most common algorithms/patterns, and good OOP design patterns have been around forever, and most new ideas are just re-implementations with slight tweaks.&lt;/p&gt;

&lt;p&gt;Similarly, if you’re in engineering management-- building relationships, understanding the competitive landscape, and talking to your reports are things that will always be useful and never really go away.&lt;/p&gt;

&lt;p&gt;I make this point because landing your second software job will be less about "does this person have experience" and more about "what does this person bring to the table with their experience".&lt;/p&gt;

&lt;p&gt;With all that said, though software technology is getting a lot of buzz at the moment, there are numerous industries and professions that are just as enjoyable and meaningful to be in.&lt;/p&gt;

&lt;p&gt;Hope this helps someone break in this year. Being a developer is an awesome blessing, and I encourage everyone to try it out and see if they like it.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;This lesson was originally published at &lt;a href="https://algodaily.com/lessons/getting-your-first-software-job-without-professional-experience"&gt;https://algodaily.com&lt;/a&gt;, where I maintain a technical interview course and write think-pieces for ambitious developers.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>career</category>
      <category>webdev</category>
      <category>beginners</category>
      <category>codenewbie</category>
    </item>
    <item>
      <title>How to Implement a Hash Map</title>
      <dc:creator>Jake Z.</dc:creator>
      <pubDate>Tue, 25 Aug 2020 22:17:11 +0000</pubDate>
      <link>https://dev.to/jacobjzhang/how-to-implement-a-hash-map-3jm3</link>
      <guid>https://dev.to/jacobjzhang/how-to-implement-a-hash-map-3jm3</guid>
      <description>&lt;p&gt;Arrays are amazing for looking up elements at specific indices as all elements in memory are contiguous, allowing for &lt;code&gt;O(1)&lt;/code&gt; or constant time lookups. But often we don't, or can't, perform lookups via indices. Hash maps and hash tables are a way around this, enabling us to lookup via &lt;code&gt;keys&lt;/code&gt; instead.&lt;/p&gt;

&lt;p&gt;Can you implement the  &lt;code&gt;Map&lt;/code&gt; class from scratch? Only two methods are necessary-- &lt;code&gt;get&lt;/code&gt; and &lt;code&gt;set&lt;/code&gt;. Many programming languages have a built-in hash or dictionary primitive (like &lt;code&gt;Javascript&lt;/code&gt; &lt;code&gt;Object&lt;/code&gt;s  and &lt;code&gt;{}&lt;/code&gt; notation), but we don't want to use that for this exercise.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;This lesson was originally published at &lt;a href="https://algodaily.com/challenges/implement-a-hash-map"&gt;https://algodaily.com&lt;/a&gt;, where I maintain a technical interview course and write think-pieces for ambitious developers.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--4slSG1cw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://storage.googleapis.com/algodailyrandomassets/curriculum/hash-maps/implement-a-hash-map-1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--4slSG1cw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://storage.googleapis.com/algodailyrandomassets/curriculum/hash-maps/implement-a-hash-map-1.png" class="img-fluid"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; Regular &lt;code&gt;Javascript&lt;/code&gt; objects and the &lt;code&gt;Map&lt;/code&gt; class are both simple key-value hash tables/associative arrays, with a few key differences:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;A &lt;code&gt;Map&lt;/code&gt; object can iterate through its elements in insertion order, whereas JavaScript's &lt;code&gt;Object&lt;/code&gt;s don't guarantee order. In addition, &lt;code&gt;Object&lt;/code&gt;s have default keys due to their prototype, and &lt;code&gt;Map&lt;/code&gt;s don't come with default keys. &lt;a href="https://medium.com/front-end-weekly/es6-map-vs-object-what-and-when-b80621932373"&gt;Here's a good breakdown&lt;/a&gt; of the two. For the purpose of this exercise, let's assume the same functionality for both.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;For the two methods you'll define:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;code&gt;get(key: string)&lt;/code&gt; should be given a key, and return the value for that key.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;set(key: string, val: string)&lt;/code&gt; should take a key and a value as parameters, and store the pair.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Additionally, we've supplied the below hashing function &lt;code&gt;hashStr&lt;/code&gt;. It tries to avoid collision, but is not perfect. It takes in a string value and returns an integer.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;hashStr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;finalHash&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nx"&gt;str&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;charCode&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;str&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;charCodeAt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nx"&gt;finalHash&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="nx"&gt;charCode&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;finalHash&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;hashStr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;testKey&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Let's call our new class the &lt;code&gt;Hashmap&lt;/code&gt; class, and use it like such:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;m&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Hashmap&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="nx"&gt;m&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;name&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Jake&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;m&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;name&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;






&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/0pzYAOLZgqg"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;Let's begin by revisiting how a general hash table works, the theory being what our &lt;code&gt;Hashmap&lt;/code&gt; &lt;code&gt;data structure&lt;/code&gt; will be based off. As we've noted, in many programming languages, there is a &lt;code&gt;Hashmap&lt;/code&gt; class that's based off a legacy &lt;code&gt;Hashtable&lt;/code&gt;. Let's step through our suggested implementation of this code.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--O1ek0ELi--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://storage.googleapis.com/algodailyrandomassets/curriculum/hash-maps/implement-a-hash-map-2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--O1ek0ELi--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://storage.googleapis.com/algodailyrandomassets/curriculum/hash-maps/implement-a-hash-map-2.png" class="img-fluid"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So we know that hash tables work by storing data in buckets. To access those buckets, we'll need a way to convert a &lt;code&gt;key&lt;/code&gt; to an bucket number. (The buckets can be modeled using both arrays and &lt;a href="https://dev.to/lessons/binary-search-technique"&gt;&lt;code&gt;binary search&lt;/code&gt;&lt;/a&gt; trees, but to keep things simple and maximize speed, we'll stick with using arrays.)&lt;/p&gt;

&lt;p&gt;Using keys decouples us from having to know where the data is in the array. Our &lt;code&gt;data structure&lt;/code&gt; thus needs a hash function, provided in this case as &lt;code&gt;hashStr&lt;/code&gt;, to calculate an &lt;code&gt;index&lt;/code&gt; into &lt;code&gt;buckets&lt;/code&gt; where the wanted value is stored. We're essentially mapping the &lt;code&gt;key&lt;/code&gt; to an array index via our &lt;code&gt;hashStr&lt;/code&gt; hash function.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;hashStr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;r&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;// 114&lt;/span&gt;

&lt;span class="c1"&gt;// array = [  _  ,  X  ,  _  ,  _ ]&lt;/span&gt;
&lt;span class="c1"&gt;// index     113   114   115   116&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;As you can see, all &lt;code&gt;hashStr&lt;/code&gt; does is take the &lt;code&gt;key&lt;/code&gt; provided in &lt;code&gt;set()&lt;/code&gt;, and computes a location for us. We'll thus need another &lt;code&gt;data structure&lt;/code&gt; for the actual storage and buckets that the values are placed. Of course, you already know it's an array!&lt;/p&gt;

&lt;h3&gt;
  
  
  Fill In
&lt;/h3&gt;

&lt;p&gt;The slots or buckets of a hash table are usually stored in an _______ and its indices.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Solution:&lt;/strong&gt; Array&lt;/p&gt;




&lt;p&gt;A good start to writing the class is to initialize it with just the storage array:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nx"&gt;Hashmap&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;_storage&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[];&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;We'll use the returned index of &lt;code&gt;hashStr&lt;/code&gt; to decide where the entered value should go in &lt;code&gt;this._storage&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;A word on a collisions&lt;/em&gt;: &lt;code&gt;collisions&lt;/code&gt; are when a hash function returns the same index for more than one key and are out of the scope of this question. However, there are ways to handle such issues using additional data structures.&lt;/p&gt;

&lt;h3&gt;
  
  
  Multiple Choice
&lt;/h3&gt;

&lt;p&gt;Which of the following is a solution for collisions in a hash table implementation?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;There is no good solution for collisions, the hash function must be unique&lt;/li&gt;
&lt;li&gt;Use separate chaining, often with a linked list, where the index of the array consists of a chain of values&lt;/li&gt;
&lt;li&gt;Use a trie to store values at every index&lt;/li&gt;
&lt;li&gt;Concatenate all the values as one single string at that bucket&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Solution:&lt;/strong&gt; Use separate chaining, often with a linked list, where the index of the array consists of a chain of values&lt;/p&gt;




&lt;p&gt;At this point, we have our building blocks, so let's go ahead and implement the &lt;code&gt;set&lt;/code&gt; method. The method will:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;take the &lt;code&gt;key&lt;/code&gt; passed&lt;/li&gt;
&lt;li&gt;run it through the hash function, and&lt;/li&gt;
&lt;li&gt;set the value in our &lt;code&gt;storage&lt;/code&gt; at that particular index&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Notice the way we're storing it as well: each index in &lt;code&gt;this._storage&lt;/code&gt; (&lt;code&gt;this._storage[idx]&lt;/code&gt;) is itself an array, thereby primitively solving for the collision problem.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;val&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;idx&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;hashStr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;_storage&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;idx&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;_storage&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;idx&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[];&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;_storage&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;idx&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;push&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;val&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;set&lt;/code&gt; method now seems pretty straightforward, right?&lt;/p&gt;

&lt;p&gt;It's the same concept with our &lt;code&gt;get&lt;/code&gt; method. What we're doing there is also running the passed &lt;code&gt;key&lt;/code&gt; through the &lt;code&gt;hashStr&lt;/code&gt; method, but instead of setting, we'll go to the resulting index and retrieve the value.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;  &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;keyVal&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;_storage&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;idx&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;keyVal&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;keyVal&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;One caveat we should note is that it's possible to pass a key that doesn't exist (or has not been &lt;code&gt;set&lt;/code&gt;), so we should handle that by returning &lt;code&gt;undefined&lt;/code&gt; if that's the case.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;idx&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;hashStr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;_storage&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;idx&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;undefined&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;keyVal&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;_storage&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;idx&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;keyVal&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;keyVal&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;That should about do it! Let's try it out.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nx"&gt;Hashmap&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;_storage&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[];&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nx"&gt;hashStr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;finalHash&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nx"&gt;str&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;charCode&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;str&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;charCodeAt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="nx"&gt;finalHash&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="nx"&gt;charCode&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;finalHash&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="kd"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;val&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;idx&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;hashStr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;_storage&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;idx&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;_storage&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;idx&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[];&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;_storage&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;idx&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;push&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;val&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="kd"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;idx&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;hashStr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;_storage&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;idx&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;undefined&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;keyVal&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;_storage&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;idx&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;keyVal&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;keyVal&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;&lt;em&gt;This lesson was originally published at &lt;a href="https://algodaily.com/challenges/implement-a-hash-map"&gt;https://algodaily.com&lt;/a&gt;, where I maintain a technical interview course and write think-pieces for ambitious developers.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>computerscience</category>
      <category>tutorial</category>
      <category>beginners</category>
    </item>
    <item>
      <title>How to Validate a Palindrome</title>
      <dc:creator>Jake Z.</dc:creator>
      <pubDate>Mon, 24 Aug 2020 21:33:48 +0000</pubDate>
      <link>https://dev.to/jacobjzhang/how-to-validate-a-palindrome-1p5a</link>
      <guid>https://dev.to/jacobjzhang/how-to-validate-a-palindrome-1p5a</guid>
      <description>&lt;p&gt;Given a string &lt;code&gt;str&lt;/code&gt;, can you write a method that will return &lt;code&gt;True&lt;/code&gt; if is a palindrome and &lt;code&gt;False&lt;/code&gt; if it is not? If you'll recall, a &lt;code&gt;palindrome&lt;/code&gt; is defined as "a word, phrase, or sequence that reads the same backward as forward". For now, assume that we will not have input strings that contain special characters or spaces, so the following examples hold:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;str&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;thisisnotapalindrome&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nx"&gt;isPalindrome&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;str&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="c1"&gt;// false&lt;/span&gt;

&lt;span class="nx"&gt;str&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;racecar&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nx"&gt;isPalindrome&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;str&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="c1"&gt;// true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;For an extra challenge, try to ignore non-alphanumerical characters. The final solution that we present will handle all edge cases.&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/_PfJ7dWGCAc"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;&lt;em&gt;This lesson was originally published at &lt;a href="https://algodaily.com/challenges/validate-palindrome"&gt;https://algodaily.com&lt;/a&gt;, where I maintain a technical interview course and write think-pieces for ambitious developers.&lt;/em&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  True or False?
&lt;/h3&gt;

&lt;p&gt;A string is defined as a palindrome if the reversal of the string is equal to the original string.&lt;/p&gt;

&lt;p&gt;For example, “toot” is a palindrome, but “boot” is not.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Solution:&lt;/strong&gt; True&lt;/p&gt;




&lt;p&gt;This is a classic question, and there are multiple ways to solve this. For the sake of learning, let's cover all of them!&lt;/p&gt;

&lt;h3&gt;
  
  
  Using built-in methods
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--S45KWds7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://storage.googleapis.com/algodailyrandomassets/curriculum/easy-strings/validate-palindrome.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--S45KWds7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://storage.googleapis.com/algodailyrandomassets/curriculum/easy-strings/validate-palindrome.png" class="img-fluid"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This would probably be invalid in an actual interview, but you can rely on the built-in &lt;code&gt;String&lt;/code&gt; method to accomplish a quick reversal. In Javascript, you can simply call &lt;code&gt;reverse()&lt;/code&gt; and in Python, you can call &lt;code&gt;[::-1]&lt;/code&gt; You can then compare the reversed string to the original:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;isPalindrome&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Calling reverse function&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;reversed&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;str&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;reverse&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nx"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="c1"&gt;// Checking if both strings are equal or not&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;str&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="nx"&gt;reversed&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;isPalindrome&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;racecar&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h3&gt;
  
  
  Order
&lt;/h3&gt;

&lt;p&gt;What's the order of successfully finding out if a string is a palindrome?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Open a while loop to perform while low is less than high&lt;/li&gt;
&lt;li&gt;Continue until end of loop and return true&lt;/li&gt;
&lt;li&gt;Define two variables: high and low, as 0 and (length of string - 1)&lt;/li&gt;
&lt;li&gt;If `string[low]` does not equal `string[high]`, return false. Increment low, decrement high&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Solution:&lt;/strong&gt; &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Continue until end of loop and return true&lt;/li&gt;
&lt;li&gt;If `string[low]` does not equal `string[high]`, return false. Increment low, decrement high&lt;/li&gt;
&lt;li&gt;Open a while loop to perform while low is less than high&lt;/li&gt;
&lt;li&gt;Define two variables: high and low, as 0 and (length of string - 1)&lt;/li&gt;
&lt;/ol&gt;




&lt;h3&gt;
  
  
  Multiple Choice
&lt;/h3&gt;

&lt;p&gt;What will the following pseudocode do to an input string?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;reverse_str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
  &lt;span class="n"&gt;start&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
  &lt;span class="n"&gt;end&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;
  &lt;span class="n"&gt;str_copy&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;letter&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;letter&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="n"&gt;start&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;end&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;temp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;str_copy&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;start&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="n"&gt;str_copy&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;start&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;str_copy&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;end&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="n"&gt;str_copy&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;end&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;temp&lt;/span&gt;
    &lt;span class="n"&gt;start&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
    &lt;span class="n"&gt;end&lt;/span&gt; &lt;span class="o"&gt;-=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;""&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;str_copy&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Make a copy&lt;/li&gt;
&lt;li&gt;Reverse the string&lt;/li&gt;
&lt;li&gt;Swap the first and last letters&lt;/li&gt;
&lt;li&gt;Infinite loop&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Solution:&lt;/strong&gt; Reverse the string&lt;/p&gt;




&lt;h3&gt;
  
  
  With a while loop:
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--d0DBpwsO--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://storage.googleapis.com/algodailyrandomassets/curriculum/easy-strings/validate-palindrome-1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--d0DBpwsO--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://storage.googleapis.com/algodailyrandomassets/curriculum/easy-strings/validate-palindrome-1.png" class="img-fluid"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We can cut down on the number of operations by recognizing that we don't need to do &lt;code&gt;len(str)-1&lt;/code&gt; iterations. Instead of using just one pointer that simply iterates through the string from its end, why not use two?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;isPalindrome&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;left&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;right&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;str&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;leftChar&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;rightChar&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;left&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nx"&gt;right&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;leftChar&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;str&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;charAt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;left&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nx"&gt;rightChar&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;str&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;charAt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;right&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;leftChar&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="nx"&gt;rightChar&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nx"&gt;left&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="nx"&gt;right&lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;isPalindrome&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;racecar&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;What we're doing above is specifying two pointers, &lt;code&gt;start&lt;/code&gt; and &lt;code&gt;end&lt;/code&gt;. &lt;code&gt;start&lt;/code&gt; points to the beginning of the string, and &lt;code&gt;end&lt;/code&gt; is a pointer to the last character. Taking the example input &lt;code&gt;racecar&lt;/code&gt;, as we run through it, these are the comparisons we'll see:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;racecar
^     ^
racecar
 ^   ^
racecar
  ^ ^
racecar
   ^
True
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h3&gt;
  
  
  Multiple Choice
&lt;/h3&gt;

&lt;p&gt;What is the run time of the following code?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;reverse_str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
  &lt;span class="n"&gt;start&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
  &lt;span class="n"&gt;end&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;
  &lt;span class="n"&gt;str_copy&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;letter&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;letter&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="n"&gt;start&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;end&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;temp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;str_copy&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;start&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="n"&gt;str_copy&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;start&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;str_copy&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;end&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="n"&gt;str_copy&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;end&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;temp&lt;/span&gt;
    &lt;span class="n"&gt;start&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
    &lt;span class="n"&gt;end&lt;/span&gt; &lt;span class="o"&gt;-=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;""&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;str_copy&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;O(log n)&lt;/li&gt;
&lt;li&gt;O(n)&lt;/li&gt;
&lt;li&gt;O(n log n)&lt;/li&gt;
&lt;li&gt;O(n^2)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Solution:&lt;/strong&gt; O(n)&lt;/p&gt;




&lt;h3&gt;
  
  
  Final Solution
&lt;/h3&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;isPalindrome&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;str&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nx"&gt;str&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;""&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;left&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;right&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;str&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;leftChar&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;rightChar&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;left&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nx"&gt;right&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;leftChar&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;str&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;charAt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;left&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;toLowerCase&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
      &lt;span class="nx"&gt;rightChar&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;str&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;charAt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;right&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;toLowerCase&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

      &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;isAlphaNumeric&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;leftChar&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;isAlphaNumeric&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;rightChar&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;leftChar&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="nx"&gt;rightChar&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="nx"&gt;left&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
          &lt;span class="nx"&gt;right&lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;isAlphaNumeric&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;leftChar&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="nx"&gt;left&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;isAlphaNumeric&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;rightChar&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="nx"&gt;right&lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;isAlphaNumeric&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;c&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="se"&gt;[^&lt;/span&gt;&lt;span class="sr"&gt;a-zA-Z0-9&lt;/span&gt;&lt;span class="se"&gt;]&lt;/span&gt;&lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;c&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;isPalindrome&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;A Santa Lived As a Devil At NASA&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Check out more visual tutorials for &lt;a href="https://algodaily.com/curriculum"&gt;technical challenges at AlgoDaily.com&lt;/a&gt; and try out &lt;a href="https://algodaily.com/challenges/daily"&gt;our daily coding problem newsletter&lt;/a&gt;!&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>computerscience</category>
      <category>tutorial</category>
      <category>beginners</category>
    </item>
    <item>
      <title>How to Get the Intersection of Two Arrays</title>
      <dc:creator>Jake Z.</dc:creator>
      <pubDate>Sat, 22 Aug 2020 16:11:00 +0000</pubDate>
      <link>https://dev.to/jacobjzhang/get-the-intersection-of-two-arrays-2cc2</link>
      <guid>https://dev.to/jacobjzhang/get-the-intersection-of-two-arrays-2cc2</guid>
      <description>&lt;p&gt;Oftentimes, interviewers will test you on things that are deceptively easy. We saw this in &lt;a href="https://algodaily.com/challenges/reverse-a-string" rel="noopener noreferrer"&gt;Reverse a String&lt;/a&gt;, and will see more in future challenges. But sometimes you might get tested on a concept that, while a bit trivial, is really useful in day to day software engineering.&lt;/p&gt;

&lt;p&gt;One of those things is &lt;code&gt;array manipulation&lt;/code&gt;, or basically doing things to an &lt;code&gt;array&lt;/code&gt; that creates some kind of transformation.&lt;/p&gt;

&lt;h2&gt;
  
  
  Prompt
&lt;/h2&gt;

&lt;p&gt;Can you write a function that &lt;strong&gt;takes two arrays as inputs&lt;/strong&gt; and returns to us their intersection? Let's return the intersection in the form of an array. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fstorage.googleapis.com%2Falgodailyrandomassets%2Fcurriculum%2Farrays%2Farray-intersection.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fstorage.googleapis.com%2Falgodailyrandomassets%2Fcurriculum%2Farrays%2Farray-intersection.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Note that all elements in the final result should be unique. Here's one example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;nums1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;nums2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;

&lt;span class="nf"&gt;intersection&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;nums1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;nums2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="c1"&gt;// [2]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And here's another one:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;nums1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;nums2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;

&lt;span class="nf"&gt;intersection&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;nums1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;nums2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="c1"&gt;// [9, 4]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;This lesson was originally published at &lt;a href="https://algodaily.com/challenges/array-intersection" rel="noopener noreferrer"&gt;https://algodaily.com&lt;/a&gt;, where I maintain a technical interview course and write think-pieces for ambitious developers.&lt;/em&gt;&lt;/p&gt;




&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/81lQHoHw2jA"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;h2&gt;
  
  
  Brute Force
&lt;/h2&gt;

&lt;p&gt;We'll start off slowly, by using the smallest sample inputs possible to examine the make-up of the problem. We know we'll need a &lt;code&gt;result&lt;/code&gt; array to return, so hold that in mind:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;results&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[];&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's say we need to find the intersection of two arrays: &lt;code&gt;[1]&lt;/code&gt; and &lt;code&gt;[1]&lt;/code&gt;. In this case, we know that the output is also &lt;code&gt;[1]&lt;/code&gt;-- it's rather simple, because we just need to do a straight comparison of &lt;code&gt;1&lt;/code&gt; and &lt;code&gt;1&lt;/code&gt;. We go through the first &lt;code&gt;[1]&lt;/code&gt;, see the &lt;code&gt;1&lt;/code&gt;, and locate it in the second array. Because they're the same, we just return a &lt;code&gt;result&lt;/code&gt; with that match.&lt;/p&gt;

&lt;p&gt;So we need to expand beyond this. Let's say the two inputs are modified to &lt;code&gt;[1]&lt;/code&gt; and &lt;code&gt;[2]&lt;/code&gt;. Well, when we compare the two single elements, we know that they're not the same. We thus don't need to do anything with &lt;code&gt;result&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;As this continues beyond one array element, we can continue this process of checking if each element in the first array exists in the second.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fstorage.googleapis.com%2Falgodailyrandomassets%2Fcurriculum%2Farrays%2Farray-intersection-1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fstorage.googleapis.com%2Falgodailyrandomassets%2Fcurriculum%2Farrays%2Farray-intersection-1.png"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;intersection&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;firstArray&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;el&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;secondArray&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;includes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;el&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The concept of intersection is from set theory, so this problem is really simple if we just use &lt;code&gt;Set&lt;/code&gt;s! In mathematics, the intersection of two sets A and B is the set that contains all elements of A that also belong to B.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Set&lt;/code&gt;s are an object type in most languages that allow you to store unique values of most primitives.&lt;/p&gt;

&lt;p&gt;If we transform our input arrays into sets, we can make use of the &lt;code&gt;filter&lt;/code&gt; method, and apply it to one of the sets-- filtering out anything not in the other set.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;intersection&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;nums1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;nums2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="kd"&gt;set&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;nums1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;fileredSet&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;nums2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;n&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="kd"&gt;set&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;has&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;n&lt;/span&gt;&lt;span class="p"&gt;)));&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;fileredSet&lt;/span&gt; &lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This would have a time complexity of &lt;code&gt;O(n)&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The other way is to not use &lt;code&gt;Set&lt;/code&gt;s and keep arrays to model the inputs. With that approach, we'll also need a hash &lt;code&gt;Object&lt;/code&gt; to ensure uniqueness. This works because object keys must be unique.&lt;/p&gt;

&lt;p&gt;We can collect unique intersections by doing an &lt;code&gt;indexOf&lt;/code&gt; check and then returning it in array form:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;intersection&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;nums1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;nums2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;intersection&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{};&lt;/span&gt;

    &lt;span class="k"&gt;for &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;num&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;nums1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;nums2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;indexOf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;num&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nx"&gt;intersection&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;num&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nb"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;keys&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;intersection&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;val&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;parseInt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;val&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Despite there being two methods, it might be helpful to use the &lt;code&gt;Set&lt;/code&gt; if you encounter a similar problem during your interview. This is because it demonstrates knowledge of a commonly used &lt;code&gt;data structure&lt;/code&gt; and a background in mathematics.&lt;/p&gt;

&lt;p&gt;Check out more visual tutorials for &lt;a href="https://algodaily.com/curriculum" rel="noopener noreferrer"&gt;technical challenges at AlgoDaily.com&lt;/a&gt; and try out &lt;a href="https://algodaily.com/challenges/daily" rel="noopener noreferrer"&gt;our daily coding problem newsletter&lt;/a&gt;!&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>computerscience</category>
      <category>tutorial</category>
      <category>beginners</category>
    </item>
    <item>
      <title>How to Reverse a String</title>
      <dc:creator>Jake Z.</dc:creator>
      <pubDate>Wed, 19 Aug 2020 00:35:10 +0000</pubDate>
      <link>https://dev.to/jacobjzhang/how-to-reverse-a-string-k9c</link>
      <guid>https://dev.to/jacobjzhang/how-to-reverse-a-string-k9c</guid>
      <description>&lt;p&gt;The only way to get better at solving algorithms and data structures is to power through a few.&lt;/p&gt;

&lt;p&gt;We covered the best ways to prepare &lt;a href="https://algodaily.com/lessons/how-to-use-algodaily-and-get-the-most-out-of-it"&gt;in this lesson&lt;/a&gt;, in &lt;a href="https://algodaily.com/lessons/how-to-prepare-for-a-technical-interview"&gt;this one&lt;/a&gt;, and &lt;a href="https://algodaily.com/lessons/how-to-get-better-at-coding-interviews"&gt;here&lt;/a&gt;. Be sure to visit those if you need some more guidance. Otherwise, let's jump into it.&lt;/p&gt;

&lt;h3&gt;
  
  
  Reverse a String
&lt;/h3&gt;

&lt;p&gt;Let's &lt;strong&gt;reverse a string&lt;/strong&gt;!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--oXLuRGPr--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://storage.googleapis.com/algodailyrandomassets/curriculum/easy-strings/reverse-a-string.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--oXLuRGPr--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://storage.googleapis.com/algodailyrandomassets/curriculum/easy-strings/reverse-a-string.jpg" class="img-fluid"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Can you write a function that reverses an inputted string without using the built-in &lt;code&gt;Array#reverse&lt;/code&gt; method?&lt;/p&gt;

&lt;p&gt;Let's look at some examples. So, calling:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;reverseString("jake")&lt;/code&gt; should return &lt;code&gt;"ekaj"&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;reverseString("reverseastring")&lt;/code&gt; should return &lt;code&gt;"gnirtsaesrever"&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--uKawc8Bg--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://storage.googleapis.com/algodailyrandomassets/curriculum/easy-strings/reverse-a-string-1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--uKawc8Bg--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://storage.googleapis.com/algodailyrandomassets/curriculum/easy-strings/reverse-a-string-1.png" class="img-fluid"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;This lesson was originally published at &lt;a href="https://algodaily.com/challenges/reverse-a-string"&gt;https://algodaily.com&lt;/a&gt;, where I maintain a technical interview course and write think-pieces for ambitious developers.&lt;/em&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  True or False?
&lt;/h3&gt;

&lt;p&gt;In Java, C#, JavaScript, Python and Go, strings are &lt;code&gt;immutable&lt;/code&gt;. This means the string object's state can't be changed after creation.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Solution:&lt;/strong&gt; True&lt;/p&gt;




&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/L3nxzt4i4Vo"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;h3&gt;
  
  
  On Interviewer Mindset
&lt;/h3&gt;

&lt;p&gt;Reversing a string is one of the most common technical interview questions that candidates get. Interviewers love it because it's deceptively simple. After all, as a software engineer, you'd probably call the &lt;code&gt;#reverse&lt;/code&gt; method on your favorite &lt;code&gt;String&lt;/code&gt; class and call it a day!&lt;/p&gt;

&lt;p&gt;So don't overlook this one-- it appears a surprising amount as a warm-up or build-up question. Many interviewers will take the approach of using an easy question like this one, and actually judge much more harshly. You'll want to make you sure really nail this.&lt;/p&gt;

&lt;h3&gt;
  
  
  How We'll Begin Solving
&lt;/h3&gt;

&lt;p&gt;We want the &lt;strong&gt;string reversed&lt;/strong&gt;, which means that we end up with all our letters positioned backwards. &lt;em&gt;If you need a quick review of &lt;code&gt;string&lt;/code&gt;s, check out &lt;a href="https://algodaily.com/lessons/a-gentle-refresher-into-arrays-and-strings"&gt;our lesson on arrays and strings&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;We know that &lt;code&gt;string&lt;/code&gt;s can be thought of as character arrays-- that is, each element in the array is a single character. And if we can assume that, then we know the location (array position) of each character, as well as the index when the &lt;code&gt;array&lt;/code&gt; ends.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;There's a caveat to thinking of strings as character arrays-- it's not always true. As readers and viewers have pointed out, a string represents text formed from graphemes (the smallest functional unit of a writing system)-- formed by combining character sequences in unicode.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Though strings and arrays contain similar methods like &lt;code&gt;length&lt;/code&gt;, &lt;code&gt;concat&lt;/code&gt;, and character position access-- &lt;em&gt;they are not identical&lt;/em&gt;. As an example, arrays are mutable and strings usually are not. Before we can operate on the string as an array, we'll need to separate the units (in JS by calling the &lt;code&gt;.split()&lt;/code&gt; method, or bypass this property by generating a brand new string instead of trying to operate on the original.&lt;/p&gt;

&lt;p&gt;However, after the &lt;code&gt;split&lt;/code&gt; operation, we can apply that paradigm to operating on this string. Thus we can step through each of its indices. Stepping through the beginning of the string, we'll make these observations at each point:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--2p2OSZfM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://storage.googleapis.com/algodailyrandomassets/curriculum/easy-strings/reverse-a-string-2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--2p2OSZfM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://storage.googleapis.com/algodailyrandomassets/curriculum/easy-strings/reverse-a-string-2.png" class="img-fluid"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;str&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;JAKE&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="c1"&gt;// position 0 - "J"&lt;/span&gt;
&lt;span class="c1"&gt;// position 1 - "A"&lt;/span&gt;
&lt;span class="c1"&gt;// ...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Since a reversed string is just itself backwards, &lt;strong&gt;a brute force solution&lt;/strong&gt; could be to use the indices, and iterate from &lt;em&gt;the back to the front&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;See the code attached and try to run it using &lt;code&gt;Run Sample Code&lt;/code&gt;. You'll see that we log out each character from the back of the string!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;reverseString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;newString&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="c1"&gt;// start from end&lt;/span&gt;
  &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;str&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Processing &lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;newString&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;str&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
        &lt;span class="c1"&gt;// append it to the string builder&lt;/span&gt;
    &lt;span class="nx"&gt;newString&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;newString&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;str&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c1"&gt;// return the string&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;newString&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;reverseString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;test&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h3&gt;
  
  
  Fill In
&lt;/h3&gt;

&lt;p&gt;We want to &lt;code&gt;console.log&lt;/code&gt; out:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="mi"&gt;5&lt;/span&gt;
&lt;span class="mi"&gt;4&lt;/span&gt;
&lt;span class="mi"&gt;3&lt;/span&gt;
&lt;span class="mi"&gt;2&lt;/span&gt;
&lt;span class="mi"&gt;1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;What's the missing line here?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;arr&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;  &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;

&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;___________&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Solution:&lt;/strong&gt; arr.length - 1&lt;/p&gt;




&lt;h3&gt;
  
  
  Can We Do Better Than Brute Force?
&lt;/h3&gt;

&lt;p&gt;However, it wouldn't really be an interesting algorithms question if there wasn't a better way. Let's see how we can optimize this, or make it run faster. When trying to make something more efficient, it helps to think of things to &lt;em&gt;cut or reduce&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;One thing to note is that we're going through the &lt;em&gt;entire&lt;/em&gt; string-- do we truly need to iterate through every single letter?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Let's examine a worst case scenario.&lt;/strong&gt; What if the string is a million characters long? That would be a million operations to work through! Can we improve it?&lt;/p&gt;

&lt;h3&gt;
  
  
  Yes, With More Pointers!
&lt;/h3&gt;

&lt;p&gt;Well, we're only working with a single pointer right now. The iterator from our loop starts from the back, and appends each character to a new string, one by one. Having gone through &lt;a href="https://algodaily.com/lessons/using-the-two-pointer-technique"&gt;The Two Pointer Technique&lt;/a&gt;, we may recognize that some dramatic improvements can be had by increasing the number of pointers we use.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--2yOV37ry--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://storage.googleapis.com/algodailyrandomassets/curriculum/arrays/two-pointer-1.svg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--2yOV37ry--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://storage.googleapis.com/algodailyrandomassets/curriculum/arrays/two-pointer-1.svg" class="img-fluid"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;By this I mean, we can &lt;strong&gt;cut the number of operations in half&lt;/strong&gt;. How? What if we did some &lt;strong&gt;swapping&lt;/strong&gt; instead? By using a &lt;code&gt;while&lt;/code&gt; loop and two pointers-- one on the left and one on the right.&lt;/p&gt;

&lt;p&gt;With this in mind-- the big reveal is that, at each iteration, we can swap the letters at the pointer indices. After swapping, we would increment the &lt;code&gt;left&lt;/code&gt; pointer while decrementing the &lt;code&gt;right&lt;/code&gt; one. That could be hard to visualize, so let's see a basic example listed out.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;jake    // starting string

eakj    // first pass
^  ^

ekaj    // second pass
 ^^
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h3&gt;
  
  
  Multiple Choice
&lt;/h3&gt;

&lt;p&gt;What's a good use case for the two pointers technique?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Shifting indices to be greater at each iteration&lt;/li&gt;
&lt;li&gt;Reducing a solution with a nested for-loop and O(n^2) complexity to O(n)&lt;/li&gt;
&lt;li&gt;Finding pairs and duplicates in a for-loop&lt;/li&gt;
&lt;li&gt;None of these&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Solution:&lt;/strong&gt; Reducing a solution with a nested for-loop and O(n^2) complexity to O(n)&lt;/p&gt;




&lt;p&gt;With two pointers, we've cut the number of operations in half. It's much faster now! However, similar to the brute force, the time complexity is still &lt;code&gt;O(n)&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--moIAJsJl--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://storage.googleapis.com/algodailyrandomassets/curriculum/easy-strings/reverse-a-string-3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--moIAJsJl--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://storage.googleapis.com/algodailyrandomassets/curriculum/easy-strings/reverse-a-string-3.png" class="img-fluid"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Why Is This?
&lt;/h3&gt;

&lt;p&gt;Well, if &lt;code&gt;n&lt;/code&gt; is the length of the string, we'll end up making &lt;code&gt;n/2&lt;/code&gt; swaps. But remember, &lt;a href="https://algodaily.com/lessons/understanding-big-o-and-algorithmic-complexity"&gt;Big O Notation&lt;/a&gt; isn't about the raw number of operations required for an algorithm-- it's about &lt;em&gt;how the number scales with the input&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;So despite requiring half the number operations-- a &lt;code&gt;4&lt;/code&gt;-character string would require &lt;code&gt;2&lt;/code&gt; swaps with the two-pointer method. But an &lt;code&gt;8&lt;/code&gt;-character string would require &lt;code&gt;4&lt;/code&gt; swaps. The input doubled, and so did the number of operations.&lt;/p&gt;

&lt;h3&gt;
  
  
  Final Solution
&lt;/h3&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;reverseString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;strArr&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;str&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;""&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;start&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;end&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;str&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;start&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="nx"&gt;end&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;temp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;strArr&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;start&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
    &lt;span class="nx"&gt;strArr&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;start&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;strArr&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;end&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
    &lt;span class="nx"&gt;strArr&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;end&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;temp&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nx"&gt;start&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nx"&gt;end&lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;strArr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;""&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



</description>
      <category>javascript</category>
      <category>computerscience</category>
      <category>tutorial</category>
      <category>beginners</category>
    </item>
    <item>
      <title>A Visual Guide to How to Actually Invert a Binary Tree</title>
      <dc:creator>Jake Z.</dc:creator>
      <pubDate>Sun, 16 Aug 2020 11:38:36 +0000</pubDate>
      <link>https://dev.to/jacobjzhang/a-visual-guide-to-how-to-actually-invert-a-binary-tree-1lkc</link>
      <guid>https://dev.to/jacobjzhang/a-visual-guide-to-how-to-actually-invert-a-binary-tree-1lkc</guid>
      <description>&lt;p&gt;Can you invert a &lt;code&gt;binary tree&lt;/code&gt; over its vertical axis? This is a famous problem made popular by this tweet:&lt;/p&gt;


&lt;blockquote&gt;
&lt;p&gt;Google: 90% of our engineers use the software you wrote (Homebrew), but you can’t invert a binary tree on a whiteboard so fuck off.&lt;/p&gt;— Max Howell (@mxcl) &lt;a href="https://twitter.com/mxcl/status/608682016205344768?ref_src=twsrc%5Etfw"&gt;June 10, 2015&lt;/a&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--vL1AblPn--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://storage.googleapis.com/algodailyrandomassets/curriculum/trees/invert-a-binary-tree-cover-image.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--vL1AblPn--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://storage.googleapis.com/algodailyrandomassets/curriculum/trees/invert-a-binary-tree-cover-image.png" class="img-fluid"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Given a &lt;code&gt;binary tree&lt;/code&gt; like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;     4
   /   \
  2     7
 / \   / \
1   3 6   9
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Performing an inversion would result in:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Output:

     4
   /   \
  7     2
 / \   / \
9   6 3   1
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;The definition of a tree node is as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;Node&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;val&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;val&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;val&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;left&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;right&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;&lt;em&gt;This lesson was originally published at &lt;a href="https://algodaily.com/challenges/invert-a-binary-tree"&gt;https://algodaily.com&lt;/a&gt;, where I maintain a technical interview course and write think-pieces for ambitious developers.&lt;/em&gt;&lt;/p&gt;




&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/aFws303_XOc"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;This is the famous question that &lt;code&gt;Homebrew&lt;/code&gt; author &lt;code&gt;Max Howell&lt;/code&gt; &lt;a href="https://twitter.com/mxcl/status/608682016205344768?lang=en"&gt;famously got wrong in a Google Interview&lt;/a&gt;. Hopefully this prevents you from having the same misfortune!&lt;/p&gt;

&lt;p&gt;Let's think about brute force-- how would we do it without any clever algorithms? We can start with a very basic input as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  1
 / \
2   3
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;So to invert it vertically, we'd start at &lt;code&gt;1&lt;/code&gt;, where there's nothing to flip or swap, and it would stay put. We've now processed the first row. &lt;/p&gt;

&lt;p&gt;Moving on to the second, we encounter &lt;code&gt;2&lt;/code&gt; and &lt;code&gt;3&lt;/code&gt;, so we'd swap them and get:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--wfPDR4Tp--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://storage.googleapis.com/algodailyrandomassets/curriculum/trees/invert-a-binary-tree-image1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--wfPDR4Tp--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://storage.googleapis.com/algodailyrandomassets/curriculum/trees/invert-a-binary-tree-image1.png" class="img-fluid"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  1
 / \
3   2
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Interesting, this seems to have inverted it! Is it as simple as swapping when there's more than one node?&lt;/p&gt;

&lt;p&gt;What if we had more than two nodes to swap per level though? If there was an additional level, it might look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;      1
     / \
    3   2
   / \   \
  4   5   3
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;That final row is currently directionally &lt;code&gt;4 -&amp;gt; 5 -&amp;gt; 3&lt;/code&gt;, but we'd want the outcome to be &lt;code&gt;3 -&amp;gt; 5 -&amp;gt; 4&lt;/code&gt; to be properly inverted.&lt;/p&gt;

&lt;p&gt;However, we can achieve this by doing two separate swaps. Notice that the below is what we'd get if we swapped &lt;code&gt;4&lt;/code&gt; and &lt;code&gt;5&lt;/code&gt; to obtain &lt;code&gt;5 -&amp;gt; 4&lt;/code&gt;, and then swapping &lt;code&gt;5 -&amp;gt; 4&lt;/code&gt; with &lt;code&gt;3&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--lB7B4nIm--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://storage.googleapis.com/algodailyrandomassets/curriculum/trees/invert-a-binary-tree-image2.png%3Fbust%3D1" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--lB7B4nIm--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://storage.googleapis.com/algodailyrandomassets/curriculum/trees/invert-a-binary-tree-image2.png%3Fbust%3D1" class="img-fluid"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;      1
     / \
    2   3
   /   / \
  3   5   4
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;So, to put it all together: we can perform an in-order traversal and do a swap at each iteration.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--L48LPzPM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://storage.googleapis.com/algodailyrandomassets/curriculum/trees/invert-a-binary-tree-image3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--L48LPzPM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://storage.googleapis.com/algodailyrandomassets/curriculum/trees/invert-a-binary-tree-image3.png" class="img-fluid"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A caveat that was pointed out by readers-- if we're dealing with a substantially large binary tree, then a recursive solution might cause problems due to call stack size. There are two ways to get around this:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Using a stack to mimic the recursion&lt;/li&gt;
&lt;li&gt;Using a queue, visiting the levels one by one in a BFS fashion and swapping the left and right nodes to invert the tree.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Here's what the final code looks like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;invertTree&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;head&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;head&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;temp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;head&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;left&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nx"&gt;head&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;left&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;head&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;right&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nx"&gt;head&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;right&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;temp&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="nx"&gt;invertTree&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;head&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;left&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;invertTree&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;head&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;right&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;head&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Check out more visual tutorials for &lt;a href="https://algodaily.com/curriculum"&gt;technical challenges at AlgoDaily.com&lt;/a&gt; and try out &lt;a href="https://algodaily.com/challenges/daily"&gt;our daily coding problem newsletter&lt;/a&gt;!&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Using the Two Pointer Technique</title>
      <dc:creator>Jake Z.</dc:creator>
      <pubDate>Sat, 15 Aug 2020 16:41:12 +0000</pubDate>
      <link>https://dev.to/jacobjzhang/using-the-two-pointer-technique-40g5</link>
      <guid>https://dev.to/jacobjzhang/using-the-two-pointer-technique-40g5</guid>
      <description>&lt;h2&gt;
  
  
  The Two Pointer Technique
&lt;/h2&gt;

&lt;p&gt;The &lt;strong&gt;two pointer technique&lt;/strong&gt; is a near necessity in any software developer's toolkit, especially when it comes to technical interviews. In this guide, we'll cover the basics so that you know when and how to use this technique.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--2yOV37ry--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://storage.googleapis.com/algodailyrandomassets/curriculum/arrays/two-pointer-1.svg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--2yOV37ry--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://storage.googleapis.com/algodailyrandomassets/curriculum/arrays/two-pointer-1.svg" class="img-fluid"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;This lesson was originally published at &lt;a href="https://algodaily.com/lessons/using-the-two-pointer-technique"&gt;https://algodaily.com&lt;/a&gt;, where I maintain a technical interview course and write think-pieces for ambitious developers.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What is the pattern?
&lt;/h2&gt;

&lt;p&gt;The name &lt;code&gt;two pointers&lt;/code&gt; does justice in this case, as it is exactly as it sounds. It's the use of two different pointers (usually to keep track of array or string indices) to solve a problem involving said indices with the benefit of saving time and space. See the below for the two pointers highlighted in yellow.&lt;/p&gt;

&lt;p&gt;But what are &lt;code&gt;pointers&lt;/code&gt;? In computer science, a &lt;code&gt;pointer&lt;/code&gt; is a reference to an object. In many programming languages, that object stores a memory address of another value located in computer memory, or in some cases, that of memory-mapped computer hardware.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--2yryr_QT--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://storage.googleapis.com/algodailyrandomassets/curriculum/arrays/two-pointer-2.svg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--2yryr_QT--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://storage.googleapis.com/algodailyrandomassets/curriculum/arrays/two-pointer-2.svg" class="img-fluid"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  When do we use it?
&lt;/h3&gt;

&lt;p&gt;In many problems involving collections such as arrays or lists, we have to analyze each element of the collection compared to its other elements.&lt;/p&gt;

&lt;p&gt;There are many approaches to solving problems like these. For example we usually start from the first index and iterate through the &lt;code&gt;data structure&lt;/code&gt; one or more times depending on how we implement our code.&lt;/p&gt;

&lt;p&gt;Sometimes we may even have to create an additional &lt;code&gt;data structure&lt;/code&gt; depending on the problem's requirements. This approach might give us the correct result, but it likely won't give us the most space and time efficient result.&lt;/p&gt;

&lt;p&gt;This is why the &lt;code&gt;two-pointer technique&lt;/code&gt; is efficient. We are able to process two elements per loop instead of just one. Common patterns in the two-pointer approach entail:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Two pointers, each starting from the beginning and the end until they both meet.&lt;/li&gt;
&lt;li&gt;One pointer moving at a slow pace, while the other pointer moves at twice the speed.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;These patterns can be used for string or array questions. They can also be streamlined and made more efficient by iterating through two parts of an object simultaneously. You can see this in the &lt;a href="https://algodaily.com/challenges/two-sum"&gt;Two Sum problem&lt;/a&gt; or &lt;a href="https://algodaily.com/challenges/reverse-a-string"&gt;Reverse a String&lt;/a&gt; problems.&lt;/p&gt;

&lt;h2&gt;
  
  
  Running through an example
&lt;/h2&gt;

&lt;p&gt;One usage is while searching for pairs in an array. Let us consider &lt;a href="https://algodaily.com/challenges/two-sum"&gt;a practical example&lt;/a&gt;: assume that you have a sorted array &lt;code&gt;arr&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;You're tasked with figuring out the pair of elements where &lt;code&gt;arr[p]&lt;/code&gt; + &lt;code&gt;arr[q]&lt;/code&gt; add up to a certain number. (To try this problem out, check the &lt;a href="https://algodaily.com/challenges/two-sum"&gt;Two Sum&lt;/a&gt; and &lt;a href="https://algodaily.com/challenges/sorted-two-sum"&gt;Sorted Two Sum&lt;/a&gt; problems here.)&lt;/p&gt;

&lt;p&gt;The brute force solution is to compare each element with every other number, but that's a time complexity of &lt;code&gt;O(n^2)&lt;/code&gt;. We can do better!&lt;/p&gt;

&lt;p&gt;So let's optimize. You need to identify the indices &lt;code&gt;pointer_one&lt;/code&gt; and &lt;code&gt;pointer_two&lt;/code&gt; whose values sum to the integer &lt;code&gt;target&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Let's initialize two variables, &lt;code&gt;pointer_one&lt;/code&gt; and &lt;code&gt;pointer_two&lt;/code&gt;, and consider them as our two pointers.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;pointer_one&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
&lt;span class="n"&gt;pointer_two&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Note that &lt;code&gt;len(arr)-1&lt;/code&gt; helps to get the last index possible in an array.&lt;/p&gt;

&lt;p&gt;Also observe that when we start, &lt;code&gt;pointer_one&lt;/code&gt; points to the first element of the array, and &lt;code&gt;pointer_two&lt;/code&gt; points to the last element.&lt;/p&gt;

&lt;p&gt;This won't always be the case with this technique (we'll explore the &lt;a href="https://algodaily.com/lessons/a-birds-eye-view-into-sliding-windows"&gt;sliding window concept&lt;/a&gt; later, which uses two pointers but have them move in a different direction). For our current purposes, it is more efficient to start wide, and iteratively narrow in (particularly if the array is sorted).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;two_sum&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;target&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;pointer_one&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
    &lt;span class="n"&gt;pointer_two&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;input&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;length&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;

    &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="n"&gt;pointer_one&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;pointer_two&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Since the array is already sorted, and we're looking to process an index at each iteration, we can use two pointers to process them faster. One pointer &lt;em&gt;starts from the beginning of the array&lt;/em&gt;, and the other pointer &lt;em&gt;begins from the end of the array&lt;/em&gt;, and then we add the values at these pointers.&lt;/p&gt;

&lt;p&gt;Once we're set up, what we want to do is check if the current pointers already sum up to our target. This might happen if the correct ones are on the exact opposite ends of the array.&lt;/p&gt;

&lt;p&gt;Here's what the check might look like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nb"&gt;sum&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;targetValue&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;However, it likely will not be the target immediately. Thus, we apply this logic: if the sum of the values is less than the target value, we increment the left pointer (move your left pointer &lt;code&gt;pointer_one&lt;/code&gt; one index rightwards).&lt;/p&gt;

&lt;p&gt;And if the sum is higher than the target value, we decrement the right pointer (correct the position of your pointer &lt;code&gt;pointer_two&lt;/code&gt; if necessary).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;elif&lt;/span&gt; &lt;span class="nb"&gt;sum&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;targetValue&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
  &lt;span class="n"&gt;pointer_one&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
  &lt;span class="n"&gt;pointer_two&lt;/span&gt; &lt;span class="o"&gt;-=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;In other words, understand that if &lt;code&gt;arr[pointer_one]&lt;/code&gt; &amp;lt; &lt;code&gt;target-arr[pointer_two]&lt;/code&gt;, it means we should move forward on &lt;code&gt;pointer_one&lt;/code&gt; to get closer to where we want to be in magnitude.&lt;/p&gt;

&lt;p&gt;This is what it looks like all put together:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;two_sum&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;target&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;pointer_one&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
    &lt;span class="n"&gt;pointer_two&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;input&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;length&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;

    &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="n"&gt;pointer_one&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;pointer_two&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="nb"&gt;sum&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;input&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;pointer_one&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nb"&gt;input&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;pointer_two&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nb"&gt;sum&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;targetValue&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;true&lt;/span&gt;
        &lt;span class="k"&gt;elif&lt;/span&gt; &lt;span class="nb"&gt;sum&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;targetValue&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;pointer_one&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
        &lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;pointer_two&lt;/span&gt; &lt;span class="o"&gt;-=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;false&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;It's crucial to see that how both indices were moving in conjunction, and how they depend on each other.&lt;/p&gt;

&lt;p&gt;We kept moving the pointers until we got the sum that matches the target value-- or until we reached the middle of the array, and no combinations were found.&lt;/p&gt;

&lt;p&gt;The time complexity of this solution is &lt;code&gt;O(n)&lt;/code&gt; and space complexity is &lt;code&gt;O(1)&lt;/code&gt;, a significant improvement over our first implementation!&lt;/p&gt;

&lt;h3&gt;
  
  
  Another Example
&lt;/h3&gt;

&lt;p&gt;In addition, to the previous example, the two pointer technique can also involve the pattern of using a fast pointer and a slow pointer.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;Node&lt;/span&gt; &lt;span class="n"&gt;fast&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;head&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;slow&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;head&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;One usage is through detecting cycles in a &lt;code&gt;linked list&lt;/code&gt; data structure. For example, a cycle (when a node points back to a previous node) begins at the last node of the &lt;code&gt;linked list&lt;/code&gt; in the example below.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--mgyIWmZK--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://storage.googleapis.com/algodailyrandomassets/curriculum/linked-lists/slow-and-fast-pointers-step-1.svg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--mgyIWmZK--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://storage.googleapis.com/algodailyrandomassets/curriculum/linked-lists/slow-and-fast-pointers-step-1.svg" class="img-fluid"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;1 -- &amp;gt; 2 --&amp;gt; 3 --&amp;gt; 4
             ^     |
             |     |
             &amp;lt;- - -

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;The idea is to move the fast pointer twice as quickly as the slow pointer so the distance between them increases by &lt;code&gt;1&lt;/code&gt; at each step.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--j5ObSPeH--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://storage.googleapis.com/algodailyrandomassets/curriculum/linked-lists/slow-and-fast-pointers-step-2.svg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--j5ObSPeH--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://storage.googleapis.com/algodailyrandomassets/curriculum/linked-lists/slow-and-fast-pointers-step-2.svg" class="img-fluid"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="k"&gt;while&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fast&lt;/span&gt;&lt;span class="o"&gt;!=&lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;fast&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;next&lt;/span&gt;&lt;span class="o"&gt;!=&lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="o"&gt;){&lt;/span&gt;
  &lt;span class="n"&gt;slow&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;slow&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;next&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

  &lt;span class="n"&gt;fast&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;fast&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;next&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;next&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;However, if at some point both pointers meet, then we have found a cycle in the linked list. Otherwise we'll have have reached the end of the list and no cycle is present.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--0B5Nj-yc--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://storage.googleapis.com/algodailyrandomassets/curriculum/linked-lists/slow-and-fast-pointers-step-3.svg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--0B5Nj-yc--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://storage.googleapis.com/algodailyrandomassets/curriculum/linked-lists/slow-and-fast-pointers-step-3.svg" class="img-fluid"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;slow&lt;/span&gt;&lt;span class="o"&gt;==&lt;/span&gt;&lt;span class="n"&gt;fast&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;The attached code is what the entire method would look like all together.&lt;/p&gt;

&lt;p&gt;The time complexity would be &lt;code&gt;O(N)&lt;/code&gt; or linear time.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;boolean&lt;/span&gt; &lt;span class="nf"&gt;detectCycle&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Node&lt;/span&gt; &lt;span class="n"&gt;head&lt;/span&gt;&lt;span class="o"&gt;){&lt;/span&gt;
    &lt;span class="nc"&gt;Node&lt;/span&gt; &lt;span class="n"&gt;fast&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;head&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;slow&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;head&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;while&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fast&lt;/span&gt;&lt;span class="o"&gt;!=&lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;fast&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;next&lt;/span&gt;&lt;span class="o"&gt;!=&lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="o"&gt;){&lt;/span&gt;
        &lt;span class="n"&gt;slow&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;slow&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;next&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

        &lt;span class="n"&gt;fast&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;fast&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;next&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;next&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

        &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;slow&lt;/span&gt;&lt;span class="o"&gt;==&lt;/span&gt;&lt;span class="n"&gt;fast&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



</description>
      <category>beginners</category>
      <category>tutorial</category>
      <category>codenewbie</category>
      <category>computerscience</category>
    </item>
    <item>
      <title>A Beginner's Reference to SQL vs. NoSQL</title>
      <dc:creator>Jake Z.</dc:creator>
      <pubDate>Fri, 14 Aug 2020 11:53:02 +0000</pubDate>
      <link>https://dev.to/jacobjzhang/a-beginner-s-reference-to-sql-vs-nosql-egk</link>
      <guid>https://dev.to/jacobjzhang/a-beginner-s-reference-to-sql-vs-nosql-egk</guid>
      <description>&lt;p&gt;Many new developers wonder what the difference is between &lt;code&gt;SQL&lt;/code&gt; and &lt;code&gt;NoSQL&lt;/code&gt;. The subjects come up often in theoretical discussions and systems design interview preparation.&lt;/p&gt;

&lt;p&gt;In this tutorial, we will be looking at the difference between SQL and NoSQL based on certain parameters. Before we begin, let’s analyze each individually to develop our understanding of these contrasting concepts.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;This lesson was originally published at &lt;a href="https://algodaily.com/lessons/a-beginners-reference-to-sql-vs-nosql"&gt;https://algodaily.com&lt;/a&gt;, where I maintain a technical interview course and write think-pieces for ambitious developers.&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  What is SQL?
&lt;/h3&gt;

&lt;p&gt;Some definitions to start:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;SQL&lt;/code&gt; stands for &lt;strong&gt;Structured Query Language&lt;/strong&gt;. As evident from the name, it is a querying language that is used to perform various data operations. It is supported on almost all &lt;strong&gt;Relational Databases.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;And what is a Relational Database?&lt;/em&gt; A relational database, often synonymous as a &lt;code&gt;SQL&lt;/code&gt; Database, is a collection of data records that may have predefined associations or relationships with each other.&lt;/p&gt;

&lt;p&gt;By extension, a &lt;strong&gt;Relational Database Management System (RDMS)&lt;/strong&gt; is an interface (application or UI) to manage the records, usually by way of &lt;code&gt;SQL&lt;/code&gt;. It's used to store, edit, read, and write such data in the form of tables. It's also often visually shown as a spreadsheet-like shape.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--NejVQTPI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://storage.googleapis.com/algodailyrandomassets/curriculum/systems-design/sql-vs-no-sql/2-representation%2520of%2520rdmbs_png.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--NejVQTPI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://storage.googleapis.com/algodailyrandomassets/curriculum/systems-design/sql-vs-no-sql/2-representation%2520of%2520rdmbs_png.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  SQL Databases
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--SoLPCj71--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://storage.googleapis.com/algodailyrandomassets/curriculum/systems-design/sql-vs-no-sql/1-rdmbs%2520data%2520storage_png.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--SoLPCj71--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://storage.googleapis.com/algodailyrandomassets/curriculum/systems-design/sql-vs-no-sql/1-rdmbs%2520data%2520storage_png.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;SQL&lt;/code&gt; databases, or &lt;code&gt;Relational Database&lt;/code&gt;s, employ the traditional way of storing data (where each database may contain several tables). However, it is worth mentioning that in &lt;code&gt;RDB&lt;/code&gt;s, each table contains rows that have the same attributes or "shape". As an example, in a "restaurant" database, you may have one table for &lt;code&gt;customers&lt;/code&gt;, another for &lt;code&gt;orders&lt;/code&gt;, and yet another for restaurant &lt;code&gt;locations&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Now here comes the &lt;strong&gt;importance of columns&lt;/strong&gt;. Each column describes one specific piece of information about the record. The type of data that each column will contain is also predefined. For example, in a &lt;code&gt;customer&lt;/code&gt; table, one column may contain the customer &lt;code&gt;id&lt;/code&gt; (an &lt;code&gt;integer&lt;/code&gt; type column). Another may show the customer order &lt;code&gt;id&lt;/code&gt; (another &lt;code&gt;integer&lt;/code&gt;), and a third may contain information about customer address (&lt;code&gt;varchar&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;Properly defining tables and columns is upfront work to be done to gainfully use a database. Then, the day to day task becomes adding new rows. This is where the &lt;code&gt;SQL&lt;/code&gt; language comes in handy. It offers a convenient way to create tables, define columns, add records, delete them, etc. It also allows us to "connect" or &lt;code&gt;associate&lt;/code&gt; (create relationships for) multiple tables by using the concept of &lt;code&gt;primary&lt;/code&gt; and &lt;code&gt;foreign&lt;/code&gt; keys.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--baBz0O6S--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://storage.googleapis.com/algodailyrandomassets/curriculum/systems-design/sql-vs-no-sql/3-rdbms%2520data%2520storage%2520table%2520example_png.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--baBz0O6S--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://storage.googleapis.com/algodailyrandomassets/curriculum/systems-design/sql-vs-no-sql/3-rdbms%2520data%2520storage%2520table%2520example_png.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Types of SQL DBs
&lt;/h3&gt;

&lt;p&gt;Here's a selection of the various SQL Databases.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Acdb5Lgl--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://storage.googleapis.com/algodailyrandomassets/curriculum/systems-design/sql-vs-no-sql/4-types%2520of%2520SQ%2520RDB_png.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Acdb5Lgl--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://storage.googleapis.com/algodailyrandomassets/curriculum/systems-design/sql-vs-no-sql/4-types%2520of%2520SQ%2520RDB_png.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What is NoSQL?
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--JuU_bd1i--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://storage.googleapis.com/algodailyrandomassets/curriculum/systems-design/sql-vs-no-sql/5-nosql%2520definition_png.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--JuU_bd1i--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://storage.googleapis.com/algodailyrandomassets/curriculum/systems-design/sql-vs-no-sql/5-nosql%2520definition_png.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let's move on to the definition of &lt;code&gt;NoSQL&lt;/code&gt;. Several &lt;code&gt;NoSQL&lt;/code&gt; database systems have grown rapidly in popularity over the last few years. They are non-relational &lt;code&gt;DMS&lt;/code&gt;s that support structured data, unstructured, semi-structured, &lt;em&gt;and&lt;/em&gt; polymorphic data.&lt;/p&gt;

&lt;p&gt;At a high level, NoSQL just means &lt;strong&gt;not only SQL&lt;/strong&gt;. Thus, it doesn't speak to a single database offering-- rather, it's a collection of diverse technologies. Don't assume that the databases are similar in nature either.&lt;/p&gt;

&lt;p&gt;As stated, there are no official rules as to what makes a database &lt;code&gt;NoSQL&lt;/code&gt;. The term describes more &lt;strong&gt;about what they aren’t&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;NoSQL Databases:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;typically don't use SQL&lt;/li&gt;
&lt;li&gt;usually don't store data in tables&lt;/li&gt;
&lt;li&gt;usually don't care about relationships&lt;/li&gt;
&lt;li&gt;usually don't provide ACID transaction&lt;/li&gt;
&lt;li&gt;usually don't require formal data schemas (making them more flexible)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Types of NoSQL Technologies
&lt;/h3&gt;

&lt;p&gt;Let's run through a list of data store offerings within the &lt;code&gt;NoSQL&lt;/code&gt; flavor.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Document DB/Document Stores:&lt;/strong&gt;&lt;br&gt;
These are organized around the idea that the fundamental thing to store is a self-contained piece of data (called a &lt;code&gt;document&lt;/code&gt;). Such a document describes its own schema-- this is in opposition to individual rows of data constrained in well-defined columns. With &lt;code&gt;document&lt;/code&gt;s, there generally are no restrictions in shape or structure. It may be in &lt;code&gt;XML&lt;/code&gt; format, but often it's &lt;code&gt;JSON&lt;/code&gt;-- a loose structure based on plain old Javascript objects.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example:&lt;/strong&gt; store a simple piece of data consisting of two pieces of information: &lt;code&gt;title&lt;/code&gt; and &lt;code&gt;rating&lt;/code&gt;. The &lt;code&gt;title&lt;/code&gt; is a string and &lt;code&gt;rating&lt;/code&gt; is an integer.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--yVsipwWJ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://storage.googleapis.com/algodailyrandomassets/curriculum/systems-design/sql-vs-no-sql/6-nosql-documentstore-ex1_png.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--yVsipwWJ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://storage.googleapis.com/algodailyrandomassets/curriculum/systems-design/sql-vs-no-sql/6-nosql-documentstore-ex1_png.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the next piece of data, we have different descriptions and utilize &lt;code&gt;nesting&lt;/code&gt; of information.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--UGHCPMPQ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://storage.googleapis.com/algodailyrandomassets/curriculum/systems-design/sql-vs-no-sql/7-nosql-documentstore-ex2_png.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--UGHCPMPQ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://storage.googleapis.com/algodailyrandomassets/curriculum/systems-design/sql-vs-no-sql/7-nosql-documentstore-ex2_png.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When we are schema-less, we can simply add new documents in this data store freely. The only constraint is that each &lt;code&gt;document&lt;/code&gt; will be given a unique &lt;code&gt;id&lt;/code&gt;. But beyond that, you often have total flexibility. There's no need to provide a formal schema and no need to define relationships. One downfall of this is that the database needs to provide a more flexible way of querying the data-- thus arrived solutions like &lt;code&gt;CouchDB&lt;/code&gt; and &lt;code&gt;MongoDB&lt;/code&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Key-value databases&lt;/strong&gt; are another category. Its main emphasis is on having &lt;strong&gt;no predefined schema&lt;/strong&gt; for your data. All it does is store and retrieve everything based on key-value pairs. In some ways, it's like a two-column table (if you had a &lt;code&gt;key&lt;/code&gt; column and &lt;code&gt;value&lt;/code&gt; column), and nothing more is enforced. It could be any data type. You could fit in bits of &lt;code&gt;XML&lt;/code&gt; or &lt;code&gt;JSON&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Furthermore, It is worth mentioning that many products in this category are specifically designed with fault-tolerant distributed architecture. Simplified, this means you can easily install them across multiple machines. As such, no one machine is a point of failure-- the database can survive machine failures and continue functioning.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--B9EnhYQz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://storage.googleapis.com/algodailyrandomassets/curriculum/systems-design/sql-vs-no-sql/8-no%2520sql%2520key%2520value%2520storage_png.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--B9EnhYQz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://storage.googleapis.com/algodailyrandomassets/curriculum/systems-design/sql-vs-no-sql/8-no%2520sql%2520key%2520value%2520storage_png.png"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Graph:&lt;/strong&gt; Yet another category of &lt;code&gt;NoSQL&lt;/code&gt; tech. It is a data store in which everything is kept in the form of connecting nodes, in a &lt;code&gt;graph&lt;/code&gt; structure. There is no one "master" point. Although many other NoSQL DBMS tend to de-emphasize relationships, &lt;code&gt;graph database&lt;/code&gt;s are all about having nodes of data connected to each other, describing relationships among them.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--M_F8TBtZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://storage.googleapis.com/algodailyrandomassets/curriculum/systems-design/sql-vs-no-sql/9-nosql-graph_databsee-ex_png.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--M_F8TBtZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://storage.googleapis.com/algodailyrandomassets/curriculum/systems-design/sql-vs-no-sql/9-nosql-graph_databsee-ex_png.png"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Column-oriented database:&lt;/strong&gt; In a traditional row-oriented database, when we try to retrieve a specific record, every single row is scanned. Indexing certain columns may improve the lookup speed-- however, indexing every column slows down the updating (write) speed. Sometimes it may require you to lock the tables-- if not completely, then partially-- by locking certain parts of your table.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This is where column-oriented databases come in handy. They store individual columns separately, allowing an efficient scan when we have a limited number of columns (because there is only one data type in each table). Therefore, it is very efficient to add new columns. However, adding an entire record becomes more difficult. Although they may look similar to traditional databases, the method of storing and retrieving data is where the actual difference lies. They are best for analytics. Examples of the column-oriented database include but not limited to Cassandra (released by Facebook as an open-source project), Hypertable, Google BigTable, and Apache HBase.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--p_qN4Vwp--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://storage.googleapis.com/algodailyrandomassets/curriculum/systems-design/sql-vs-no-sql/10-nosql-column_oriented_databsee-ex_png.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--p_qN4Vwp--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://storage.googleapis.com/algodailyrandomassets/curriculum/systems-design/sql-vs-no-sql/10-nosql-column_oriented_databsee-ex_png.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Comparison of the Two
&lt;/h2&gt;

&lt;p&gt;Now that we know the fundamentals of both &lt;code&gt;SQL&lt;/code&gt; and &lt;code&gt;NoSQL&lt;/code&gt;, we can dive into the technical details and compare them across certain factors. Analyzing across these parameters will help us understand their differences.&lt;/p&gt;

&lt;h3&gt;
  
  
  Theoretical difference
&lt;/h3&gt;

&lt;p&gt;In short, &lt;code&gt;SQL&lt;/code&gt; databases are primarily &lt;code&gt;Relational Database Management System&lt;/code&gt;s, while &lt;code&gt;NoSQL&lt;/code&gt; databases are non-relational distributed databases and datastores.&lt;/p&gt;

&lt;h3&gt;
  
  
  Schema:
&lt;/h3&gt;

&lt;p&gt;A &lt;code&gt;schema&lt;/code&gt; refers to the &lt;em&gt;organization and shape of records&lt;/em&gt; within a database. Both of these database types have a very contrasting data storage models. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;SQL databases&lt;/strong&gt; usually deal with &lt;em&gt;structured data&lt;/em&gt; that is organized in &lt;strong&gt;the form of tables&lt;/strong&gt;. On the other hand, &lt;strong&gt;NoSQL databases&lt;/strong&gt;, along with support for structured data, offer the convenience of storing unstructured, semi-structured, and polymorphic data as well.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--baBz0O6S--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://storage.googleapis.com/algodailyrandomassets/curriculum/systems-design/sql-vs-no-sql/3-rdbms%2520data%2520storage%2520table%2520example_png.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--baBz0O6S--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://storage.googleapis.com/algodailyrandomassets/curriculum/systems-design/sql-vs-no-sql/3-rdbms%2520data%2520storage%2520table%2520example_png.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;NoSQL databases can store information in the form of document stores, key-value pairs, graphs databases, and column stores. These DBs do not have predefined schemas that they need to adhere to.&lt;/p&gt;

&lt;p&gt;This distinction makes them useful for specific scenarios. For example, &lt;code&gt;RDB&lt;/code&gt;s are intuitively useful for accounting systems because they model the accounting ledger well. NoSQL is preferred in "Big Data" scenarios where the flexibility of data types are essential.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--UGHCPMPQ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://storage.googleapis.com/algodailyrandomassets/curriculum/systems-design/sql-vs-no-sql/7-nosql-documentstore-ex2_png.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--UGHCPMPQ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://storage.googleapis.com/algodailyrandomassets/curriculum/systems-design/sql-vs-no-sql/7-nosql-documentstore-ex2_png.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Scalability
&lt;/h3&gt;

&lt;p&gt;Scalability refers to how a database technology adapts to an ever-increasing amount of data without sacrificing performance.&lt;/p&gt;

&lt;p&gt;In this regard, singular SQL databases tend to be &lt;strong&gt;vertically scalable&lt;/strong&gt;, in the sense that additional load can be handled by using more efficient and newer hardware (CPUs, RAM and SSD). On the flip side, NoSQL databases tend to be more &lt;strong&gt;horizontally scalable&lt;/strong&gt; (they can automatically handle more traffic by distributing it among more servers in the database cluster).&lt;/p&gt;

&lt;p&gt;Note that relational databases can also be scaled via more hardware-- however, there is some additional work to be done to unify the various database instances. This is why NoSQL databases are preferred in the case when our data is increasing at a very high rate.&lt;/p&gt;

&lt;h3&gt;
  
  
  Support
&lt;/h3&gt;

&lt;p&gt;Historically, SQL database were in the market long before the &lt;code&gt;NoSQL&lt;/code&gt; ones arrived. Therefore, it shouldn’t come as a surprise that almost all the SQL database vendors provide substantial support to their users. Moreover, a huge community of independent consultants is there to help with the large deployment of SQL databases.&lt;/p&gt;

&lt;p&gt;Of course, the same is starting to also be true for NoSQL databases. However, many are still in their embryonic stage, and thus depend more (or often solely) on the open source community for support. Furthermore, independent consultants are also more scarce when it comes to the setup and deployment of large-scale NoSQL databases.&lt;/p&gt;

&lt;h3&gt;
  
  
  Languages Used
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;SQL databases&lt;/strong&gt; &lt;code&gt;support Structured Query Language (SQL)&lt;/code&gt; which allows us to perform various operations on the database. It accomplishes this by providing different types of commands. These commands can be categorized based on their functionality:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Data Definition Language&lt;/strong&gt; (DDL)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Data Manipulation Language&lt;/strong&gt; (DML)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Data Control Language&lt;/strong&gt; (DCL)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Transaction Control Language&lt;/strong&gt; (TCL)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Data Query Language&lt;/strong&gt; (DQL)&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Though &lt;code&gt;SQL&lt;/code&gt; is the most stable and widely used option for performing database operations, it may be restricting in the sense that it requires users to predefine the structure of tables and records. There's also the constraint that all data it stores must be consistent in observing that structure.&lt;/p&gt;

&lt;p&gt;On the other hand, &lt;strong&gt;NoSQL databases&lt;/strong&gt; are &lt;em&gt;dynamic and flexible&lt;/em&gt;. They allow storing unstructured data in multiple ways. Depending on the nature of data, NoSQL options include document stores, key-value pairs, graph databases, and column-oriented stores. As mentioned, you are not required to come up with the structure of data before-hand. Each document may have its own unique structure. This is referred to as &lt;code&gt;Unstructured Query Language (UnQL)&lt;/code&gt; and syntax will vary between products.&lt;/p&gt;

&lt;h3&gt;
  
  
  ACID vs BASE Model:
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;SQL&lt;/code&gt; databases never compromise on &lt;code&gt;ACID&lt;/code&gt; (Atomicity, Consistency, Isolation, Durability) properties. On the flip side, most of the NoSQL &lt;code&gt;DB&lt;/code&gt;s observe the Brewers CAP theorem (Consistency, Availability and Partition tolerance) and the &lt;code&gt;BASE&lt;/code&gt; Model (Basic Availability, Soft-state, Eventual Consistency).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--xq1qyDbg--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://storage.googleapis.com/algodailyrandomassets/curriculum/systems-design/sql-vs-no-sql/11-ACID%2520VS%2520BASE%2520Model.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--xq1qyDbg--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://storage.googleapis.com/algodailyrandomassets/curriculum/systems-design/sql-vs-no-sql/11-ACID%2520VS%2520BASE%2520Model.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Examples
&lt;/h3&gt;

&lt;p&gt;Finally, let's provide some examples. Although there are many RDBs and NoSQL, we will restrict this list to the most popular ones:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;SQL DBs include&lt;/strong&gt; MS-SQL, Oracle, SQLite, MySQL, and Postgres.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;NoSQL DBs include&lt;/strong&gt; CouchDB, MongoDB, BigTable, Cassandra, Redis, RavenDB, HBase, and Neo4j.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;This lesson was originally published at &lt;a href="https://algodaily.com/lessons/a-beginners-reference-to-sql-vs-nosql"&gt;https://algodaily.com&lt;/a&gt;, where I maintain a technical interview course and write think-pieces for ambitious developers.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>computerscience</category>
      <category>tutorial</category>
      <category>beginners</category>
    </item>
    <item>
      <title>How to Get Better at Approaching Coding Interviews</title>
      <dc:creator>Jake Z.</dc:creator>
      <pubDate>Thu, 13 Aug 2020 12:25:48 +0000</pubDate>
      <link>https://dev.to/jacobjzhang/how-to-get-better-at-approaching-coding-interviews-nnp</link>
      <guid>https://dev.to/jacobjzhang/how-to-get-better-at-approaching-coding-interviews-nnp</guid>
      <description>&lt;h2&gt;
  
  
  How to Get Better at Approaching Coding Interviews
&lt;/h2&gt;

&lt;p&gt;So you want to get better at interviewing? It's all in the approach-- this guide is a &lt;strong&gt;step by step walkthrough&lt;/strong&gt; on exactly how to answer coding interview question from companies like Facebook, Amazon, Microsoft, Netflix, or Google.&lt;/p&gt;

&lt;p&gt;This article will cover a lot. It'll walk you through a common technical (whiteboard or non-whiteboard) interview question, and you'll be exposed to things like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The mentality you need to conquer nerves&lt;/li&gt;
&lt;li&gt;Every step to take during the interview&lt;/li&gt;
&lt;li&gt;What patterns to brush up on&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And much more. Let's start by tackling &lt;strong&gt;the mental aspects&lt;/strong&gt; of the interview before the tangible steps to approaching such problems.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ZIB6PB2_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://storage.googleapis.com/algodailyrandomassets/curriculum/misc/approaching-coding-interviews.svg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ZIB6PB2_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://storage.googleapis.com/algodailyrandomassets/curriculum/misc/approaching-coding-interviews.svg"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Getting Over Nerves
&lt;/h2&gt;

&lt;p&gt;Software engineering and technical interviews are nerve-wracking. We all know this, but rarely do we ask why.&lt;/p&gt;

&lt;p&gt;Why do these kinds of interviews specifically conjure up such dread?&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--S64Fx7sT--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://images.pexels.com/photos/105472/pexels-photo-105472.jpeg%3Fauto%3Dcompress%26cs%3Dtinysrgb%26dpr%3D2%26h%3D650%26w%3D940" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--S64Fx7sT--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://images.pexels.com/photos/105472/pexels-photo-105472.jpeg%3Fauto%3Dcompress%26cs%3Dtinysrgb%26dpr%3D2%26h%3D650%26w%3D940" class="col-lg-6 col-sm-12"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Really, there are few consequences.&lt;/p&gt;

&lt;p&gt;Worst case scenario, you fail to correctly express the algorithm they're looking for. Or maybe you can't think of the correct definition for something. You then probably don't get the job.&lt;/p&gt;

&lt;p&gt;That's not a great outcome, but there are far worse things. You can always just go home, brush up on what you missed, and try to apply elsewhere.&lt;/p&gt;

&lt;p&gt;Knowing that doesn't seem to help though, and here's why.&lt;/p&gt;

&lt;p&gt;Our fears usually derive from &lt;em&gt;uncertainty&lt;/em&gt;. That is, the belief that there's a chance you'll be presented with a question or challenge that &lt;em&gt;you have no idea how to solve&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;But this is not actually the case!&lt;/p&gt;

&lt;p&gt;First off, with the right approach-- which the rest of this article will explore in-depth, you can solve any problem.&lt;/p&gt;

&lt;p&gt;Secondly-- yes there is a chance you're asked something completely out of left field. But for the most part, interviewers really &lt;em&gt;do&lt;/em&gt; want to see &lt;strong&gt;how you think&lt;/strong&gt;. As someone who's been on the other end quite a number of times, know that we want you to do well.&lt;/p&gt;

&lt;p&gt;If nerves are still in the way, there are some other solutions. Some things that might be helpful are &lt;a href="https://www.amazon.com/gp/product/1439195455/ref=as_li_qf_asin_il_tl?ie=UTF8&amp;amp;camp=1789&amp;amp;creative=9325&amp;amp;creativeASIN=1439195455&amp;amp;linkCode=as2&amp;amp;tag=algodaily03-20&amp;amp;linkId=00452c0588f28a516612a0778b749753"&gt;daily meditation&lt;/a&gt;, eating a healthy meal that fuels your brain, and &lt;a href="https://www.amazon.com/gp/product/0316113514/ref=as_li_qf_asin_il_tl?ie=UTF8&amp;amp;camp=1789&amp;amp;creative=9325&amp;amp;creativeASIN=0316113514&amp;amp;linkCode=as2&amp;amp;tag=algodaily03-20&amp;amp;linkId=2344bdbddf2327be22643a8ac562f0ac"&gt;regular aerobic exercise&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--0A4LDYU9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://images.pexels.com/photos/1092730/pexels-photo-1092730.jpeg%3Fauto%3Dcompress%26cs%3Dtinysrgb%26dpr%3D2%26h%3D650%26w%3D940" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--0A4LDYU9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://images.pexels.com/photos/1092730/pexels-photo-1092730.jpeg%3Fauto%3Dcompress%26cs%3Dtinysrgb%26dpr%3D2%26h%3D650%26w%3D940" class="col-lg-6 col-sm-12"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What to Do If You Blank Out Completely
&lt;/h2&gt;

&lt;p&gt;With almost any technical challenge, if you have the right approach, you can figure out a way to solve a problem. But what if you genuinely have no idea where to start?&lt;/p&gt;

&lt;p&gt;So let's address something quickly-- if you really have no clue, here's what to do.&lt;/p&gt;

&lt;p&gt;Let's say you're a frontend engineer with a few years of &lt;code&gt;Javascript&lt;/code&gt; Single Page App development under your belt. You're asked the following technical question in an interview.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;When would you apply asynchronous communication between two backend systems?&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;You freeze, and suddenly your chest tightens. You've never worked on any backend systems, and you've forgotten what &lt;code&gt;asynchronous&lt;/code&gt; means. For a few seconds, you stare at the interviewer, and your mind has nowhere to go.&lt;/p&gt;

&lt;p&gt;Here's two potential ways to address this:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Link it to &lt;em&gt;something&lt;/em&gt; you've done&lt;/li&gt;
&lt;li&gt;Emphasize how &lt;em&gt;excited you are&lt;/em&gt; to learn and work on such things&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The first response works because it still allows you to demonstrate your experience:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;I haven't directly worked on backend systems, but can you remind me what &lt;code&gt;asynchronous&lt;/code&gt; means again? Ah, a form of a programming that allows work to be done separately from the primary application thread? I've done something similar with React-- sometimes inserting data into the database via a REST endpoint takes some time, but we want to give immediate feedback to the user that it's being persisted. So **my educated guess&lt;/em&gt;* is that it would be when you want to have a process do something while waiting for something else to complete.*&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In this case, it may not be 100% what the interviewer wanted to hear, but you've shown &lt;em&gt;some&lt;/em&gt; technical acumen. You were also able to include some discussion about past experiences.&lt;/p&gt;

&lt;p&gt;On the other hand, what if there's nothing at all you can relate the question to? Talking about how excited you are and how you &lt;em&gt;would&lt;/em&gt; learn this might be a good alternative:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;To be honest, I'm not sure, but I've heard the term &lt;code&gt;asynchronous&lt;/code&gt; and would love to learn more about backend systems. I'll be sure to read up on it after this interview, do you recommend any books or articles to start with?&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Are Whiteboard Algorithm Interviews Good?
&lt;/h2&gt;

&lt;p&gt;The rest of this lesson will be talking about approaching standardized data structures and algorithm based questions. It will be still relevant, but less so, to small sample challenges like "&lt;em&gt;here's a basic setup, implement a REST API with some scaffolding&lt;/em&gt;".&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--jSee2lXN--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://miro.medium.com/max/600/1%2AHPGzysLVdFgdfV356RpKRA.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--jSee2lXN--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://miro.medium.com/max/600/1%2AHPGzysLVdFgdfV356RpKRA.jpeg" class="img-fluid"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Yes, &lt;strong&gt;whiteboard algorithm interviews are controversial&lt;/strong&gt;. However, there are several reasons they still persist. Firstly, they give several strong signals to the interviewer, such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Can the candidate can think with clarity in front of others (what this lesson aims to address)&lt;/li&gt;
&lt;li&gt;Do they sound like they've prepped for the interview (signal for work ethic)&lt;/li&gt;
&lt;li&gt;Do they have a reasonable amount of logical ability?&lt;/li&gt;
&lt;li&gt;Can they tell a good solution from a bad one?&lt;/li&gt;
&lt;li&gt;How is their grasp of computer science fundamentals?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Secondly&lt;/strong&gt;, they &lt;em&gt;are easy to do at scale&lt;/em&gt;, a consideration especially important if you are a conglomerate that needs to make thousands of annual hires.&lt;/p&gt;

&lt;p&gt;Yes, there are take-home assignments, build-a-feature type of interviews, and week-long "trial" periods. I'm sure these are all great methods.&lt;/p&gt;

&lt;p&gt;However, the standard "can you solve this problem in front of me" &lt;code&gt;data structure&lt;/code&gt; and algorithm questions are still very much the standard at most software companies.&lt;/p&gt;

&lt;p&gt;Let's figure out how to tackle them.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Approach of Good Interviewees
&lt;/h2&gt;

&lt;p&gt;Before we dive in, here's an important note. For any of this to work, you've got to have your data structures and algorithms down pat.&lt;/p&gt;

&lt;p&gt;The more practice you have with these topics, the easier it will be to &lt;code&gt;pattern&lt;/code&gt;-ize them. It'll also be easier to retrieve them from memory come interview time.&lt;/p&gt;

&lt;p&gt;A good starting point is, of course, &lt;a href="https://algodaily.com/curriculum"&gt;AlgoDaily's Premium Course&lt;/a&gt; and &lt;a href="https://algodaily.com/challenges/daily"&gt;daily newsletter problem&lt;/a&gt;. Other recommendations can be found in our lesson around &lt;a href="https://www.algodaily.com/lessons/how-to-prepare-for-a-technical-interview"&gt;How to Prepare for a Technical Interview&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;With all that said, here's the typical steps we recommend for &lt;strong&gt;solving whiteboard questions&lt;/strong&gt;. We'll spend plenty of time exploring each in depth.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Run through a few (1-3) example inputs to &lt;em&gt;get a feel for the problem&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;Unpack &lt;em&gt;the brute force solution&lt;/em&gt; quickly by asking how a human would do this&lt;/li&gt;
&lt;li&gt;Tie the brute force solution back to a &lt;strong&gt;pattern, data structure, or Computer Science technique&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Optimize and run through the same test cases&lt;/em&gt; from step 1 again&lt;/li&gt;
&lt;li&gt;If you have time, &lt;em&gt;call out edge cases&lt;/em&gt; and improvements to the problem&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Communication During the Interview
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--DrwN5YO6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://images.pexels.com/photos/7374/startup-photos.jpg%3Fauto%3Dcompress%26cs%3Dtinysrgb%26dpr%3D2%26h%3D650%26w%3D940" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--DrwN5YO6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://images.pexels.com/photos/7374/startup-photos.jpg%3Fauto%3Dcompress%26cs%3Dtinysrgb%26dpr%3D2%26h%3D650%26w%3D940" class="col-lg-6 col-sm-12"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It's not a secret that a big part of the interview is a test of your communication skills. Software engineering is a team sport.&lt;/p&gt;

&lt;p&gt;The myth of the lone genius programmer is simply that-- a myth. This is especially for big, hairy, impactful projects that require hundreds of thousands of engineers.&lt;/p&gt;

&lt;p&gt;How do you demonstrate strong communication skills?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;You must keep talking&lt;/strong&gt; - I can't emphasize this enough. Unless you need complete silence to think-- which is fine-- you should be voicing your thoughts.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;If you're stuck, let the interviewer know&lt;/li&gt;
&lt;li&gt;If you don't understand the problem, ask more clarifying questions&lt;/li&gt;
&lt;li&gt;If you have no idea what's going on, say you need more context&lt;/li&gt;
&lt;li&gt;If you need a hint, let them know!&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;If you're shy, that's perfectly fine&lt;/strong&gt;. But with regards to the interview-- know that you might be working with either this person, or someone of a similar aptitude and technical ability. For better or worse, how the interviewer sees you during the interview is what they think they'll get when you come on board. Try your best to be friendly and vocal, if only for the few hours it takes to land the job.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to Gather Requirements
&lt;/h2&gt;

&lt;p&gt;Let's move on to practical technical interview tips. We can examine the &lt;a href="https://algodaily.com/challenges/zeros-to-the-end"&gt;Zeros to the End&lt;/a&gt; problem. Here's the prompt:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Write a method that moves all zeros in an array to its end.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The very first thing you should do is &lt;strong&gt;to clarify the requirements.&lt;/strong&gt; Until you know exactly what the problem is, you have no business trying to come up with a solution. Here's why:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Candidate: Cool, zeros to the back, nonzeros in front. That's it right?&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Seems simple enough. Why not jump right to the solving it? Because the interview might then say:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Interviewer: Also, note that you should maintain the order of all other elements. Oh, and this needs to be done in O(n) time.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If you hadn't considered that, you might have gone a very bad path. It's crucial to always &lt;strong&gt;repeat the question in your own words&lt;/strong&gt; and clarify heavily. Get the full scope of requirements, and repeat it so they know you've fully grasped the entirety of the problem&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Candidate: So we want to move all the zeros to the back, while keeping nonzeros in front. We want to also keep the order the nonzeros were originally in, and the algorithm should run in linear time.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Interviewer: Right on.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Start With Inputs and Outputs
&lt;/h2&gt;

&lt;p&gt;The very &lt;em&gt;next&lt;/em&gt; thing to do is either ask for few sample arrays, or come up with your own. Start building your test cases. It helps you start to process how to transform the inputs to get the outputs.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Try to start with a very small input, and increase its size as you do more examples.&lt;/em&gt; Here's what you might say:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Candidate: Very interesting problem. Alright, just to make sure I understand the transformation and result that we want, let me run through a few examples. So if I'm given &lt;code&gt;[0, 1]&lt;/code&gt;, we'd want &lt;code&gt;[1, 0]&lt;/code&gt; back?&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Interviewer: Yes, exactly. &lt;em&gt;(Candidate begins to think of how to move that lone zero in the first example)&lt;/em&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Candidate: Hm, for that one, we just needed to swap the &lt;code&gt;0&lt;/code&gt; with the &lt;code&gt;1&lt;/code&gt;. Now, if given &lt;code&gt;[1, 0, 2, 0, 4, 0]&lt;/code&gt;, I would want &lt;code&gt;[1, 2, 4, 0, 0, 0]&lt;/code&gt; back.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Interviewer: Correct.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Candidate: And &lt;code&gt;[0, 0, 4]&lt;/code&gt; becomes &lt;code&gt;[4, 0, 0]&lt;/code&gt;. Hm...&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  How to Come Up With a Brute Force Solution
&lt;/h2&gt;

&lt;p&gt;Now that you've tried some inputs and outputs, the primary question to ask is this:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;If a machine were not available, how would a human manually solve this?&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Remember, computers are just tools. Before we had them, humans had to calculate things by hand. So asking yourself how you'd do it manually is a great way to start brainstorming ways to solve the problem. When loops and conditionals aren't available, you're able to say in plain English what you need to do.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Candidate: Hm, yeah, for these examples, the result keeps returning an array of the non-zeros plus an array of the zeros at the end. Thinking through a very basic implementation, what I've been doing is: iterating through, finding the non-zeros, and just putting them in an another &lt;code&gt;temp&lt;/code&gt; array. Then I've been filling the rest of the result array with &lt;code&gt;0&lt;/code&gt;s until we've gotten the original length.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Interviewer: Interesting. Want to write that implementation out?&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Use Pseudocode To Clarify Your Thoughts
&lt;/h2&gt;

&lt;p&gt;Unless an algorithm is extremely simple, you'll want to write pseudocode first.&lt;/p&gt;

&lt;p&gt;This is especially true for brute-force solutions. The interviewer may be okay with &lt;em&gt;just&lt;/em&gt; the pseudocode for the first pass, and could ask you to spend the remaining time solving and coding an optimized solution.&lt;/p&gt;

&lt;p&gt;Additionally, thinking in pseudocode is much easier to modify should you find a deleterious error. Here's what it might first look like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;temp = []
zero_count = 0
iterate through array:
  if nonzero, push to new temp
  if zero, increment count
for zero_count times:
  push to temp
return temp
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;It's a good sign you're on the right track if the interviewer modifies the problem to make it a bit more complicated. They might do this by adding a constraint (do this in constant time), or by making the input significantly larger. &lt;em&gt;In my experience, most interviewers will plan to do one easy problem and one harder problem.&lt;/em&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Interviewer: Great, now can you do this without instantiating a new array?&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Don't lose your cool at this point, and also don't get too excited about passing the first part. It's time to tie our brute force solution to a technique to improve it. We will now cover a number of ways to do so.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to Optimize With Patterns and Abstractions
&lt;/h2&gt;

&lt;p&gt;After you've done about ~50-100 practice interview challenges, you'll begin to recognize patterns you can leverage. Here's an example of one: &lt;code&gt;If you want speed, you usually need more space/memory.&lt;/code&gt; This is especially relevant to the next section about using a data structure.&lt;/p&gt;

&lt;p&gt;Look at each step in your solution so far and think about any potential ways to simplify it or break it down. Are there any ways to reduce its complexity?&lt;/p&gt;

&lt;p&gt;One trick is to think about what you're doing from a higher-level. By this, I mean get yourself out of the weeds of the logic, and go back to input-to-output. In the above example, yes we're moving zeros to the end by concatenating arrays, but what are the actual things we'll need to do? The process might be thought of as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Identify the non-zero elements&lt;/li&gt;
&lt;li&gt;Put elements at different indexes&lt;/li&gt;
&lt;li&gt;Find out how many &lt;code&gt;0&lt;/code&gt;s there are&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The beauty of having clear steps like the above is that &lt;em&gt;you can now explore alternative ways to accomplish each one&lt;/em&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;For example, to identify the non-zero elements, you can iterate over the array and use a conditional.&lt;/li&gt;
&lt;li&gt;Alternatively, you can use a &lt;code&gt;filter&lt;/code&gt; method.&lt;/li&gt;
&lt;li&gt;And if that's not helpful, you can also look for multiple &lt;code&gt;zeros&lt;/code&gt; in a row and &lt;code&gt;splice&lt;/code&gt; a new array out.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Something else to ask yourself:  &lt;code&gt;What am I trying to do in plain English?&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Another very easy way to make progress is to &lt;strong&gt;try to futz with the input.&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;If it's a collection, does &lt;em&gt;sorting&lt;/em&gt; or &lt;em&gt;grouping&lt;/em&gt; help?&lt;/li&gt;
&lt;li&gt;If it's a tree, can we transform it into an array or a linked list?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--lZy6Pgmk--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://images.pexels.com/photos/45883/cable-computer-sata-s-ata-45883.jpeg%3Fauto%3Dcompress%26cs%3Dtinysrgb%26dpr%3D2%26h%3D650%26w%3D940" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--lZy6Pgmk--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://images.pexels.com/photos/45883/cable-computer-sata-s-ata-45883.jpeg%3Fauto%3Dcompress%26cs%3Dtinysrgb%26dpr%3D2%26h%3D650%26w%3D940" class="img-fluid"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If tweaking the input doesn't make a dent, maybe it's time to make a bigger transformation.&lt;/p&gt;

&lt;h2&gt;
  
  
  Introduce a Data Structure or Abstract Data Type
&lt;/h2&gt;

&lt;p&gt;This is where a study of data structures (and experience implementing and using them) really helps. If you can identify the bottleneck, you can start to try to throw data structures at the problem to see if there are any performance or spatial gains.&lt;/p&gt;

&lt;p&gt;Going back to the &lt;a href="https://algodaily.com/challenges/zeros-to-the-end"&gt;Zeros to the End&lt;/a&gt; problem we did earlier, our bottleneck is likely the step of &lt;code&gt;putting elements at different indexes&lt;/code&gt;. In that case, we may realize that using a &lt;code&gt;counter&lt;/code&gt; variable is beneficial.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Note that the &lt;code&gt;data structure&lt;/code&gt; doesn't need to be fancy. In our case, we're literally introducing a single &lt;code&gt;int&lt;/code&gt; variable-- but sometimes that's all you need.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;What should the &lt;code&gt;counter&lt;/code&gt; be counting? Well, once we've split the array up into non-zeros (&lt;code&gt;[1, 2, 3]&lt;/code&gt;) and zeros (&lt;code&gt;[0, 0, 0]&lt;/code&gt;), we only really care about where the non-zeros end.&lt;/p&gt;

&lt;p&gt;Because we don't need to worry about what is in the array after non-zero elements, we can simply keep a separate pointer to track the index of the final array. It will let us know where to start the zeros.&lt;/p&gt;

&lt;p&gt;We could then write the follow pseudocode to utilize this strategy:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;insert_position = 0
for i in nums
  if i is not 0
    increase insert_position
    keep it in insert_position
  fill the rest in with 0
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Despite having two loops, the time complexity simplifies to &lt;code&gt;O(n)&lt;/code&gt;. However, the space complexity is constant since we're using the same array, so we have an improvement!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--UzMuJQMe--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i.imgur.com/W4mdIiN.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--UzMuJQMe--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i.imgur.com/W4mdIiN.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  A Tactical Data Structure Cheatsheet
&lt;/h2&gt;

&lt;p&gt;Need access to an element in a collection really fast? &lt;strong&gt;An array already has the location in memory.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Have to insert data quickly? &lt;strong&gt;Add it to a hash table or linked list.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Need a maximum or minimum in O(1) time? &lt;strong&gt;Call in a heap.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Need to model connections? &lt;strong&gt;Get a &lt;a href="https://algodaily.com/lessons/simple-reference-to-graphs"&gt;&lt;code&gt;graph&lt;/code&gt;&lt;/a&gt; in there.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--GwY5kjmx--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://images.pexels.com/photos/533189/pexels-photo-533189.jpeg%3Fauto%3Dcompress%26cs%3Dtinysrgb%26dpr%3D2%26h%3D650%26w%3D940" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--GwY5kjmx--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://images.pexels.com/photos/533189/pexels-photo-533189.jpeg%3Fauto%3Dcompress%26cs%3Dtinysrgb%26dpr%3D2%26h%3D650%26w%3D940" class="col-lg-6 col-sm-12"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The more data structures you know, the better. You can check &lt;a href="https://algodaily.com/curriculum"&gt;the curriculum&lt;/a&gt; for a list of absolute requirements.&lt;/p&gt;

&lt;p&gt;It's also useful (but not necessary) to play with more advanced structures-- think AVL trees, tries, priority queues, suffix arrays, and bloom filters. They are less likely to be needed, but they are useful in industry and can be impressive to pull out during an interview.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A special note about hash tables:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Get to know these guys very well! They can be used in a surprising number of solutions. Many problems can be reduced to searching for elements in a large data collection, finding duplicates in said collection, or storing/retrieving items. Hash tables/hash maps do these things extremely well, so always have it top of mind.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;If an additional &lt;code&gt;data structure&lt;/code&gt; doesn't help, it may be time to try out an old-school (but reliable) technique.&lt;/p&gt;

&lt;h2&gt;
  
  
  Introduce a Computer Science Algorithm Technique
&lt;/h2&gt;

&lt;p&gt;There are a few techniques that everyone should be aware of. Usually these are covered in &lt;code&gt;Intro to Algorithms&lt;/code&gt; classes to categorize algorithms.&lt;/p&gt;

&lt;p&gt;They are generally tools not just beneficial for interviews, but for software engineering work in general, so get to know them!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Divide and Conquer&lt;/strong&gt;: &lt;a href="https://algodaily.com/lessons/problem-solving-with-recursion-vs-iteration"&gt;try to divide the problem&lt;/a&gt; into sub-problems that are easier to think through or solve. This allows for the possibility of..&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Recursion&lt;/strong&gt; - see if you can leverage a function that calls on itself. Be especially wary of &lt;a href="https://algodaily.com/lessons/a-primer-on-recursion"&gt;&lt;code&gt;recursion&lt;/code&gt;&lt;/a&gt; for trees.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Memo-ization&lt;/strong&gt;- Can the partial results you've generated in the brute force solution can be used for larger or different inputs? &lt;a href="https://algodaily.com/lessons/memoization-in-dynamic-programming"&gt;If so, leverage caching of some sort&lt;/a&gt;. What data can you store in memory (or create and store in memory) to help facilitate the algorithm?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Greedy&lt;/strong&gt; - think about what the best move at each iteration or step is. Is there an obvious one at each step? This comes up a lot in &lt;a href="https://algodaily.com/lessons/simple-reference-to-graphs"&gt;&lt;code&gt;graph&lt;/code&gt;&lt;/a&gt; traversal problems like Dijkstra's algorithm.&lt;/p&gt;

&lt;h2&gt;
  
  
  What to Do When None Of the Above Worked
&lt;/h2&gt;

&lt;p&gt;So none of the above patterns, data structures, or techniques are shining any light on the problem. What to do?&lt;/p&gt;

&lt;p&gt;You have two options.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Ask more questions.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;OR&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Say, I'm stuck. Can I please get a hint?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Keep communicating! Interviewers are usually more than happy to give a hint-- in fact, that's their job. Certain interview questions will unfortunately have one or two "key intuitions" that you must grok before you can get to a solution.&lt;/p&gt;

&lt;h2&gt;
  
  
  After You Have A Working Solution
&lt;/h2&gt;

&lt;p&gt;Here's a huge key that takes a while to click. After you've written pseudocode for an optimized solution, &lt;strong&gt;manually run through 1-3 example inputs, step by step, through your pseudocode to make sure it works&lt;/strong&gt;. Warning: nerves will be there, and you may lose your place from time to time, but this is extremely important.&lt;/p&gt;

&lt;p&gt;Good engineers test their code thoroughly and can step through logic. The space between having a pseudocode solution and writing code on the whiteboard is a good time to demonstrate this. &lt;/p&gt;

&lt;p&gt;At this point, you'll also be able to weed out incorrect assumptions or make important realizations ("oh wait, we should use a &lt;code&gt;Map&lt;/code&gt; instead of a JS object instead").&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Candidate: Let's start with &lt;code&gt;[1, 0, 3]&lt;/code&gt;, I think that's a good test candidate. OK, starting with &lt;code&gt;1&lt;/code&gt;, we see that it's not a zero, so it can stay put. We're going to the next element so let's increment our final array index counter. Now we have &lt;code&gt;0&lt;/code&gt;, let's skip. OK, &lt;code&gt;3&lt;/code&gt;, not a zero, our counter is at &lt;code&gt;1&lt;/code&gt; so we put it after &lt;code&gt;1&lt;/code&gt; and we have &lt;code&gt;[1, 3]&lt;/code&gt;. Great! Then we put a &lt;code&gt;0&lt;/code&gt; at the end and we get the results we want.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The interviewer will likely say something like "great, let's code it up", or they may try to find out how confident you are in your solution. If the input-outputs check in, you should feel good about moving on.&lt;/p&gt;

&lt;p&gt;Note: if you're going to be interviewing on a whiteboard, buy a &lt;a href="https://www.amazon.com/gp/product/B075LLKL9F/ref=as_li_qf_asin_il_tl?ie=UTF8&amp;amp;camp=1789&amp;amp;creative=9325&amp;amp;creativeASIN=B075LLKL9F&amp;amp;linkCode=as2&amp;amp;tag=algodaily03-20&amp;amp;linkId=112235175903de2af465b96357b3c5d4"&gt;Magnetic White Board Dry&lt;/a&gt; and practice handwriting code on it.&lt;/p&gt;

&lt;p&gt;There's many things that people don't consider about coding on a whiteboard: space management mostly, but also how to use shorter variables, and writing horizontally.&lt;/p&gt;

&lt;p&gt;Anyway, you've now written this code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;zerosToEnd&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;nums&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;insertPos&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nx"&gt;nums&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;nums&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nx"&gt;nums&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;insertPos&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;nums&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;j&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;insertPos&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;j&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nx"&gt;nums&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;j&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;nums&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;j&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;nums&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Once you've written your solution code out, the technical portion should be done.&lt;/p&gt;

&lt;p&gt;The interview will now steer towards questions for the interviewer. Make sure that you have questions prepped, and try your best not to think about your performance.&lt;/p&gt;

&lt;p&gt;At that point, whatever happened is out of your control, so be forward looking and keep your mind in the present with the interviewer. You'll come across as much more professional if you can maintain your composure, even if the interview didn't go exactly how you wanted.&lt;/p&gt;

&lt;p&gt;I hope you've found this guide helpful. Remember that any coding challenge can be solved with the right approach, and the right mentality. Best of luck!&lt;/p&gt;

&lt;p&gt;&lt;em&gt;This lesson was originally published at &lt;a href="https://algodaily.com/lessons/how-to-get-better-at-coding-interviews"&gt;https://algodaily.com&lt;/a&gt;, where I maintain a technical interview course and write think-pieces for ambitious developers.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>career</category>
      <category>javascript</category>
      <category>beginners</category>
    </item>
  </channel>
</rss>
