"use strict";(self.webpackChunkfi=self.webpackChunkfi||[]).push([[5934],{1910:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>l,contentTitle:()=>o,default:()=>h,frontMatter:()=>s,metadata:()=>a,toc:()=>d});var i=t(85893),r=t(11151);const s={id:"greedy",slug:"/recursion/pyramid-slide-down/greedy",title:"Greedy solution",description:"Greedy solution of the Pyramid Slide Down.\n",tags:["java","greedy"],last_updated:{date:new Date("2023-08-17T00:00:00.000Z")}},o=void 0,a={id:"recursion/2023-08-17-pyramid-slide-down/greedy",title:"Greedy solution",description:"Greedy solution of the Pyramid Slide Down.\n",source:"@site/algorithms/04-recursion/2023-08-17-pyramid-slide-down/02-greedy.md",sourceDirName:"04-recursion/2023-08-17-pyramid-slide-down",slug:"/recursion/pyramid-slide-down/greedy",permalink:"/algorithms/recursion/pyramid-slide-down/greedy",draft:!1,unlisted:!1,editUrl:"https://github.com/mfocko/blog/tree/main/algorithms/04-recursion/2023-08-17-pyramid-slide-down/02-greedy.md",tags:[{label:"java",permalink:"/algorithms/tags/java"},{label:"greedy",permalink:"/algorithms/tags/greedy"}],version:"current",lastUpdatedAt:1703786024,formattedLastUpdatedAt:"Dec 28, 2023",sidebarPosition:2,frontMatter:{id:"greedy",slug:"/recursion/pyramid-slide-down/greedy",title:"Greedy solution",description:"Greedy solution of the Pyramid Slide Down.\n",tags:["java","greedy"],last_updated:{date:"2023-08-17T00:00:00.000Z"}},sidebar:"autogeneratedBar",previous:{title:"Na\xefve solution",permalink:"/algorithms/recursion/pyramid-slide-down/naive"},next:{title:"Top-down DP solution",permalink:"/algorithms/recursion/pyramid-slide-down/top-down-dp"}},l={},d=[{value:"Time complexity",id:"time-complexity",level:2},{value:"Running the tests",id:"running-the-tests",level:2}];function c(e){const n={admonition:"admonition",annotation:"annotation",code:"code",em:"em",h2:"h2",li:"li",math:"math",mi:"mi",mo:"mo",mrow:"mrow",ol:"ol",p:"p",pre:"pre",semantics:"semantics",span:"span",strong:"strong",...(0,r.a)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsxs)(n.p,{children:["We will try to optimize it a bit. Let's start with a relatively simple ",(0,i.jsx)(n.em,{children:"greedy"}),"\napproach."]}),"\n",(0,i.jsx)(n.admonition,{title:"Greedy algorithms",type:"info",children:(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.em,{children:"Greedy algorithms"})," can be described as algorithms that decide the action on the\noptimal option at the moment."]})}),"\n",(0,i.jsx)(n.p,{children:"We can try to adjust the na\xefve solution. The most problematic part are the\nrecursive calls. Let's apply the greedy approach there:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-java",children:"public static int longestSlideDown(int[][] pyramid, int row, int col) {\n if (row == pyramid.length - 1) {\n // BASE: We're at the bottom\n return pyramid[row][col];\n }\n\n if (col + 1 >= pyramid[row + 1].length\n || pyramid[row + 1][col] > pyramid[row + 1][col + 1]) {\n // If we cannot go right or it's not feasible, we continue to the left.\n return pyramid[row][col] + longestSlideDown(pyramid, row + 1, col);\n }\n\n // Otherwise we just move to the right.\n return pyramid[row][col] + longestSlideDown(pyramid, row + 1, col + 1);\n}\n"})}),"\n",(0,i.jsxs)(n.p,{children:["OK, if we cannot go right ",(0,i.jsx)(n.strong,{children:"or"})," the right path adds smaller value to the sum,\nwe simply go left."]}),"\n",(0,i.jsx)(n.h2,{id:"time-complexity",children:"Time complexity"}),"\n",(0,i.jsxs)(n.p,{children:["We have switched from ",(0,i.jsx)(n.em,{children:"adding the maximum"})," to ",(0,i.jsx)(n.em,{children:"following the \u201cbigger\u201d path"}),", so\nwe improved the time complexity tremendously. We just go down the pyramid all\nthe way to the bottom. Therefore we are getting:"]}),"\n",(0,i.jsx)(n.span,{className:"katex-display",children:(0,i.jsxs)(n.span,{className:"katex",children:[(0,i.jsx)(n.span,{className:"katex-mathml",children:(0,i.jsx)(n.math,{xmlns:"http://www.w3.org/1998/Math/MathML",display:"block",children:(0,i.jsxs)(n.semantics,{children:[(0,i.jsxs)(n.mrow,{children:[(0,i.jsx)(n.mi,{mathvariant:"script",children:"O"}),(0,i.jsx)(n.mo,{stretchy:"false",children:"("}),(0,i.jsx)(n.mi,{children:"r"}),(0,i.jsx)(n.mi,{children:"o"}),(0,i.jsx)(n.mi,{children:"w"}),(0,i.jsx)(n.mi,{children:"s"}),(0,i.jsx)(n.mo,{stretchy:"false",children:")"})]}),(0,i.jsx)(n.annotation,{encoding:"application/x-tex",children:"\\mathcal{O}(rows)"})]})})}),(0,i.jsx)(n.span,{className:"katex-html","aria-hidden":"true",children:(0,i.jsxs)(n.span,{className:"base",children:[(0,i.jsx)(n.span,{className:"strut",style:{height:"1em",verticalAlign:"-0.25em"}}),(0,i.jsx)(n.span,{className:"mord mathcal",style:{marginRight:"0.02778em"},children:"O"}),(0,i.jsx)(n.span,{className:"mopen",children:"("}),(0,i.jsx)(n.span,{className:"mord mathnormal",children:"ro"}),(0,i.jsx)(n.span,{className:"mord mathnormal",style:{marginRight:"0.02691em"},children:"w"}),(0,i.jsx)(n.span,{className:"mord mathnormal",children:"s"}),(0,i.jsx)(n.span,{className:"mclose",children:")"})]})})]})}),"\n",(0,i.jsx)(n.p,{children:"We have managed to convert our exponential solution into a linear one."}),"\n",(0,i.jsx)(n.h2,{id:"running-the-tests",children:"Running the tests"}),"\n",(0,i.jsx)(n.p,{children:"However, if we run the tests, we notice that the second test failed:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"Test #1: passed\nTest #2: failed\n"})}),"\n",(0,i.jsxs)(n.p,{children:["What's going on? Well, we have improved the time complexity, but greedy\nalgorithms are not the ideal solution to ",(0,i.jsx)(n.strong,{children:"all"})," problems. In this case there\nmay be a solution that is bigger than the one found using the greedy algorithm."]}),"\n",(0,i.jsx)(n.p,{children:"Imagine the following pyramid:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:" 1\n 2 3\n 5 6 7\n 8 9 10 11\n99 13 14 15 16\n"})}),"\n",(0,i.jsx)(n.p,{children:"We start at the top:"}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:["Current cell: ",(0,i.jsx)(n.code,{children:"1"}),", we can choose from ",(0,i.jsx)(n.code,{children:"2"})," and ",(0,i.jsx)(n.code,{children:"3"}),", ",(0,i.jsx)(n.code,{children:"3"})," looks better, so we\nchoose it."]}),"\n",(0,i.jsxs)(n.li,{children:["Current cell: ",(0,i.jsx)(n.code,{children:"3"}),", we can choose from ",(0,i.jsx)(n.code,{children:"6"})," and ",(0,i.jsx)(n.code,{children:"7"}),", ",(0,i.jsx)(n.code,{children:"7"})," looks better, so we\nchoose it."]}),"\n",(0,i.jsxs)(n.li,{children:["Current cell: ",(0,i.jsx)(n.code,{children:"7"}),", we can choose from ",(0,i.jsx)(n.code,{children:"10"})," and ",(0,i.jsx)(n.code,{children:"11"}),", ",(0,i.jsx)(n.code,{children:"11"})," looks better, so we\nchoose it."]}),"\n",(0,i.jsxs)(n.li,{children:["Current cell: ",(0,i.jsx)(n.code,{children:"11"}),", we can choose from ",(0,i.jsx)(n.code,{children:"15"})," and ",(0,i.jsx)(n.code,{children:"16"}),", ",(0,i.jsx)(n.code,{children:"16"})," looks better, so\nwe choose it."]}),"\n"]}),"\n",(0,i.jsxs)(n.p,{children:["Our final sum is: ",(0,i.jsx)(n.code,{children:"1 + 3 + 7 + 11 + 16 = 38"}),", but in the bottom left cell we\nhave a ",(0,i.jsx)(n.code,{children:"99"})," that is bigger than our whole sum."]}),"\n",(0,i.jsx)(n.admonition,{type:"tip",children:(0,i.jsx)(n.p,{children:"Dijkstra's algorithm is a greedy algorithm too, try to think why it is correct."})})]})}function h(e={}){const{wrapper:n}={...(0,r.a)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(c,{...e})}):c(e)}},11151:(e,n,t)=>{t.d(n,{Z:()=>a,a:()=>o});var i=t(67294);const r={},s=i.createContext(r);function o(e){const n=i.useContext(s);return i.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:o(e.components),i.createElement(s.Provider,{value:n},e.children)}}}]);