<?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: Nikhil Vats</title>
    <description>The latest articles on DEV Community by Nikhil Vats (@nikhilvats).</description>
    <link>https://dev.to/nikhilvats</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%2F332308%2Fd899a991-9a3a-475c-bd0f-5261890fff14.jpeg</url>
      <title>DEV Community: Nikhil Vats</title>
      <link>https://dev.to/nikhilvats</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/nikhilvats"/>
    <language>en</language>
    <item>
      <title>Competitive Coding Q1: Min Stack</title>
      <dc:creator>Nikhil Vats</dc:creator>
      <pubDate>Fri, 10 Apr 2020 21:04:40 +0000</pubDate>
      <link>https://dev.to/nikhilvats/competitive-coding-q1-min-stack-357e</link>
      <guid>https://dev.to/nikhilvats/competitive-coding-q1-min-stack-357e</guid>
      <description>&lt;h3&gt;
  
  
  Question
&lt;/h3&gt;

&lt;p&gt;Design a stack that supports push, pop, top, and retrieving the minimum element in constant or O(1) time.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;push(x) -- Push element x onto stack.&lt;/li&gt;
&lt;li&gt;pop() -- Removes the element on top of the stack.&lt;/li&gt;
&lt;li&gt;top() -- Get the top element.&lt;/li&gt;
&lt;li&gt;getMin() -- Retrieve the minimum element in the stack.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Note - If you are confused about what O(1)/constant time means, I have written a &lt;a href="https://dev.to/nikhilvats/complexity-analysis-9p7"&gt;separate comprehensive post&lt;/a&gt; covering the topic time complexity.&lt;/p&gt;

&lt;p&gt;Now then, let's get to it! &lt;/p&gt;

&lt;h3&gt;
  
  
  Approach
&lt;/h3&gt;

&lt;h4&gt;
  
  
  What is a stack?
&lt;/h4&gt;

&lt;p&gt;A stack is a linear data structure that follows a particular order in which the operations are performed. A simple example is a stack of plates placed over one another in a canteen. The plate which is at the top is the first one to be removed, i.e. the plate which has been placed at the bottommost position remains in the stack for the longest period of time. So, it can be simply seen to follow LIFO (Last in first out) order. If you want to learn more about it, take a look at this video -&lt;br&gt;
&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/vZEuSFXSMDI"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;We will use the inbuilt &lt;strong&gt;stack&lt;/strong&gt; in the C++ STL(Standard template library) rather than implementing it ourselves. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;stack&lt;/strong&gt; data structure has the following functions -&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;empty() – Returns whether the stack is empty&lt;/li&gt;
&lt;li&gt;size() – Returns the size of the stack&lt;/li&gt;
&lt;li&gt;top() – Returns a reference to the topmost element of the stack&lt;/li&gt;
&lt;li&gt;push(x) – Adds the element ‘x’ at the top of the stack&lt;/li&gt;
&lt;li&gt;pop() – Deletes the topmost element of the stack&lt;/li&gt;
&lt;/ol&gt;

&lt;h4&gt;
  
  
  Problem
&lt;/h4&gt;

&lt;p&gt;All the above operations take O(1) time. Now, in our problem, there's just 1 additional constraint which is we have to keep track of the minimum element also. This poses the following problems -&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;While pushing we have to update the minimum element in case the new element is less than all the existing ones. This can be done simply by checking whether the newly inserted element is less than the current minimum element, if it is we can simply update the minimum element.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;When popping, if the topmost element is minimum, we have to recalculate the minimum element but this recalculation takes O(n) time as we have to loop through all the elements to find the minimum one. To find the next minimum element in O(1) time, we will change the push, top and pop operations.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h4&gt;
  
  
  Solution
&lt;/h4&gt;

&lt;p&gt;Let &lt;strong&gt;s&lt;/strong&gt; be the stack, &lt;strong&gt;x&lt;/strong&gt; be the element to be inserted and &lt;strong&gt;minElem&lt;/strong&gt; be the current minimum element. Occasionally, we will denote the previous minimum element (before it was updated) by &lt;strong&gt;prevMinElem&lt;/strong&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Push Operation&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&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="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;empty&lt;/span&gt;&lt;span class="p"&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="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&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="n"&gt;minElem&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;x&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="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&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;x&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;minElem&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;     &lt;span class="c1"&gt;// then x is the new minimum element&lt;/span&gt;
&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;     &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;push&lt;/span&gt;&lt;span class="p"&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;x&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;minElem&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;     &lt;span class="n"&gt;minElem&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="mi"&gt;7&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="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;     &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&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;A. In line 5, we push &lt;strong&gt;2*x - minElem&lt;/strong&gt; and not &lt;strong&gt;x&lt;/strong&gt;, this is to keep track of previous the minimum element as we will see in a minute.&lt;br&gt;
 B. Note that, the topmost element i.e. 2*x - minElem is less than x (the new min element) because -&lt;br&gt;
