{"id":257,"date":"2020-12-20T02:30:45","date_gmt":"2020-12-20T02:30:45","guid":{"rendered":"https:\/\/www.canosielabs.com\/blog\/?p=257"},"modified":"2020-12-20T18:48:51","modified_gmt":"2020-12-20T18:48:51","slug":"climbing-stairs","status":"publish","type":"post","link":"https:\/\/www.canosielabs.com\/blog\/climbing-stairs\/","title":{"rendered":"Climbing Stairs"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">Today, we&#8217;ll talk about the classic <a href=\"https:\/\/leetcode.com\/problems\/climbing-stairs\" data-type=\"URL\" data-id=\"https:\/\/leetcode.com\/problems\/climbing-stairs\" target=\"_blank\" rel=\"noreferrer noopener\">climbing stairs problem<\/a>.  <\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>You are climbing a staircase. It takes\u00a0n\u00a0steps to reach the top.<\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Each time you can either climb\u00a0<code>1<\/code>\u00a0or\u00a0<code>2<\/code>\u00a0steps. In how many distinct ways can you climb to the top?<\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">How do we compose a solution?  First, lets see how this solution can initiatively be solved and then see if it is a dynamic programming problem.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Initiative Solution<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Let&#8217;s start by looking at some simple cases.  We will denote the function f(n) as the distinct number of ways to climb to step n.<\/p>\n\n\n\n<p>\nf(0) = 1\n<br \/>\nf(1) = 1\n<br \/>\nf(2) = 2    ([{1, 1}, {2}])\n<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Take a look at f(2) = how many distinct ways can you climb to the 2nd step.  We can do this in two ways, by taking 2  1-steps and by taking 1 2-step.    Let&#8217;s continue.  What about f(3)?<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large is-resized\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.canosielabs.com\/blog\/wp-content\/uploads\/2020\/12\/path-3.png\" alt=\"\" class=\"wp-image-260\" width=\"409\" height=\"176\" srcset=\"https:\/\/www.canosielabs.com\/blog\/wp-content\/uploads\/2020\/12\/path-3.png 665w, https:\/\/www.canosielabs.com\/blog\/wp-content\/uploads\/2020\/12\/path-3-300x129.png 300w, https:\/\/www.canosielabs.com\/blog\/wp-content\/uploads\/2020\/12\/path-3-250x108.png 250w, https:\/\/www.canosielabs.com\/blog\/wp-content\/uploads\/2020\/12\/path-3-550x237.png 550w, https:\/\/www.canosielabs.com\/blog\/wp-content\/uploads\/2020\/12\/path-3-419x180.png 419w\" sizes=\"auto, (max-width: 409px) 100vw, 409px\" \/><\/figure><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">For f(3), we can see the answer is 3.  We can either start with 1-step then take a one additional 2-step, start with a 2-step and take one additional 1-step or simply take three 1-steps.  It&#8217;s important to note,  in order to get to the <strong>third step<\/strong>, we must be at <strong>step 1<\/strong> (n-2) or <strong>step 2<\/strong> (n-1).   This indicates that the maximum number of distinct ways to climb to step 3 must include the number of distinct ways to climb to step n-1 and n-2.  We&#8217;ll see this more clearly with f(4):<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large is-resized\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.canosielabs.com\/blog\/wp-content\/uploads\/2020\/12\/path-4.png\" alt=\"\" class=\"wp-image-262\" width=\"356\" height=\"390\" srcset=\"https:\/\/www.canosielabs.com\/blog\/wp-content\/uploads\/2020\/12\/path-4.png 764w, https:\/\/www.canosielabs.com\/blog\/wp-content\/uploads\/2020\/12\/path-4-274x300.png 274w, https:\/\/www.canosielabs.com\/blog\/wp-content\/uploads\/2020\/12\/path-4-250x274.png 250w, https:\/\/www.canosielabs.com\/blog\/wp-content\/uploads\/2020\/12\/path-4-550x603.png 550w, https:\/\/www.canosielabs.com\/blog\/wp-content\/uploads\/2020\/12\/path-4-164x180.png 164w, https:\/\/www.canosielabs.com\/blog\/wp-content\/uploads\/2020\/12\/path-4-456x500.png 456w\" sizes=\"auto, (max-width: 356px) 100vw, 356px\" \/><\/figure><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">We see from the diagram, <strong>that f(4) must include f(3) plus f(2).<\/strong>  Because the final step from step 3 and step 2 are different, we can conclude that there are no duplicate paths in all of the paths that make up f(2) + the final 2-step AND all the paths that make up f(3) + the final 1-step.  <\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"764\" height=\"477\" src=\"https:\/\/www.canosielabs.com\/blog\/wp-content\/uploads\/2020\/12\/step-tree.png\" alt=\"\" class=\"wp-image-268\" srcset=\"https:\/\/www.canosielabs.com\/blog\/wp-content\/uploads\/2020\/12\/step-tree.png 764w, https:\/\/www.canosielabs.com\/blog\/wp-content\/uploads\/2020\/12\/step-tree-300x187.png 300w, https:\/\/www.canosielabs.com\/blog\/wp-content\/uploads\/2020\/12\/step-tree-250x156.png 250w, https:\/\/www.canosielabs.com\/blog\/wp-content\/uploads\/2020\/12\/step-tree-550x343.png 550w, https:\/\/www.canosielabs.com\/blog\/wp-content\/uploads\/2020\/12\/step-tree-288x180.png 288w, https:\/\/www.canosielabs.com\/blog\/wp-content\/uploads\/2020\/12\/step-tree-481x300.png 481w\" sizes=\"auto, (max-width: 764px) 100vw, 764px\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Overlapping Sub-problem<\/strong> &#8211;  Yes.  We can see that as we break the problem down, we are repeating the subproblems multiple times.  <\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Optimal Substructure<\/strong> &#8211; Yes. The maximum number of distinct ways to climb to step n is the maximum number of ways to climb to i) climb to step n-1 and take 1 more step plus ii) climb to step n-2 and climb 2 steps. <\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Base case(s)<\/strong> &#8211; the two base cases for this solution is f(0) = f(1) = 1 since there is only 1 way to be at step 0 (the start) and step 1.  <\/p>\n\n\n\n<h2 class=\"wp-block-heading\">DP Table<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">For our state, we only need a 1-D array where at each position n, we simply need to store f(n) = the maximum number of distinct ways to climb to step n.  <\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Memoization<\/h2>\n\n\n\n<p>\nWe can achieve this solution using a top-down memoization technique.  We start at f(n) and keep breaking the problem down into sub-problems until we reach our base cases:<\/p>\n<pre><code class=\"language-java\">class Solution {\n    private int[] cache = new int[46];\n        \n    public int climbStairs(int n) {\n        \n        if (n==0 || n==1) {\n            return 1;\n        }\n        \n        if (cache[n]==0){\n            int result = climbStairs(n-1) + climbStairs(n-2);            \n            cache[n] = result;            \n        }            \n        return cache[n];\n    }        \n}<\/code><\/pre>\n<p>Note: we know from our problem definition, our cache size needs to be 46.  We can be smarter about the size if n was unbounded, but in our case, we want don&#8217;t want to add unnecessary complexity.\n<\/p>\n\n\n\n\n<h2 class=\"wp-block-heading\">Tabulation<\/h2>\n\n\n\n<p>\nUsing tabulation, we can compute from the bottom-up.  I.e. Start at f(1), f(2), f(3)&#8230;and so on up to f(n).\n<\/p>\n<pre><code class=\"language-java\">class Solution {        \n    public int climbStairs(int n) {\n        int[] cache = new int[n + 1];\n        cache[0] = 1;\n        cache[1] = 1;\n        \n        for(int i=2; i&lt;=n; i++){\n            cache[i] = cache[i-1] + cache[i-2];\n        }\n        return cache[n];                \n    }        \n}<\/code><\/pre><br \/><br \/>\n<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Conclusion<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Though the solution is very simple, the tricky portion is the understanding that f(n) = f(n-1) + f(n-2).  While this might be immediately clear to some, it is one of the more common aspects that trick people up.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Today, we&#8217;ll talk about the classic climbing stairs problem. You are climbing a staircase. It takes\u00a0n\u00a0steps to reach the top. Each time you can either&hellip;<\/p>\n","protected":false},"author":3,"featured_media":255,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"bgseo_title":"","bgseo_description":"","bgseo_robots_index":"index","bgseo_robots_follow":"follow","footnotes":""},"categories":[11],"tags":[10],"class_list":["post-257","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-interview-coding-questions","tag-coding-questions"],"_links":{"self":[{"href":"https:\/\/www.canosielabs.com\/blog\/wp-json\/wp\/v2\/posts\/257","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.canosielabs.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.canosielabs.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.canosielabs.com\/blog\/wp-json\/wp\/v2\/users\/3"}],"replies":[{"embeddable":true,"href":"https:\/\/www.canosielabs.com\/blog\/wp-json\/wp\/v2\/comments?post=257"}],"version-history":[{"count":11,"href":"https:\/\/www.canosielabs.com\/blog\/wp-json\/wp\/v2\/posts\/257\/revisions"}],"predecessor-version":[{"id":276,"href":"https:\/\/www.canosielabs.com\/blog\/wp-json\/wp\/v2\/posts\/257\/revisions\/276"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.canosielabs.com\/blog\/wp-json\/wp\/v2\/media\/255"}],"wp:attachment":[{"href":"https:\/\/www.canosielabs.com\/blog\/wp-json\/wp\/v2\/media?parent=257"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.canosielabs.com\/blog\/wp-json\/wp\/v2\/categories?post=257"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.canosielabs.com\/blog\/wp-json\/wp\/v2\/tags?post=257"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}