x &amp;lt; minElem (the old one)&lt;br&gt;
=&amp;gt; x - minElem &amp;lt; 0&lt;br&gt;
=&amp;gt; x - minElem + x &amp;lt; x (Add x on both sides)&lt;br&gt;
=&amp;gt; &lt;strong&gt;2x -  minElem &amp;lt; x&lt;/strong&gt;&lt;br&gt;
Hence, now the &lt;strong&gt;topmost element of stack&lt;/strong&gt; is less than &lt;strong&gt;minElem&lt;/strong&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Pop Operation&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;pop&lt;/span&gt;&lt;span class="p"&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="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;empty&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="n"&gt;cout&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class="s"&gt;"Stack empty"&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="k"&gt;else&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="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;top&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;top&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="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;pop&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="mi"&gt;6&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="n"&gt;top&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;minElem&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;         &lt;span class="n"&gt;minElem&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;minElem&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;top&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="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;A. In &lt;strong&gt;Line 6&lt;/strong&gt;, we check if the element to be removed is less than the minimum element, this will happen if the last element inserted was the minimum element, so, as explained in push operation above, we stored &lt;strong&gt;2*x - minElem in the topmost element&lt;/strong&gt; and updated the &lt;strong&gt;minElem to store x&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;B. &lt;strong&gt;Line 7&lt;/strong&gt; is the key step if we expand the expression above -&lt;br&gt;
  minElem = 2*minElem - (2*x - prevMinElem)&lt;br&gt;
  minElem = 2*x - (2*x - prevMinElem)&lt;br&gt;
  minElem = prevMinElem&lt;br&gt;
  Hence we have updated the minElem to store the prevMinElem.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Top Operation&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We have to update the top operation as well because if &lt;strong&gt;x&lt;/strong&gt; was less than &lt;strong&gt;minElem&lt;/strong&gt;, we pushed &lt;strong&gt;2*x-minElem&lt;/strong&gt; in the stack and stored x in &lt;strong&gt;minElem&lt;/strong&gt;. Hence, we change the top operation in the following manner -&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;top&lt;/span&gt;&lt;span class="p"&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="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;top&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;top&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="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;top&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;minElem&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="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;minElem&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="k"&gt;else&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;return&lt;/span&gt; &lt;span class="n"&gt;top&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;A. In &lt;strong&gt;line 2&lt;/strong&gt;, we check if top &amp;lt; minElem, if it is the case then we return minElem as we know that we pushed &lt;strong&gt;2*x-prevMinElem&lt;/strong&gt; in the stack (hence top = 2*x - minElem) and &lt;strong&gt;x&lt;/strong&gt; in &lt;strong&gt;minElem&lt;/strong&gt;. &lt;br&gt;
B. If top is not &amp;lt; minElem, then we simply return minElem.&lt;/p&gt;

&lt;p&gt;You are welcome to try the problem in your IDE now. If you are stuck anywhere, come back to the blog. &lt;/p&gt;

&lt;h3&gt;
  
  
  Code
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="n"&gt;class&lt;/span&gt; &lt;span class="n"&gt;MinStack&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;stack&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;s&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;minElem&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;MinStack&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;cout&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class="s"&gt;"Stack initialized"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="n"&gt;push&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;x&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="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;empty&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;minElem&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&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="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;minElem&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;push&lt;/span&gt;&lt;span class="p"&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;x&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;minElem&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;  
&lt;span class="c1"&gt;// push 2*x-minElem to keep track of prevMinElem&lt;/span&gt;
            &lt;span class="n"&gt;minElem&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="c1"&gt;// update minElem to store x&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="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&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="kt"&gt;void&lt;/span&gt; &lt;span class="n"&gt;pop&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="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;empty&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;cout&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class="s"&gt;"Stack empty"&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;top&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;top&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;pop&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="n"&gt;t&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;minElem&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;minElem&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;minElem&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;top&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// update minElem to prevMinElem&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;top&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;t&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;top&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="n"&gt;t&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;minElem&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;minElem&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; 
        &lt;span class="k"&gt;else&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;t&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;getMin&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="n"&gt;minElem&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;The hard part is over, take a bow! Let's come to time complexity now. We can easily see that the time complexity for each operation is O(1) since there is no loop, etc. and we are simply comparing numbers and performing basic stack operations that have time complexity O(1).&lt;/p&gt;

&lt;p&gt;Drop a comment or tell me on &lt;a href="//twitter.com/NikhilVatss"&gt;twitter&lt;/a&gt; if you liked this article or have any suggestions or reviews. &lt;/p&gt;

</description>
      <category>computerscience</category>
      <category>datastructures</category>
      <category>competitivecoding</category>
      <category>algorithms</category>
    </item>
    <item>
      <title>Merge Sort: Algorithm Analysis</title>
      <dc:creator>Nikhil Vats</dc:creator>
      <pubDate>Sat, 28 Mar 2020 22:23:26 +0000</pubDate>
      <link>https://dev.to/nikhilvats/merge-sort-algorithm-analysis-53db</link>
      <guid>https://dev.to/nikhilvats/merge-sort-algorithm-analysis-53db</guid>
      <description>&lt;h4&gt;
  
  
  Recap -
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Insertion Sort&lt;/strong&gt; is one of the simplest algorithms for sorting. It sorts a list/array by looping through it and placing each element at its correct position in the sorted array which starts from &lt;em&gt;0th element&lt;/em&gt; and ends at &lt;em&gt;current_position-1&lt;/em&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Pseudocode&lt;/strong&gt; is an informal way of writing programs that do not require any strict programming language syntax.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Insertion Sort takes &lt;strong&gt;linear time&lt;/strong&gt; to run in the best case (sorted) and &lt;strong&gt;quadratic time&lt;/strong&gt; in the worst (reverse sorted) and average case.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;In this article, we will learn about some of the common ways of designing algorithms before moving on to merge sort, its running time and its comparison with insertion sort.&lt;/p&gt;

&lt;h3&gt;
  
  
  Designing Algorithms
&lt;/h3&gt;

&lt;p&gt;Some of the common ways of designing algorithms are - &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Incremental approach&lt;/strong&gt;: Building the solution one component at a time. Ex - Insertion Sort&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Divide and Conquer approach&lt;/strong&gt;: Breaking the problem into several sub-problems of smaller size (unit size), solving them recursively and finally, combining their solutions to find the solution for the original problem. Ex - Merge Sort&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Merge Sort
&lt;/h3&gt;

&lt;p&gt;Merge Sort, being a divide and conquer algorithm includes the following steps - &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Divide&lt;/strong&gt;: Split the &lt;strong&gt;n&lt;/strong&gt; element sequence into two subsequences of n/2 elements each.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Conquer&lt;/strong&gt;: Recursively, sort the two subsequences by dividing them further into smaller subsequences until we reach atomic subsequences (subsequences containing one element each).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Combine&lt;/strong&gt;: Merge the two sorted sequences into one sorted sequence repeatedly to find the solution.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Note - In the above steps, sequence means an array/list/etc., we will use these terms interchangeably from now on.&lt;/p&gt;

&lt;h4&gt;
  
  
  Merge Sort Algorithm
&lt;/h4&gt;

&lt;p&gt;Merge sort algorithm is illustrated below -&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="n"&gt;MERGE&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;SORT&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;r&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="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt;                      &lt;span class="c1"&gt;//check for base case&lt;/span&gt;
&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;        &lt;span class="n"&gt;q&lt;/span&gt; &lt;span class="err"&gt;←&lt;/span&gt; &lt;span class="err"&gt;⌊&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="err"&gt;⌋&lt;/span&gt;        &lt;span class="c1"&gt;//divide&lt;/span&gt;
&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;        &lt;span class="n"&gt;MERGE&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;SORT&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;q&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;     &lt;span class="c1"&gt;//conquer&lt;/span&gt;
&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;        &lt;span class="n"&gt;MERGE&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;SORT&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;q&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;r&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;//conquer&lt;/span&gt;
&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;        &lt;span class="n"&gt;MERGE&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;q&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;       &lt;span class="c1"&gt;//combine&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note - For any real number x, we denote the greatest integer less than or equal to x by ⌊x⌋ (read “the floor of x”) and the least integer greater than or equal to x by ⌈x⌉ (read “the ceiling of x”).  &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 1&lt;/strong&gt; checks for the base case i.e. checks that the array doesn't contain only one element (p = r) and proceeds only if that's not the case.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 2&lt;/strong&gt; divides the array into two parts p...q and q+1...r.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 3&lt;/strong&gt; recursively calls the function MERGE-SORT on the first array (p...q).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 4&lt;/strong&gt; recursively calls the function MERGE-SORT on the second array (q+1...r).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 5&lt;/strong&gt; combines the two arrays by calling another function MERGE. The pseudocode for MERGE(A, p, q, r) is given below.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="n"&gt;MERGE&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;q&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;n1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;q&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;p&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;n2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;q&lt;/span&gt;

    &lt;span class="cm"&gt;/* create temporary arrays */&lt;/span&gt;
    &lt;span class="n"&gt;Let&lt;/span&gt; &lt;span class="n"&gt;L&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;n1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="n"&gt;and&lt;/span&gt; &lt;span class="n"&gt;R&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;n2&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="n"&gt;be&lt;/span&gt; &lt;span class="n"&gt;new&lt;/span&gt; &lt;span class="n"&gt;arrays&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;

    &lt;span class="cm"&gt;/* Copy data to temporary arrays L[] and R[] */&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&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;to&lt;/span&gt; &lt;span class="n"&gt;n1&lt;/span&gt;
        &lt;span class="n"&gt;L&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;j&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;to&lt;/span&gt; &lt;span class="n"&gt;n2&lt;/span&gt;
        &lt;span class="n"&gt;R&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;j&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;q&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;j&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt; 

    &lt;span class="cm"&gt;/* Merge the temp arrays back into A[p..r]*/&lt;/span&gt;
    &lt;span class="n"&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="c1"&gt;// Initial index of first subarray &lt;/span&gt;
    &lt;span class="n"&gt;j&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="c1"&gt;// Initial index of second subarray &lt;/span&gt;
    &lt;span class="n"&gt;k&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// Initial index of merged subarray&lt;/span&gt;
    &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;n1&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;j&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;n2&lt;/span&gt;  
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;L&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="n"&gt;R&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;j&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
            &lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;k&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;L&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt; 
            &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  
        &lt;span class="k"&gt;else&lt;/span&gt;
            &lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;k&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;R&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;j&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt; 
            &lt;span class="n"&gt;j&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  
        &lt;span class="n"&gt;k&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; 

    &lt;span class="cm"&gt;/* Copy the remaining elements of L[], if any */&lt;/span&gt;
    &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;n1&lt;/span&gt;
        &lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;k&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;L&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt; 
        &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; 
        &lt;span class="n"&gt;k&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; 

    &lt;span class="cm"&gt;/* Copy the remaining elements of R[], if any */&lt;/span&gt;
    &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="n"&gt;j&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;n2&lt;/span&gt;
        &lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;k&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;R&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;j&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt; 
        &lt;span class="n"&gt;j&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; 
        &lt;span class="n"&gt;k&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;h4&gt;
  
  
  Merge Sort Analysis
&lt;/h4&gt;

&lt;p&gt;Analyzing divide and conquer algorithms results in recurrences relation, for example in merge sort -&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Divide: D(n) = Θ(1) as dividing takes constant time.&lt;/li&gt;
&lt;li&gt;Conquer: solve two subproblems, each of size n/2, which contributes 2T(n/2) to the running time.&lt;/li&gt;
&lt;li&gt;Combine: the MERGE procedure on an n-element subarray takes time Θ(n) because we only loop through elements of different arrays, so C(n) = Θ(n).&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Hence T(n) = Θ(1) if n = 1 (already sorted so, constant time) and T(n) = 2T(n/2) + Θ(n) if n &amp;gt; 1&lt;/p&gt;

&lt;p&gt;Solving this, we get T(n) = Θ(nlogn) i.e. a quasilinear function. Hence, merge sort takes linearithmic/quasilinear running time in the best, average and worst case. We will discuss the different ways of solving it in the next article, for now, just focus on the result. &lt;/p&gt;

&lt;h4&gt;
  
  
  Merge Sort vs Insertion Sort
&lt;/h4&gt;

&lt;p&gt;Now, let's see why running time is important by comparing insertion sort (running time = c1.n&lt;sup&gt;2&lt;/sup&gt;) with merge sort (running time = c2.nlogn) . Take two computers A and B sorting 10&lt;sup&gt;7&lt;/sup&gt; numbers -&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Computer A performs Insertion sort and executes 10-billion instructions per second&lt;br&gt;
Computer A is 1000 times faster than B.&lt;br&gt;
Suppose c1 = 2.&lt;br&gt;
It takes c1.n&lt;sup&gt;2&lt;/sup&gt;/execution speed = 2.(10&lt;sup&gt;7&lt;/sup&gt;)&lt;sup&gt;2&lt;/sup&gt; instructions / 10&lt;sup&gt;10&lt;/sup&gt; instructions per second&lt;br&gt;
= 20000 seconds&lt;br&gt;
= more than 5.5 hours&lt;br&gt;
If rather we sort 100 million numbers than computer A would take more than 23 days.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Computer B performs Merge sort and executes 10 million instructions per second&lt;br&gt;
Suppose c2 = 50&lt;br&gt;
It takes c2.nlogn/execution speed = 50.10&lt;sup&gt;7&lt;/sup&gt; log 10&lt;sup&gt;7&lt;/sup&gt; instructions / 10&lt;sup&gt;7&lt;/sup&gt; instructions per second&lt;br&gt;
= 1163 seconds&lt;br&gt;
= less than 20 minutes&lt;br&gt;
If rather we sort 100 million numbers than computer B would take less than 4 hours.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Hence, even when the computer performing Insertion sort was 1000 times faster and the constant c1 was also less for Insertion sort, the computer performing Merge sort takes much less time when the number of elements is very large. &lt;/p&gt;

&lt;p&gt;That's it for this one. Please comment if there are any mistakes, doubts or suggestions. As I said, we will discuss various ways of solving recurrence relations in the next article to see how we got the running time for merge sort.&lt;/p&gt;

</description>
      <category>computerscience</category>
      <category>datastructures</category>
      <category>algorithms</category>
      <category>mergesort</category>
    </item>
    <item>
      <title>Insertion Sort: Algorithm Analysis</title>
      <dc:creator>Nikhil Vats</dc:creator>
      <pubDate>Thu, 19 Mar 2020 15:20:55 +0000</pubDate>
      <link>https://dev.to/nikhilvats/insertion-sort-algorithm-analysis-1ikn</link>
      <guid>https://dev.to/nikhilvats/insertion-sort-algorithm-analysis-1ikn</guid>
      <description>&lt;p&gt;Hola, first things first, thanks for making it to this article. The last one was a tough one, no? Just for me? Okay then (^__^)!&lt;/p&gt;

&lt;h4&gt;
  
  
  Recap -
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;We analyze space and time complexity of an algorithm to see how efficient it is and whether we should go with it or design a new one according to our needs (the amount of data, the operations we need to perform and so on).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;There are three kinds of analysis namely the worst case, best case, and average case.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;There are five asymptotic notations - &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Big-Oh: upper bound of an algorithm&lt;/li&gt;
&lt;li&gt;Big-Omega: lower bound of an algorithm&lt;/li&gt;
&lt;li&gt;Theta: lower and upper bound (tight bound) of an algorithm &lt;/li&gt;
&lt;li&gt;Little-oh: upper bound that is not asymptotically tight&lt;/li&gt;
&lt;li&gt;Little-omega: lower bound that is not asymptotically tight&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Insertion Sort
&lt;/h3&gt;

&lt;p&gt;Sorting is a very common problem in Computer Science and is asked often in coding interviews and tests. As the name suggests, sorting basically means converting an unsorted input like [1,10,5,8,2] to a sorted output like [1,2,5,8,10], increasing order unless specified otherwise.&lt;/p&gt;

&lt;p&gt;Insertion sort is a common way of sorting and is illustrated below -&lt;/p&gt;

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

&lt;p&gt;Credits - &lt;a href="https://www.geeksforgeeks.org/" rel="noopener noreferrer"&gt;GeeksForGeeks&lt;/a&gt;&lt;br&gt;
You probably know this but GfG is one of the best sources for learning many topics in Computer Science. So, if you ever feel stuck or if you have a doubt, go read the GfG article for that topic.&lt;/p&gt;

&lt;p&gt;Now, let's go through the &lt;strong&gt;pseudocode&lt;/strong&gt; for Insertion Sort but you may ask what is Pseudocode? Here you go. &lt;/p&gt;

&lt;h4&gt;
  
  
  Pseudocode -
&lt;/h4&gt;

&lt;p&gt;It is an informal way of writing programs that do not require any strict programming language syntax. We describe algorithms in Pseudocode so that people who know any programming language can understand it easily. One important point to note is that in pseudocode, index (of arrays, etc.) generally starts from 1 as opposed to 0 in programming languages. The pseudocode for Insertion Sort is -&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;

&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;j&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;length&lt;/span&gt;      
&lt;span class="c1"&gt;// loop from the second element till the end&lt;/span&gt;
&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&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;A&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;j&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;               
&lt;span class="c1"&gt;// store the current element in a variable named key&lt;/span&gt;
&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;    &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;j&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="c1"&gt;// start from current position - 1&lt;/span&gt;
&lt;span class="mi"&gt;4&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;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="n"&gt;and&lt;/span&gt; &lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&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="c1"&gt;// loop until we reach the beginning of array or we find an element less than the key (current element) in the sorted array&lt;/span&gt;
&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;       &lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&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="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="c1"&gt;// if condition in the step above is true, shift the element right one place&lt;/span&gt;
&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;       &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="c1"&gt;// go to the previous position, then go to step 4&lt;/span&gt;
&lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;    &lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&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="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;
&lt;span class="c1"&gt;// insert the current element at its correct position in the sorted array&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;That's it. Simple, eh? If you have any doubts, I would be happy to elaborate in the comments section.&lt;/p&gt;

&lt;p&gt;Now, let's analyze the performance of insertion sort, using the concepts we learned in the previous article.&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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fjypkk3nu9qa68ow53ug9.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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fjypkk3nu9qa68ow53ug9.png" alt="insertion-sort-performance-analysis"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The cost for ith step is ci. The cost for any comment is 0 since it's not performed and is just for the programmer's understanding. Hence, insertion sort is essentially a seven-step algorithm.&lt;/p&gt;

&lt;p&gt;Now, steps 1, 2, 4 and 8 will run &lt;strong&gt;n-1&lt;/strong&gt; times (from second to the last element). &lt;/p&gt;

&lt;p&gt;Step 5 will run tj times (assumption) for n-1 elements (second till last). Similarly, steps 6 and 7 will run tj-1 times for n-1 elements. They will run one less time because for each element - before line 8 is executed, while condition (step 5) is checked/executed but steps 6 and 7 ain't as the condition in while statement fails.&lt;/p&gt;

&lt;p&gt;Summing up, the total cost for insertion sort is -&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fgv0jui51vakpc9izxw4d.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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fgv0jui51vakpc9izxw4d.png" alt="Total cost for insertion sort"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now we analyze the best, worst and average case for Insertion Sort.&lt;/p&gt;

&lt;h4&gt;
  
  
  Best case -
&lt;/h4&gt;

&lt;p&gt;The array is already sorted. tj will be 1 for each element as while condition will be checked once and fail because A[i] is not greater than &lt;strong&gt;key&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Hence cost for steps 1, 2, 4 and 8 will remain the same. Cost for step 5 will be n-1 and cost for step 6 and 7 will be 0 as tj-1 = 1-1 = 0. So cost for best case is - &lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fh1awr0xux54osurmv8vs.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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fh1awr0xux54osurmv8vs.png" alt="best-case-insertion-sort"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We can express this running time as &lt;strong&gt;an+b&lt;/strong&gt; where a and b are constants that depend on costs ci. Hence, running time is a linear function of size &lt;strong&gt;n&lt;/strong&gt;, that is, the number of elements in the array.&lt;/p&gt;

&lt;h4&gt;
  
  
  Worst case -
&lt;/h4&gt;

&lt;p&gt;The array is reverse sorted. tj will be j for each element as &lt;strong&gt;key&lt;/strong&gt; will be compared with each element in the sorted array and hence, while condition will be checked j-1 times for comparing key with all elements in the sorted array plus one more time when i becomes 0 (after which i &amp;gt; 0 will fail, control goes to step 8).&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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fl68j1b56vftbfhluilfn.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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fl68j1b56vftbfhluilfn.png" alt="worst-case-time-calculation"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The explanation for the first summation is simple - the sum of numbers from 1 to n is n(n+1)/2, since the summation starts from 2 and not 1, we subtract 1 from the result. We can simplify the second summation similarly by replacing n by n-1 in the first summation. &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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Foaz6ogeee727o8chdm5w.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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Foaz6ogeee727o8chdm5w.png" alt="worst-case-insertion-sort-time"&gt;&lt;/a&gt;&lt;br&gt;
We can express this worst-case running time as &lt;strong&gt;an&lt;sup&gt;2&lt;/sup&gt;+bn+c&lt;/strong&gt; where a, b and c are constants that depend on costs ci. Hence, running time is a quadratic function of size &lt;strong&gt;n&lt;/strong&gt;, that is, the number of elements in the array.&lt;/p&gt;

&lt;h4&gt;
  
  
  Average case -
&lt;/h4&gt;

&lt;p&gt;The average case running time is the same as the worst-case (a quadratic function of n). On average, half the elements in A[1..j-1]􏰂 are less than A[j] 􏰂, and half the elements are greater. On average, therefore, we check half of the subarray A[1..j-1], and so tj is about j/2. The resulting average-case running time turns out to be a quadratic function of the input size, just like the worst-case running time.&lt;/p&gt;

&lt;p&gt;That's it for today. If you have any reviews/suggestions, please tell them in the comments section. In the next article, we will go through various techniques for finding &lt;/p&gt;

</description>
      <category>insertionsort</category>
      <category>computerscience</category>
      <category>datascience</category>
      <category>algorithms</category>
    </item>
    <item>
      <title>Complexity Analysis</title>
      <dc:creator>Nikhil Vats</dc:creator>
      <pubDate>Wed, 18 Mar 2020 20:48:15 +0000</pubDate>
      <link>https://dev.to/nikhilvats/complexity-analysis-9p7</link>
      <guid>https://dev.to/nikhilvats/complexity-analysis-9p7</guid>
      <description>&lt;h4&gt;
  
  
  Recap
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;Data structures are used for storing data and organizing data in a way such that the required operations like sorting, inserting can be performed efficiently.&lt;/li&gt;
&lt;li&gt;An algorithm is a finite set of instructions designed to perform a specific task.&lt;/li&gt;
&lt;li&gt;Data structures and algorithms together make a program.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Complexity Analysis
&lt;/h3&gt;

&lt;p&gt;There are two types of complexity we analyze when we design an algorithm  -&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Time Complexity tells us how much time an algorithm takes to complete.&lt;/li&gt;
&lt;li&gt;Space Complexity tells us how much storage does this algorithm need for completion.&lt;/li&gt;
&lt;/ol&gt;

&lt;h4&gt;
  
  
  Kinds of time complexity analysis -
&lt;/h4&gt;

&lt;h5&gt;
  
  
  1. Worst case
&lt;/h5&gt;

&lt;ul&gt;
&lt;li&gt;upper bound on running time for &lt;em&gt;any&lt;/em&gt; input. &lt;/li&gt;
&lt;li&gt;T(n) = maximum time of an algorithm on any input of size &lt;strong&gt;n&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h5&gt;
  
  
  2. Average case
&lt;/h5&gt;

&lt;ul&gt;
&lt;li&gt;Expected running time over &lt;em&gt;all&lt;/em&gt; inputs.&lt;/li&gt;
&lt;li&gt;T(n) = expected running time of an algorithm over all inputs of size &lt;strong&gt;n&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h5&gt;
  
  
  3. Best case
&lt;/h5&gt;

&lt;ul&gt;
&lt;li&gt;lower bound on running time for &lt;em&gt;any&lt;/em&gt; input.&lt;/li&gt;
&lt;li&gt;T(n) = minimum time of an algorithm on any input of size &lt;strong&gt;n&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Asymptotic Notations
&lt;/h3&gt;

&lt;p&gt;Asymptotic notations are a very important part of this course and it will really haunt you (&amp;gt;_&amp;lt;) if you don't understand them properly. Most of us face difficulties at first in understanding asymptotic notations, in my case, I read class notes, &lt;a href="https://stackoverflow.com/questions/1364444/difference-between-big-o-and-little-o-notation"&gt;stack overflow&lt;/a&gt;, and &lt;a href="https://github.com/CodeClub-JU/Introduction-to-Algorithms-CLRS/blob/master/Introduction%20to%20Algorithms%20-%203rd%20Edition.pdf"&gt;this book&lt;/a&gt; before my mid-semester exam to understand them. The issue is as we move on to the o (little-oh) and w (little-omega) notations, we get confused. So, I have summarised all I have learned from the above resources to explain in the best way possible.  Pay attention y'all or maybe take a break and come back with a fresh mind?&lt;/p&gt;

&lt;p&gt;The asymptotic notations are of the following five types -&lt;/p&gt;

&lt;h4&gt;
  
  
  1. O (Big-Oh) notation
&lt;/h4&gt;

&lt;p&gt;O-notation, pronounced "big-oh notation", is used to describe the asymptotic upper bound of an algorithm. Formally, it is defined as:&lt;/p&gt;

&lt;p&gt;For a given function, g(n) , we denote by O(g(n)) the set of functions,&lt;br&gt;
O(g(n)) = { f(n): there exist &lt;strong&gt;positive constants c and n0&lt;/strong&gt; such that&lt;br&gt;
&lt;strong&gt;0 &amp;lt;= f(n) &amp;lt;= c.g(n) for all n &amp;gt;= n0&lt;/strong&gt; }.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--r6C8lmub--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/m7acz08xwugmq2vh3gm7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--r6C8lmub--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/m7acz08xwugmq2vh3gm7.png" alt="Big-O-notation-graph"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Some common O notations are -&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;O(1) - constant, independent of size n&lt;/li&gt;
&lt;li&gt;O(log n) - logarithmic&lt;/li&gt;
&lt;li&gt;O(n) - linear&lt;/li&gt;
&lt;li&gt;O(nlogn) = O(logn!) - loglinear, quasilinear or linearithmic&lt;/li&gt;
&lt;li&gt;O(n&lt;sup&gt;2&lt;/sup&gt;) - quadratic&lt;/li&gt;
&lt;li&gt;O(n&lt;sup&gt;c&lt;/sup&gt;) - polynomial or algebraic&lt;/li&gt;
&lt;li&gt;O(c&lt;sup&gt;n&lt;/sup&gt;) where c &amp;gt; 1 - exponential&lt;/li&gt;
&lt;li&gt;O(n!) - factorial&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Ivi_HtVf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/aixxzxil4rn7kr38nrn3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Ivi_HtVf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/aixxzxil4rn7kr38nrn3.png" alt="Big O complexity chart"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  2. Ω (Big-Omega) notation
&lt;/h4&gt;

&lt;p&gt;Ω-notation, pronounced "big-omega notation", is used to describe the asymptotic lower bound of an algorithm. Formally, it is defined as:&lt;/p&gt;

&lt;p&gt;For a given function, g(n), we denote by Ω(g(n)) the set of functions,&lt;br&gt;
Ω(g(n)) = { f(n): there exist &lt;strong&gt;positive constants c and n0&lt;/strong&gt; such that &lt;br&gt;
&lt;strong&gt;0 &amp;lt;= c.g(n) &amp;lt;= f(n) for all n &amp;gt;= n0&lt;/strong&gt; }. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--cay4eWcG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/vs3tlsw98c9ixq14uz0i.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--cay4eWcG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/vs3tlsw98c9ixq14uz0i.png" alt="Big Omega"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  3. Θ (Theta) notation
&lt;/h4&gt;

&lt;p&gt;We talked about O notation above. The disadvantage of describing the complexity of an algorithm in terms of O notation is that if we say that an algorithm runs in f(n)=O(n&lt;sup&gt;2&lt;/sup&gt;), then that algorithm could actually run in n time.&lt;/p&gt;

&lt;p&gt;Here comes the role of Θ notation. Usually, we want to be able to say that an algorithm runs no slower and no faster than a particular function. This is called a &lt;strong&gt;tight bound&lt;/strong&gt;. Hence, we define Θ notation as -&lt;/p&gt;

&lt;p&gt;For a given function, g(n), we denote by Θ(g(n)) the set of&lt;br&gt;
functions&lt;br&gt;
Θ(g(n)) = { f(n): there exist &lt;strong&gt;positive constants c1 , c2 , and n0&lt;/strong&gt; such that &lt;strong&gt;0 ≤ c1.g(n) &amp;lt;= f(n) &amp;lt;= c2.g(n) for all n &amp;gt;= n0&lt;/strong&gt; }.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Y8HvxU7G--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/gswj37ipze0qbdinr3tr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Y8HvxU7G--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/gswj37ipze0qbdinr3tr.png" alt="Theta-notation"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  4. o (little-oh) notation
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;o-notation, pronounced little-oh notation, is used to denote a upper bound that is not &lt;strong&gt;asymptotically tight&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Asymptotically tight&lt;/strong&gt;: We say a bound f(n) = O(g(n)) is asymptotically tight if f(n) = Θ(g(n)), that is, if also g(n) = O(f(n). The bound 2n&lt;sup&gt;2&lt;/sup&gt; = O(n&lt;sup&gt;2&lt;/sup&gt;) is asymptotically tight as n&lt;sup&gt;2&lt;/sup&gt; = O(2n&lt;sup&gt;2&lt;/sup&gt;) also hold, but the bound 2n = O(n&lt;sup&gt;2&lt;/sup&gt;) is not as n&lt;sup&gt;2&lt;/sup&gt; != O(2n) because there is no c for which c.2n &amp;gt;= n&lt;sup&gt;2&lt;/sup&gt; for n&amp;gt;no. So 2n = o(n&lt;sup&gt;2&lt;/sup&gt;) but 2n&lt;sup&gt;2&lt;/sup&gt; != o(n&lt;sup&gt;2&lt;/sup&gt;).&lt;/li&gt;
&lt;li&gt; For a given function, g(n), we denote by o(g(n)) the set of functions
o(g(n)) = { f(n): for any positive constant &lt;strong&gt;c &amp;gt; 0&lt;/strong&gt;, there exists a constant &lt;strong&gt;n0 &amp;gt; 0 such that 0 &amp;lt;= f(n) &amp;lt; c.g(n) for all n &amp;gt;= n0&lt;/strong&gt; }.&lt;/li&gt;
&lt;li&gt;The implication of this is that g(n) becomes insignificant relative to f(n) as n approaches infinity: 
&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ksmDxqRW--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/b2n7wi9zwkzwciisogi3.png" alt="limit for little oh"&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;So the main differences between Big O and small O are points 2 and 4 and the fact that there is no equality in the definition of little oh (in point 3, compare with the definition of Big O). Apart from these, some other differences (picked from &lt;a href="https://stackoverflow.com/questions/1364444/difference-between-big-o-and-little-o-notation"&gt;here&lt;/a&gt;) are -&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;In Big-O, it is only necessary that you find a particular multiplier c for which the inequality holds beyond some minimum n. In Little-o, it must be that there is a minimum x after which the inequality holds no matter how small you make c, as long as it is not negative or zero.&lt;/li&gt;
&lt;li&gt;Although somewhat counter-intuitively, Little-oh is the stronger statement. There is a much larger gap between the growth rates of f and g if f ∈ o(g) than if f ∈ O(g).&lt;/li&gt;
&lt;li&gt;One illustration of the disparity is this: f ∈ O(f) is true, but f ∈ o(f) is false.&lt;/li&gt;
&lt;li&gt;Therefore, Big-Oh can be read as "f ∈ O(g) means that f's asymptotic growth is no faster than g's", whereas little-o can be read as "f ∈ o(g) means that f's asymptotic growth is strictly slower than g's". It's like &amp;lt;= versus &amp;lt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  5. ω (little-omega) notation
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;ω-notation, pronounced little-omega notation, is used to denote a lower bound that is not asymptotically tight.&lt;/li&gt;
&lt;li&gt;For a given function, g(n), we denote by ω(g(n)) the set of functions
ω(g(n)) = { f(n): for any positive constant &lt;strong&gt;c &amp;gt; 0&lt;/strong&gt;, there exists a constant &lt;strong&gt;n0 &amp;gt; 0 such that 0 &amp;lt;= c.g(n) &amp;lt; f(n) for all n &amp;gt;= n0&lt;/strong&gt; }.&lt;/li&gt;
&lt;li&gt;The implication of this is that g(n) becomes insignificant relative to f(n) as n approaches infinity:
&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--9E3mLRwQ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/mwof78w8th740wiuvnwz.png" alt="limit for small omega"&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;We can analyze the differences between little and big omega in a similar manner as done above.&lt;/p&gt;

&lt;p&gt;Some relational properties of the notations are given below -&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--MURpxjgS--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/bliombyq2d56saqoj6k8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--MURpxjgS--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/bliombyq2d56saqoj6k8.png" alt="Transitivity"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--a_WL_e6E--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/24b25nqi3obt0s8ujs7g.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--a_WL_e6E--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/24b25nqi3obt0s8ujs7g.png" alt="Reflexivity"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--o2qIxXSb--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/g6ouyqv0f6p8kzm3actm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--o2qIxXSb--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/g6ouyqv0f6p8kzm3actm.png" alt="Symmetry"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Thanks for bearing me, this was a long one for all of us. I hope you understood. If you have any doubts/suggestions/reviews, please let me know in the comment section. Your one single praise can go a long way in motivating me xD. In the coming articles, we will use the notations described above, so if you are lost about what the use of these notations is, read the next article.&lt;/p&gt;

</description>
      <category>algorithms</category>
      <category>codenewbie</category>
      <category>computerscience</category>
      <category>timecomplexity</category>
    </item>
    <item>
      <title>Introduction to DSA</title>
      <dc:creator>Nikhil Vats</dc:creator>
      <pubDate>Wed, 18 Mar 2020 14:35:07 +0000</pubDate>
      <link>https://dev.to/nikhilvats/introduction-to-dsa-28dg</link>
      <guid>https://dev.to/nikhilvats/introduction-to-dsa-28dg</guid>
      <description>&lt;p&gt;Hey everyone, in this series we will go through the basics of Data Structures and Algorithms. This post is the first article in the series. The series is based on my learnings from the course with the same name taught at &lt;strong&gt;BITS Pilani, Rajasthan, India&lt;/strong&gt;. The series will cover the following topics in no particular order - &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Introduction&lt;/li&gt;
&lt;li&gt;Linear Structures (Arrays, Linked lists)&lt;/li&gt;
&lt;li&gt;Non-Linear Structures (Trees, Graphs)&lt;/li&gt;
&lt;li&gt;Sorting and Searching Techniques (including Hashing)&lt;/li&gt;
&lt;li&gt;Performance Analysis (Time and Space Complexity)&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Most of the content of the course is handpicked from the book &lt;strong&gt;Introduction to Algorithms by Cormen (CLRS)&lt;/strong&gt;. I highly recommend reading it if you are stuck at any point. You can find it &lt;a href="https://github.com/CodeClub-JU/Introduction-to-Algorithms-CLRS/blob/master/Introduction%20to%20Algorithms%20-%203rd%20Edition.pdf"&gt;here&lt;/a&gt; (for free!).&lt;/p&gt;

&lt;p&gt;In this article, we will cover the basics of Data Structures and Algorithms - the definitions, their advantages, etc.&lt;/p&gt;

&lt;h4&gt;
  
  
  1. Data Structure -
&lt;/h4&gt;

&lt;p&gt;A Data structure is a way of storing and organizing data so that it can be used efficiently. For example, let's assume that we want to write the names of people along with their phone numbers in a diary. Consider two cases -&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;We write the names of people followed by their phone numbers starting from page 1 followed by page 2 and so on.&lt;/li&gt;
&lt;li&gt;We reserve one page for each letter (A, B, C, D,.., Z) and write the names of people and their phone numbers on the page reserved for the first letter of the first name. For example - Tanya's phone number will be stored on the page reserved for the letter 'T'.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Now the method we choose for writing names depends on our use. If we want to make a phonebook, the second way is probably better since we can search a phone number easily later (go to the page marked 'T' for getting the phone number of Tanya) but if we just want to write 2 or 3 phone numbers method 1 is better.&lt;/p&gt;

&lt;p&gt;So the data structure we use helps us to manage and organize our data more efficiently and makes our code cleaner and efficient. Some commonly used data structures are &lt;em&gt;Arrays, Linked Lists, Graphs, Trees, Stack, Queue&lt;/em&gt;.&lt;br&gt;
The common operations performed on data structures are &lt;em&gt;Sorting, Merging, Deleting, Inserting, Traversing, Searching&lt;/em&gt;.&lt;/p&gt;

&lt;h4&gt;
  
  
  2. Algorithms -
&lt;/h4&gt;

&lt;p&gt;An algorithm is a finite set of instructions that accomplishes a particular task. It is a high level (human-readable), language-independent description of a step by step process for solving a problem. Algorithms and Data Structures together make a computer program that solves a problem like storing phone numbers of people alphabetically efficiently. &lt;/p&gt;

&lt;p&gt;That's it for this one. In the next article, I will talk about Performance Analysis. Please comment if you have any suggestions or requests.&lt;/p&gt;

</description>
      <category>algorithms</category>
      <category>datascience</category>
      <category>datastructures</category>
    </item>
    <item>
      <title>Pretty printing data in console</title>
      <dc:creator>Nikhil Vats</dc:creator>
      <pubDate>Wed, 30 Jan 2019 00:00:00 +0000</pubDate>
      <link>https://dev.to/nikhilvats/pretty-printing-data-in-console-n35</link>
      <guid>https://dev.to/nikhilvats/pretty-printing-data-in-console-n35</guid>
      <description>&lt;p&gt;If you are a frontend developer, you must have spent a considerable amount of time looking at the structure of the complex nested data coming from backend. No one loves going to the browser's console and click on those tiny little arrows only to see 100s of lines of messy data. Read this post to increase your efficiency by learning two better ways of logging data to console.&lt;/p&gt;

&lt;p&gt;Tip: Click an image to zoom in.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Using console.table()
&lt;/h3&gt;

&lt;p&gt;You can use &lt;code&gt;console.table(data)&lt;/code&gt; for pretty-printing the data (array of objects, an array of arrays) in the format of a table. &lt;/p&gt;

&lt;p&gt;Note that in &lt;strong&gt;Chrome&lt;/strong&gt; &lt;code&gt;console.table(data)&lt;/code&gt; may not work sometimes when the data is just an array of strings or numbers (data is not compound). In that case just use &lt;code&gt;console.table([data])&lt;/code&gt;.&lt;/p&gt;

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

// Syntax - 
console.table(data [, columns])


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

&lt;/div&gt;

&lt;p&gt;The function takes two parameters - &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Data to be pretty-printed. [&lt;strong&gt;Mandatory&lt;/strong&gt;]&lt;/li&gt;
&lt;li&gt;An array containing the columns to be included in the output. [Optional]&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Example - &lt;/p&gt;

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

// an array of objects, logging only firstName

function Person(firstName, lastName) {
  this.firstName = firstName;
  this.lastName = lastName;
}

var john = new Person("John", "Smith");
var jane = new Person("Jane", "Doe");
var emily = new Person("Emily", "Jones");

console.table([john, jane, emily], ["firstName"]);


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

&lt;/div&gt;

&lt;p&gt;Result -&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fgczhq6g11x4xkp2bj9bt.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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fgczhq6g11x4xkp2bj9bt.png" alt="console.table-result"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can also sort the table in ascending or descending order of any field by clicking the arrow in the column headers. The upward arrow in the right corner of the second column indicates that the table is arranged based on the ascending order of first names.&lt;/p&gt;

&lt;p&gt;Keep in mind that &lt;code&gt;console.table()&lt;/code&gt; is &lt;strong&gt;not supported in IE&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Using console.log() with JSON.stringify()
&lt;/h3&gt;

&lt;p&gt;You can also use &lt;code&gt;console.log(JSON.stringify(data, undefined, 4))&lt;/code&gt; for pretty-printing the data with whitespaces for readability.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;JSON.stringify()&lt;/code&gt; takes 3 parameters -&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The first parameter contains the data. [&lt;strong&gt;Mandatory&lt;/strong&gt;]&lt;/li&gt;
&lt;li&gt;The second one is the replacer parameter which can be an array or a function. This parameter is used for filtering the properties of the object (ex - printing some selected fields only). [Optional]&lt;/li&gt;
&lt;li&gt;The third one is the number of spaces to improve the readability of data by formatting it. The max value can be 10. [Optional]&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Example - &lt;/p&gt;

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

function replacer(key, value) {
  // Filtering out properties
  if (typeof value !== 'string') {
    return undefined;
  }
  return value;
}

var foo = {foundation: 'Mozilla', model: 'box', week: 45, transport: 'car', month: 7};
console.log(JSON.stringify(foo, replacer,4));

// Alternatively we could have just used console.log(JSON.stringify(foo, ['week', 'month']));


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

&lt;/div&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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fhtmu6rmyt7n4o2wozg2i.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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fhtmu6rmyt7n4o2wozg2i.png" alt="JSON.stringify-result"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>debugging</category>
      <category>data</category>
      <category>console</category>
    </item>
  </channel>
</rss>
