<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:blogger='http://schemas.google.com/blogger/2008' xmlns:georss='http://www.georss.org/georss' xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-7496974970329409400</id><updated>2026-09-23T10:03:42.245+05:30</updated><category term="LeetCode"/><category term="Google"/><category term="DP"/><category term="Binary Tree"/><category term="Amazon"/><category term="Linked List"/><category term="Microsoft"/><category term="Uber"/><category term="Graph"/><category term="Binary Search Tree"/><category term="Bits magic"/><category term="Facebook"/><category term="System Design"/><category term="Binary Search"/><category term="Adobe"/><category term="Divide and Conquer"/><category term="SlidingWindow"/><category term="backtracking"/><category term="Flipkart"/><category term="Puzzle"/><category term="GFG"/><category term="LintCode"/><category term="Two Pointers"/><category term="GeeksForGeeks"/><category term="LLD"/><category term="Netflix Tech Blog"/><category term="Pubmatic"/><category term="Salesforce"/><category term="Synopsys"/><category term="Apple"/><category term="Coinbase"/><category term="Infibeam"/><category term="LinkedIn"/><category term="Paytm"/><category term="AirBnb"/><category term="Algorithm"/><category term="Avalara"/><category term="CareerCup"/><category term="Carwale"/><category term="Deliveroo"/><category term="Directi"/><category term="Indeed"/><category term="Informatica"/><category term="InterviewBit"/><category term="MAZ Digital"/><category term="OLA"/><category term="SAP Labs"/><category term="Thought Works"/><title type='text'>Zig-Zag World of Algorithm and Data Structures</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://algods-cracker.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7496974970329409400/posts/default?redirect=false'/><link rel='alternate' type='text/html' href='http://algods-cracker.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><link rel='next' type='application/atom+xml' href='http://www.blogger.com/feeds/7496974970329409400/posts/default?start-index=26&amp;max-results=25&amp;redirect=false'/><author><name>Nishant Saxena</name><uri>http://www.blogger.com/profile/17860524009847591950</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjOdjS62BAEI1iMG_zd6lew4qyFGpfJhWHp0AJWQhiJvxQpSGg0AFZ5euJG7tK0D-EGQFno32hF-i1x4E2A49re_8-b9r0QHwXQ-9X_EvlAcekIjUYMaA1v6dWzDqzkBg/s220/2d230a1.jpg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>732</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-7496974970329409400.post-7452380631048686014</id><published>2026-01-25T21:15:00.002+05:30</published><updated>2026-01-25T21:15:52.690+05:30</updated><category scheme="http://www.blogger.com/atom/ns#" term="LeetCode"/><title type='text'>[LeetCode] All Divisions With the Highest Score of a Binary Array</title><content type='html'>&lt;p&gt;&lt;b&gt;Problem:&lt;/b&gt; You are given a 0-indexed binary array nums of length n. nums can be divided at index i (where 0 &amp;lt;= i &amp;lt;= n) into two arrays (possibly empty) numsLeft and numsRight:&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;numsLeft has all the elements of nums between index 0 and i - 1 (inclusive), while numsRight has all the elements of nums between index i and n - 1 (inclusive).&lt;/li&gt;&lt;li&gt;If i == 0, numsleft is empty, while numsright has all the elements of nums.&lt;/li&gt;&lt;li&gt;If i == n, numsleft has all the elements of nums, while numsright is empty.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;The &lt;i&gt;division score&lt;/i&gt; of an index i is &lt;i&gt;the sum of the number of 0&#39;s in numsLeft and the number of 1&#39;s in numsRight&lt;/i&gt;.&lt;/p&gt;&lt;p&gt;Return &lt;i&gt;all distinct indices&lt;/i&gt; that have the highest possible division score. You may return the answer in any order.&lt;/p&gt;&lt;p&gt;Example:&lt;/p&gt;&lt;pre style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-translate-x: 0; --tw-translate-y: 0; background-color: #f0f0f0; border-color: rgba(0, 0, 0, 0.08); border-image: initial; border-style: solid; border-width: 0px 0px 0px 2px; box-sizing: border-box; color: rgba(0, 0, 0, 0.55); font-family: Menlo, sans-serif; font-size: 14px; line-height: 1.25rem; margin: 1rem 0px; overflow-wrap: break-word; overflow: visible; padding-left: 1rem; text-wrap-mode: wrap;&quot;&gt;&lt;span style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-text-opacity: 1; --tw-translate-x: 0; --tw-translate-y: 0; border: 0px solid rgba(0, 0, 0, 0.08); box-sizing: border-box; color: #262626; font-weight: 700; overflow-wrap: break-word;&quot;&gt;Input:&lt;/span&gt; nums = [0,0,1,0]
&lt;span style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-text-opacity: 1; --tw-translate-x: 0; --tw-translate-y: 0; border: 0px solid rgba(0, 0, 0, 0.08); box-sizing: border-box; color: #262626; font-weight: 700; overflow-wrap: break-word;&quot;&gt;Output:&lt;/span&gt; [2,4]
&lt;span style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-text-opacity: 1; --tw-translate-x: 0; --tw-translate-y: 0; border: 0px solid rgba(0, 0, 0, 0.08); box-sizing: border-box; color: #262626; font-weight: 700; overflow-wrap: break-word;&quot;&gt;Explanation:&lt;/span&gt; Division at index
- 0: nums&lt;span style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-translate-x: 0; --tw-translate-y: 0; border: 0px solid rgba(0, 0, 0, 0.08); bottom: -0.25em; box-sizing: border-box; font-size: 10.5px; line-height: 0; overflow-wrap: break-word; position: relative; vertical-align: initial;&quot;&gt;left&lt;/span&gt; is []. nums&lt;span style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-translate-x: 0; --tw-translate-y: 0; border: 0px solid rgba(0, 0, 0, 0.08); bottom: -0.25em; box-sizing: border-box; font-size: 10.5px; line-height: 0; overflow-wrap: break-word; position: relative; vertical-align: initial;&quot;&gt;right&lt;/span&gt; is [0,0,&lt;u style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-translate-x: 0; --tw-translate-y: 0; border: 0px solid rgba(0, 0, 0, 0.08); box-sizing: border-box; overflow-wrap: break-word;&quot;&gt;&lt;span style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-text-opacity: 1; --tw-translate-x: 0; --tw-translate-y: 0; border: 0px solid rgba(0, 0, 0, 0.08); box-sizing: border-box; color: #262626; font-weight: 700; overflow-wrap: break-word;&quot;&gt;1&lt;/span&gt;&lt;/u&gt;,0]. The score is 0 + 1 = 1.
- 1: nums&lt;span style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-translate-x: 0; --tw-translate-y: 0; border: 0px solid rgba(0, 0, 0, 0.08); bottom: -0.25em; box-sizing: border-box; font-size: 10.5px; line-height: 0; overflow-wrap: break-word; position: relative; vertical-align: initial;&quot;&gt;left&lt;/span&gt; is [&lt;u style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-translate-x: 0; --tw-translate-y: 0; border: 0px solid rgba(0, 0, 0, 0.08); box-sizing: border-box; overflow-wrap: break-word;&quot;&gt;&lt;span style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-text-opacity: 1; --tw-translate-x: 0; --tw-translate-y: 0; border: 0px solid rgba(0, 0, 0, 0.08); box-sizing: border-box; color: #262626; font-weight: 700; overflow-wrap: break-word;&quot;&gt;0&lt;/span&gt;&lt;/u&gt;]. nums&lt;span style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-translate-x: 0; --tw-translate-y: 0; border: 0px solid rgba(0, 0, 0, 0.08); bottom: -0.25em; box-sizing: border-box; font-size: 10.5px; line-height: 0; overflow-wrap: break-word; position: relative; vertical-align: initial;&quot;&gt;right&lt;/span&gt; is [0,&lt;u style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-translate-x: 0; --tw-translate-y: 0; border: 0px solid rgba(0, 0, 0, 0.08); box-sizing: border-box; overflow-wrap: break-word;&quot;&gt;&lt;span style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-text-opacity: 1; --tw-translate-x: 0; --tw-translate-y: 0; border: 0px solid rgba(0, 0, 0, 0.08); box-sizing: border-box; color: #262626; font-weight: 700; overflow-wrap: break-word;&quot;&gt;1&lt;/span&gt;&lt;/u&gt;,0]. The score is 1 + 1 = 2.
- 2: nums&lt;span style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-translate-x: 0; --tw-translate-y: 0; border: 0px solid rgba(0, 0, 0, 0.08); bottom: -0.25em; box-sizing: border-box; font-size: 10.5px; line-height: 0; overflow-wrap: break-word; position: relative; vertical-align: initial;&quot;&gt;left&lt;/span&gt; is [&lt;u style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-translate-x: 0; --tw-translate-y: 0; border: 0px solid rgba(0, 0, 0, 0.08); box-sizing: border-box; overflow-wrap: break-word;&quot;&gt;&lt;span style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-text-opacity: 1; --tw-translate-x: 0; --tw-translate-y: 0; border: 0px solid rgba(0, 0, 0, 0.08); box-sizing: border-box; color: #262626; font-weight: 700; overflow-wrap: break-word;&quot;&gt;0&lt;/span&gt;&lt;/u&gt;,&lt;u style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-translate-x: 0; --tw-translate-y: 0; border: 0px solid rgba(0, 0, 0, 0.08); box-sizing: border-box; overflow-wrap: break-word;&quot;&gt;&lt;span style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-text-opacity: 1; --tw-translate-x: 0; --tw-translate-y: 0; border: 0px solid rgba(0, 0, 0, 0.08); box-sizing: border-box; color: #262626; font-weight: 700; overflow-wrap: break-word;&quot;&gt;0&lt;/span&gt;&lt;/u&gt;]. nums&lt;span style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-translate-x: 0; --tw-translate-y: 0; border: 0px solid rgba(0, 0, 0, 0.08); bottom: -0.25em; box-sizing: border-box; font-size: 10.5px; line-height: 0; overflow-wrap: break-word; position: relative; vertical-align: initial;&quot;&gt;right&lt;/span&gt; is [&lt;u style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-translate-x: 0; --tw-translate-y: 0; border: 0px solid rgba(0, 0, 0, 0.08); box-sizing: border-box; overflow-wrap: break-word;&quot;&gt;&lt;span style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-text-opacity: 1; --tw-translate-x: 0; --tw-translate-y: 0; border: 0px solid rgba(0, 0, 0, 0.08); box-sizing: border-box; color: #262626; font-weight: 700; overflow-wrap: break-word;&quot;&gt;1&lt;/span&gt;&lt;/u&gt;,0]. The score is 2 + 1 = 3.
- 3: nums&lt;span style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-translate-x: 0; --tw-translate-y: 0; border: 0px solid rgba(0, 0, 0, 0.08); bottom: -0.25em; box-sizing: border-box; font-size: 10.5px; line-height: 0; overflow-wrap: break-word; position: relative; vertical-align: initial;&quot;&gt;left&lt;/span&gt; is [&lt;u style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-translate-x: 0; --tw-translate-y: 0; border: 0px solid rgba(0, 0, 0, 0.08); box-sizing: border-box; overflow-wrap: break-word;&quot;&gt;&lt;span style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-text-opacity: 1; --tw-translate-x: 0; --tw-translate-y: 0; border: 0px solid rgba(0, 0, 0, 0.08); box-sizing: border-box; color: #262626; font-weight: 700; overflow-wrap: break-word;&quot;&gt;0&lt;/span&gt;&lt;/u&gt;,&lt;u style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-translate-x: 0; --tw-translate-y: 0; border: 0px solid rgba(0, 0, 0, 0.08); box-sizing: border-box; overflow-wrap: break-word;&quot;&gt;&lt;span style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-text-opacity: 1; --tw-translate-x: 0; --tw-translate-y: 0; border: 0px solid rgba(0, 0, 0, 0.08); box-sizing: border-box; color: #262626; font-weight: 700; overflow-wrap: break-word;&quot;&gt;0&lt;/span&gt;&lt;/u&gt;,1]. nums&lt;span style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-translate-x: 0; --tw-translate-y: 0; border: 0px solid rgba(0, 0, 0, 0.08); bottom: -0.25em; box-sizing: border-box; font-size: 10.5px; line-height: 0; overflow-wrap: break-word; position: relative; vertical-align: initial;&quot;&gt;right&lt;/span&gt; is [0]. The score is 2 + 0 = 2.
- 4: nums&lt;span style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-translate-x: 0; --tw-translate-y: 0; border: 0px solid rgba(0, 0, 0, 0.08); bottom: -0.25em; box-sizing: border-box; font-size: 10.5px; line-height: 0; overflow-wrap: break-word; position: relative; vertical-align: initial;&quot;&gt;left&lt;/span&gt; is [&lt;u style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-translate-x: 0; --tw-translate-y: 0; border: 0px solid rgba(0, 0, 0, 0.08); box-sizing: border-box; overflow-wrap: break-word;&quot;&gt;&lt;span style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-text-opacity: 1; --tw-translate-x: 0; --tw-translate-y: 0; border: 0px solid rgba(0, 0, 0, 0.08); box-sizing: border-box; color: #262626; font-weight: 700; overflow-wrap: break-word;&quot;&gt;0&lt;/span&gt;&lt;/u&gt;,&lt;u style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-translate-x: 0; --tw-translate-y: 0; border: 0px solid rgba(0, 0, 0, 0.08); box-sizing: border-box; overflow-wrap: break-word;&quot;&gt;&lt;span style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-text-opacity: 1; --tw-translate-x: 0; --tw-translate-y: 0; border: 0px solid rgba(0, 0, 0, 0.08); box-sizing: border-box; color: #262626; font-weight: 700; overflow-wrap: break-word;&quot;&gt;0&lt;/span&gt;&lt;/u&gt;,1,&lt;u style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-translate-x: 0; --tw-translate-y: 0; border: 0px solid rgba(0, 0, 0, 0.08); box-sizing: border-box; overflow-wrap: break-word;&quot;&gt;&lt;span style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-text-opacity: 1; --tw-translate-x: 0; --tw-translate-y: 0; border: 0px solid rgba(0, 0, 0, 0.08); box-sizing: border-box; color: #262626; font-weight: 700; overflow-wrap: break-word;&quot;&gt;0&lt;/span&gt;&lt;/u&gt;]. nums&lt;span style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-translate-x: 0; --tw-translate-y: 0; border: 0px solid rgba(0, 0, 0, 0.08); bottom: -0.25em; box-sizing: border-box; font-size: 10.5px; line-height: 0; overflow-wrap: break-word; position: relative; vertical-align: initial;&quot;&gt;right&lt;/span&gt; is []. The score is 3 + 0 = 3.
Indices 2 and 4 both have the highest possible division score 3.
Note the answer [4,2] would also be accepted.&lt;/pre&gt;&lt;pre style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-translate-x: 0; --tw-translate-y: 0; background-color: #f0f0f0; border-color: rgba(0, 0, 0, 0.08); border-image: initial; border-style: solid; border-width: 0px 0px 0px 2px; box-sizing: border-box; color: rgba(0, 0, 0, 0.55); font-family: Menlo, sans-serif; font-size: 14px; line-height: 1.25rem; margin: 1rem 0px; overflow-wrap: break-word; overflow: visible; padding-left: 1rem; text-wrap-mode: wrap;&quot;&gt;&lt;span style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-text-opacity: 1; --tw-translate-x: 0; --tw-translate-y: 0; border: 0px solid rgba(0, 0, 0, 0.08); box-sizing: border-box; color: #262626; font-weight: 700; overflow-wrap: break-word;&quot;&gt;Input:&lt;/span&gt; nums = [0,0,0]
&lt;span style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-text-opacity: 1; --tw-translate-x: 0; --tw-translate-y: 0; border: 0px solid rgba(0, 0, 0, 0.08); box-sizing: border-box; color: #262626; font-weight: 700; overflow-wrap: break-word;&quot;&gt;Output:&lt;/span&gt; [3]
&lt;span style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-text-opacity: 1; --tw-translate-x: 0; --tw-translate-y: 0; border: 0px solid rgba(0, 0, 0, 0.08); box-sizing: border-box; color: #262626; font-weight: 700; overflow-wrap: break-word;&quot;&gt;Explanation:&lt;/span&gt; Division at index
- 0: nums&lt;span style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-translate-x: 0; --tw-translate-y: 0; border: 0px solid rgba(0, 0, 0, 0.08); bottom: -0.25em; box-sizing: border-box; font-size: 10.5px; line-height: 0; overflow-wrap: break-word; position: relative; vertical-align: initial;&quot;&gt;left&lt;/span&gt; is []. nums&lt;span style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-translate-x: 0; --tw-translate-y: 0; border: 0px solid rgba(0, 0, 0, 0.08); bottom: -0.25em; box-sizing: border-box; font-size: 10.5px; line-height: 0; overflow-wrap: break-word; position: relative; vertical-align: initial;&quot;&gt;right&lt;/span&gt; is [0,0,0]. The score is 0 + 0 = 0.
- 1: nums&lt;span style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-translate-x: 0; --tw-translate-y: 0; border: 0px solid rgba(0, 0, 0, 0.08); bottom: -0.25em; box-sizing: border-box; font-size: 10.5px; line-height: 0; overflow-wrap: break-word; position: relative; vertical-align: initial;&quot;&gt;left&lt;/span&gt; is [&lt;u style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-translate-x: 0; --tw-translate-y: 0; border: 0px solid rgba(0, 0, 0, 0.08); box-sizing: border-box; overflow-wrap: break-word;&quot;&gt;&lt;span style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-text-opacity: 1; --tw-translate-x: 0; --tw-translate-y: 0; border: 0px solid rgba(0, 0, 0, 0.08); box-sizing: border-box; color: #262626; font-weight: 700; overflow-wrap: break-word;&quot;&gt;0&lt;/span&gt;&lt;/u&gt;]. nums&lt;span style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-translate-x: 0; --tw-translate-y: 0; border: 0px solid rgba(0, 0, 0, 0.08); bottom: -0.25em; box-sizing: border-box; font-size: 10.5px; line-height: 0; overflow-wrap: break-word; position: relative; vertical-align: initial;&quot;&gt;right&lt;/span&gt; is [0,0]. The score is 1 + 0 = 1.
- 2: nums&lt;span style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-translate-x: 0; --tw-translate-y: 0; border: 0px solid rgba(0, 0, 0, 0.08); bottom: -0.25em; box-sizing: border-box; font-size: 10.5px; line-height: 0; overflow-wrap: break-word; position: relative; vertical-align: initial;&quot;&gt;left&lt;/span&gt; is [&lt;u style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-translate-x: 0; --tw-translate-y: 0; border: 0px solid rgba(0, 0, 0, 0.08); box-sizing: border-box; overflow-wrap: break-word;&quot;&gt;&lt;span style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-text-opacity: 1; --tw-translate-x: 0; --tw-translate-y: 0; border: 0px solid rgba(0, 0, 0, 0.08); box-sizing: border-box; color: #262626; font-weight: 700; overflow-wrap: break-word;&quot;&gt;0&lt;/span&gt;&lt;/u&gt;,&lt;u style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-translate-x: 0; --tw-translate-y: 0; border: 0px solid rgba(0, 0, 0, 0.08); box-sizing: border-box; overflow-wrap: break-word;&quot;&gt;&lt;span style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-text-opacity: 1; --tw-translate-x: 0; --tw-translate-y: 0; border: 0px solid rgba(0, 0, 0, 0.08); box-sizing: border-box; color: #262626; font-weight: 700; overflow-wrap: break-word;&quot;&gt;0&lt;/span&gt;&lt;/u&gt;]. nums&lt;span style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-translate-x: 0; --tw-translate-y: 0; border: 0px solid rgba(0, 0, 0, 0.08); bottom: -0.25em; box-sizing: border-box; font-size: 10.5px; line-height: 0; overflow-wrap: break-word; position: relative; vertical-align: initial;&quot;&gt;right&lt;/span&gt; is [0]. The score is 2 + 0 = 2.
- 3: nums&lt;span style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-translate-x: 0; --tw-translate-y: 0; border: 0px solid rgba(0, 0, 0, 0.08); bottom: -0.25em; box-sizing: border-box; font-size: 10.5px; line-height: 0; overflow-wrap: break-word; position: relative; vertical-align: initial;&quot;&gt;left&lt;/span&gt; is [&lt;u style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-translate-x: 0; --tw-translate-y: 0; border: 0px solid rgba(0, 0, 0, 0.08); box-sizing: border-box; overflow-wrap: break-word;&quot;&gt;&lt;span style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-text-opacity: 1; --tw-translate-x: 0; --tw-translate-y: 0; border: 0px solid rgba(0, 0, 0, 0.08); box-sizing: border-box; color: #262626; font-weight: 700; overflow-wrap: break-word;&quot;&gt;0&lt;/span&gt;&lt;/u&gt;,&lt;u style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-translate-x: 0; --tw-translate-y: 0; border: 0px solid rgba(0, 0, 0, 0.08); box-sizing: border-box; overflow-wrap: break-word;&quot;&gt;&lt;span style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-text-opacity: 1; --tw-translate-x: 0; --tw-translate-y: 0; border: 0px solid rgba(0, 0, 0, 0.08); box-sizing: border-box; color: #262626; font-weight: 700; overflow-wrap: break-word;&quot;&gt;0&lt;/span&gt;&lt;/u&gt;,&lt;u style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-translate-x: 0; --tw-translate-y: 0; border: 0px solid rgba(0, 0, 0, 0.08); box-sizing: border-box; overflow-wrap: break-word;&quot;&gt;&lt;span style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-text-opacity: 1; --tw-translate-x: 0; --tw-translate-y: 0; border: 0px solid rgba(0, 0, 0, 0.08); box-sizing: border-box; color: #262626; font-weight: 700; overflow-wrap: break-word;&quot;&gt;0&lt;/span&gt;&lt;/u&gt;]. nums&lt;span style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-translate-x: 0; --tw-translate-y: 0; border: 0px solid rgba(0, 0, 0, 0.08); bottom: -0.25em; box-sizing: border-box; font-size: 10.5px; line-height: 0; overflow-wrap: break-word; position: relative; vertical-align: initial;&quot;&gt;right&lt;/span&gt; is []. The score is 3 + 0 = 3.
Only index 3 has the highest possible division score 3.&lt;/pre&gt;&lt;pre style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-translate-x: 0; --tw-translate-y: 0; background-color: #f0f0f0; border-color: rgba(0, 0, 0, 0.08); border-image: initial; border-style: solid; border-width: 0px 0px 0px 2px; box-sizing: border-box; color: rgba(0, 0, 0, 0.55); font-family: Menlo, sans-serif; font-size: 14px; line-height: 1.25rem; margin: 1rem 0px; overflow-wrap: break-word; overflow: visible; padding-left: 1rem; text-wrap-mode: wrap;&quot;&gt;&lt;span style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-text-opacity: 1; --tw-translate-x: 0; --tw-translate-y: 0; border: 0px solid rgba(0, 0, 0, 0.08); box-sizing: border-box; color: #262626; font-weight: 700; overflow-wrap: break-word;&quot;&gt;Input:&lt;/span&gt; nums = [1,1]
&lt;span style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-text-opacity: 1; --tw-translate-x: 0; --tw-translate-y: 0; border: 0px solid rgba(0, 0, 0, 0.08); box-sizing: border-box; color: #262626; font-weight: 700; overflow-wrap: break-word;&quot;&gt;Output:&lt;/span&gt; [0]
&lt;span style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-text-opacity: 1; --tw-translate-x: 0; --tw-translate-y: 0; border: 0px solid rgba(0, 0, 0, 0.08); box-sizing: border-box; color: #262626; font-weight: 700; overflow-wrap: break-word;&quot;&gt;Explanation:&lt;/span&gt; Division at index
- 0: nums&lt;span style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-translate-x: 0; --tw-translate-y: 0; border: 0px solid rgba(0, 0, 0, 0.08); bottom: -0.25em; box-sizing: border-box; font-size: 10.5px; line-height: 0; overflow-wrap: break-word; position: relative; vertical-align: initial;&quot;&gt;left&lt;/span&gt; is []. nums&lt;span style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-translate-x: 0; --tw-translate-y: 0; border: 0px solid rgba(0, 0, 0, 0.08); bottom: -0.25em; box-sizing: border-box; font-size: 10.5px; line-height: 0; overflow-wrap: break-word; position: relative; vertical-align: initial;&quot;&gt;right&lt;/span&gt; is [&lt;u style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-translate-x: 0; --tw-translate-y: 0; border: 0px solid rgba(0, 0, 0, 0.08); box-sizing: border-box; overflow-wrap: break-word;&quot;&gt;&lt;span style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-text-opacity: 1; --tw-translate-x: 0; --tw-translate-y: 0; border: 0px solid rgba(0, 0, 0, 0.08); box-sizing: border-box; color: #262626; font-weight: 700; overflow-wrap: break-word;&quot;&gt;1&lt;/span&gt;&lt;/u&gt;,&lt;u style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-translate-x: 0; --tw-translate-y: 0; border: 0px solid rgba(0, 0, 0, 0.08); box-sizing: border-box; overflow-wrap: break-word;&quot;&gt;&lt;span style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-text-opacity: 1; --tw-translate-x: 0; --tw-translate-y: 0; border: 0px solid rgba(0, 0, 0, 0.08); box-sizing: border-box; color: #262626; font-weight: 700; overflow-wrap: break-word;&quot;&gt;1&lt;/span&gt;&lt;/u&gt;]. The score is 0 + 2 = 2.
- 1: nums&lt;span style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-translate-x: 0; --tw-translate-y: 0; border: 0px solid rgba(0, 0, 0, 0.08); bottom: -0.25em; box-sizing: border-box; font-size: 10.5px; line-height: 0; overflow-wrap: break-word; position: relative; vertical-align: initial;&quot;&gt;left&lt;/span&gt; is [1]. nums&lt;span style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-translate-x: 0; --tw-translate-y: 0; border: 0px solid rgba(0, 0, 0, 0.08); bottom: -0.25em; box-sizing: border-box; font-size: 10.5px; line-height: 0; overflow-wrap: break-word; position: relative; vertical-align: initial;&quot;&gt;right&lt;/span&gt; is [&lt;u style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-translate-x: 0; --tw-translate-y: 0; border: 0px solid rgba(0, 0, 0, 0.08); box-sizing: border-box; overflow-wrap: break-word;&quot;&gt;&lt;span style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-text-opacity: 1; --tw-translate-x: 0; --tw-translate-y: 0; border: 0px solid rgba(0, 0, 0, 0.08); box-sizing: border-box; color: #262626; font-weight: 700; overflow-wrap: break-word;&quot;&gt;1&lt;/span&gt;&lt;/u&gt;]. The score is 0 + 1 = 1.
- 2: nums&lt;span style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-translate-x: 0; --tw-translate-y: 0; border: 0px solid rgba(0, 0, 0, 0.08); bottom: -0.25em; box-sizing: border-box; font-size: 10.5px; line-height: 0; overflow-wrap: break-word; position: relative; vertical-align: initial;&quot;&gt;left&lt;/span&gt; is [1,1]. nums&lt;span style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-translate-x: 0; --tw-translate-y: 0; border: 0px solid rgba(0, 0, 0, 0.08); bottom: -0.25em; box-sizing: border-box; font-size: 10.5px; line-height: 0; overflow-wrap: break-word; position: relative; vertical-align: initial;&quot;&gt;right&lt;/span&gt; is []. The score is 0 + 0 = 0.
Only index 0 has the highest possible division score 2.&lt;/pre&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;Approach:&lt;/b&gt; The problem is simple, we iterate through the the array we need to maintain number of 0s at the left and number of 1s on the right. Now how we can quickly calculate it?&lt;/p&gt;&lt;p&gt;The number of 1s on the right will be the sum of array minus the number of 1s on the left. To calculate the number of 1s quickly we can maintain &lt;i&gt;prefix array sum&lt;/i&gt;. Now you can see the calculation:&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;Number of 0s on the left at index i = i&amp;nbsp; - prefixSum[i - 1]&amp;nbsp;&lt;/li&gt;&lt;ul&gt;&lt;li&gt;prefixSum[i - 1] will tell the number of 1s at the left&lt;/li&gt;&lt;li&gt;If we subtract the prefixSum[i - 1] from i, it will tell the number of 0s on the left&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;Number of 1s on the right at index i = SUM(nums) - prefixSum[i - 1]&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Now we just need to calculate the maximum of the sum of above two values at each index i and return all the i&#39;s which has the maximum sum.&lt;/div&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;Implementation in C#:&lt;/b&gt;&lt;/p&gt;&lt;div style=&quot;background-color: white; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 13px; line-height: 18px; white-space: pre;&quot;&gt;&lt;div&gt;&lt;span style=&quot;color: blue;&quot;&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;/span&gt;public&lt;/span&gt; &lt;span style=&quot;color: #267f99;&quot;&gt;IList&lt;/span&gt;&amp;lt;&lt;span style=&quot;color: blue;&quot;&gt;int&lt;/span&gt;&amp;gt; &lt;span style=&quot;color: #795e26;&quot;&gt;MaxScoreIndices&lt;/span&gt;(&lt;span style=&quot;color: blue;&quot;&gt;int&lt;/span&gt;[] &lt;span style=&quot;color: #001080;&quot;&gt;nums&lt;/span&gt;)&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; {&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #267f99;&quot;&gt;IList&lt;/span&gt;&amp;lt;&lt;span style=&quot;color: blue;&quot;&gt;int&lt;/span&gt;&amp;gt; &lt;span style=&quot;color: #001080;&quot;&gt;result&lt;/span&gt; = &lt;span style=&quot;color: blue;&quot;&gt;new&lt;/span&gt; &lt;span style=&quot;color: #267f99;&quot;&gt;List&lt;/span&gt;&amp;lt;&lt;span style=&quot;color: blue;&quot;&gt;int&lt;/span&gt;&amp;gt;();&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: blue;&quot;&gt;int&lt;/span&gt; &lt;span style=&quot;color: #001080;&quot;&gt;length&lt;/span&gt; = &lt;span style=&quot;color: #001080;&quot;&gt;nums&lt;/span&gt;?.&lt;span style=&quot;color: #001080;&quot;&gt;Length&lt;/span&gt; ?? &lt;span style=&quot;color: #098658;&quot;&gt;0&lt;/span&gt;;&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #af00db;&quot;&gt;if&lt;/span&gt; (&lt;span style=&quot;color: #001080;&quot;&gt;length&lt;/span&gt; == &lt;span style=&quot;color: #098658;&quot;&gt;0&lt;/span&gt;)&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; {&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #af00db;&quot;&gt;return&lt;/span&gt; &lt;span style=&quot;color: #001080;&quot;&gt;result&lt;/span&gt;;&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: blue;&quot;&gt;int&lt;/span&gt; &lt;span style=&quot;color: #001080;&quot;&gt;arrSum&lt;/span&gt; = &lt;span style=&quot;color: #001080;&quot;&gt;nums&lt;/span&gt;[&lt;span style=&quot;color: #098658;&quot;&gt;0&lt;/span&gt;];&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #af00db;&quot;&gt;for&lt;/span&gt; (&lt;span style=&quot;color: blue;&quot;&gt;int&lt;/span&gt; &lt;span style=&quot;color: #001080;&quot;&gt;i&lt;/span&gt; = &lt;span style=&quot;color: #098658;&quot;&gt;1&lt;/span&gt;; &lt;span style=&quot;color: #001080;&quot;&gt;i&lt;/span&gt; &amp;lt; &lt;span style=&quot;color: #001080;&quot;&gt;length&lt;/span&gt;; ++&lt;span style=&quot;color: #001080;&quot;&gt;i&lt;/span&gt;)&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; {&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #001080;&quot;&gt;arrSum&lt;/span&gt; += &lt;span style=&quot;color: #001080;&quot;&gt;nums&lt;/span&gt;[&lt;span style=&quot;color: #001080;&quot;&gt;i&lt;/span&gt;];&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #001080;&quot;&gt;nums&lt;/span&gt;[&lt;span style=&quot;color: #001080;&quot;&gt;i&lt;/span&gt;] += &lt;span style=&quot;color: #001080;&quot;&gt;nums&lt;/span&gt;[&lt;span style=&quot;color: #001080;&quot;&gt;i&lt;/span&gt; - &lt;span style=&quot;color: #098658;&quot;&gt;1&lt;/span&gt;];&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: blue;&quot;&gt;int&lt;/span&gt; &lt;span style=&quot;color: #001080;&quot;&gt;maxScore&lt;/span&gt; = &lt;span style=&quot;color: #001080;&quot;&gt;arrSum&lt;/span&gt;;&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #001080;&quot;&gt;result&lt;/span&gt;.&lt;span style=&quot;color: #795e26;&quot;&gt;Add&lt;/span&gt;(&lt;span style=&quot;color: #098658;&quot;&gt;0&lt;/span&gt;);&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #af00db;&quot;&gt;for&lt;/span&gt; (&lt;span style=&quot;color: blue;&quot;&gt;int&lt;/span&gt; &lt;span style=&quot;color: #001080;&quot;&gt;i&lt;/span&gt; = &lt;span style=&quot;color: #098658;&quot;&gt;1&lt;/span&gt;; &lt;span style=&quot;color: #001080;&quot;&gt;i&lt;/span&gt; &amp;lt; &lt;span style=&quot;color: #001080;&quot;&gt;length&lt;/span&gt;; ++&lt;span style=&quot;color: #001080;&quot;&gt;i&lt;/span&gt;)&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; {&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: blue;&quot;&gt;int&lt;/span&gt; &lt;span style=&quot;color: #001080;&quot;&gt;currScore&lt;/span&gt; = &lt;span style=&quot;color: #001080;&quot;&gt;i&lt;/span&gt; - &lt;span style=&quot;color: #001080;&quot;&gt;nums&lt;/span&gt;[&lt;span style=&quot;color: #001080;&quot;&gt;i&lt;/span&gt; - &lt;span style=&quot;color: #098658;&quot;&gt;1&lt;/span&gt;];&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #001080;&quot;&gt;currScore&lt;/span&gt; += (&lt;span style=&quot;color: #001080;&quot;&gt;arrSum&lt;/span&gt; - &lt;span style=&quot;color: #001080;&quot;&gt;nums&lt;/span&gt;[&lt;span style=&quot;color: #001080;&quot;&gt;i&lt;/span&gt; - &lt;span style=&quot;color: #098658;&quot;&gt;1&lt;/span&gt;]);&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #af00db;&quot;&gt;if&lt;/span&gt; (&lt;span style=&quot;color: #001080;&quot;&gt;currScore&lt;/span&gt; &amp;gt; &lt;span style=&quot;color: #001080;&quot;&gt;maxScore&lt;/span&gt;)&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; {&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #001080;&quot;&gt;maxScore&lt;/span&gt; = &lt;span style=&quot;color: #001080;&quot;&gt;currScore&lt;/span&gt;;&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #001080;&quot;&gt;result&lt;/span&gt; = &lt;span style=&quot;color: #267f99;&quot;&gt;new&lt;/span&gt; &lt;span style=&quot;color: #795e26;&quot;&gt;List&lt;/span&gt;&amp;lt;&lt;span style=&quot;color: #267f99;&quot;&gt;int&lt;/span&gt;&amp;gt;();&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #001080;&quot;&gt;result&lt;/span&gt;.&lt;span style=&quot;color: #795e26;&quot;&gt;Add&lt;/span&gt;(&lt;span style=&quot;color: #001080;&quot;&gt;i&lt;/span&gt;);&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #af00db;&quot;&gt;else&lt;/span&gt; &lt;span style=&quot;color: #af00db;&quot;&gt;if&lt;/span&gt; (&lt;span style=&quot;color: #001080;&quot;&gt;currScore&lt;/span&gt; == &lt;span style=&quot;color: #001080;&quot;&gt;maxScore&lt;/span&gt;)&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; {&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #001080;&quot;&gt;result&lt;/span&gt;.&lt;span style=&quot;color: #795e26;&quot;&gt;Add&lt;/span&gt;(&lt;span style=&quot;color: #001080;&quot;&gt;i&lt;/span&gt;);&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: blue;&quot;&gt;int&lt;/span&gt; &lt;span style=&quot;color: #001080;&quot;&gt;lastScore&lt;/span&gt; = &lt;span style=&quot;color: #001080;&quot;&gt;length&lt;/span&gt; - &lt;span style=&quot;color: #001080;&quot;&gt;arrSum&lt;/span&gt;;&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #af00db;&quot;&gt;if&lt;/span&gt; (&lt;span style=&quot;color: #001080;&quot;&gt;lastScore&lt;/span&gt; &amp;gt; &lt;span style=&quot;color: #001080;&quot;&gt;maxScore&lt;/span&gt;)&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; {&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #001080;&quot;&gt;maxScore&lt;/span&gt; = &lt;span style=&quot;color: #001080;&quot;&gt;lastScore&lt;/span&gt;;&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #001080;&quot;&gt;result&lt;/span&gt; = &lt;span style=&quot;color: #267f99;&quot;&gt;new&lt;/span&gt; &lt;span style=&quot;color: #795e26;&quot;&gt;List&lt;/span&gt;&amp;lt;&lt;span style=&quot;color: #267f99;&quot;&gt;int&lt;/span&gt;&amp;gt;();&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #001080;&quot;&gt;result&lt;/span&gt;.&lt;span style=&quot;color: #795e26;&quot;&gt;Add&lt;/span&gt;(&lt;span style=&quot;color: #001080;&quot;&gt;length&lt;/span&gt;);&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #af00db;&quot;&gt;else&lt;/span&gt; &lt;span style=&quot;color: #af00db;&quot;&gt;if&lt;/span&gt; (&lt;span style=&quot;color: #001080;&quot;&gt;lastScore&lt;/span&gt; == &lt;span style=&quot;color: #001080;&quot;&gt;maxScore&lt;/span&gt;)&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; {&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #001080;&quot;&gt;result&lt;/span&gt;.&lt;span style=&quot;color: #795e26;&quot;&gt;Add&lt;/span&gt;(&lt;span style=&quot;color: #001080;&quot;&gt;length&lt;/span&gt;);&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #af00db;&quot;&gt;return&lt;/span&gt; &lt;span style=&quot;color: #001080;&quot;&gt;result&lt;/span&gt;;&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; }&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;Complexity:&lt;/b&gt; O(n)&lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='http://algods-cracker.blogspot.com/feeds/7452380631048686014/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://algods-cracker.blogspot.com/2026/01/leetcode-all-divisions-with-highest.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7496974970329409400/posts/default/7452380631048686014'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7496974970329409400/posts/default/7452380631048686014'/><link rel='alternate' type='text/html' href='http://algods-cracker.blogspot.com/2026/01/leetcode-all-divisions-with-highest.html' title='[LeetCode] All Divisions With the Highest Score of a Binary Array'/><author><name>Nishant Saxena</name><uri>http://www.blogger.com/profile/17860524009847591950</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjOdjS62BAEI1iMG_zd6lew4qyFGpfJhWHp0AJWQhiJvxQpSGg0AFZ5euJG7tK0D-EGQFno32hF-i1x4E2A49re_8-b9r0QHwXQ-9X_EvlAcekIjUYMaA1v6dWzDqzkBg/s220/2d230a1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7496974970329409400.post-5388096620674630578</id><published>2026-01-25T20:05:00.003+05:30</published><updated>2026-01-25T20:05:16.844+05:30</updated><category scheme="http://www.blogger.com/atom/ns#" term="LeetCode"/><title type='text'>[LeetCode] Minimum Cost of Buying Candies With Discount</title><content type='html'>&lt;p&gt;&lt;b&gt;Problem:&lt;/b&gt; A shop is selling candies at a discount. For &lt;i&gt;every two&lt;/i&gt; candies sold, the shop gives a &lt;i&gt;third &lt;/i&gt;candy for &lt;i&gt;free&lt;/i&gt;.&lt;/p&gt;&lt;p&gt;The customer can choose any candy to take away for free as long as the cost of the chosen candy is less than or equal to the minimum cost of the two candies bought.&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;For example, if there are 4 candies with costs 1, 2, 3, and 4, and the customer buys candies with costs 2 and 3, they can take the candy with cost 1 for free, but not the candy with cost 4.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;Given a 0-indexed integer array cost, where cost[i] denotes the cost of the ith candy, return the minimum cost of buying all the candies.&lt;/p&gt;&lt;p&gt;Example:&lt;/p&gt;&lt;pre style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-translate-x: 0; --tw-translate-y: 0; background-color: #f0f0f0; border-color: rgba(0, 0, 0, 0.08); border-image: initial; border-style: solid; border-width: 0px 0px 0px 2px; box-sizing: border-box; color: rgba(0, 0, 0, 0.55); font-family: Menlo, sans-serif; font-size: 14px; line-height: 1.25rem; margin: 1rem 0px; overflow-wrap: break-word; overflow: visible; padding-left: 1rem; text-wrap-mode: wrap;&quot;&gt;&lt;span style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-text-opacity: 1; --tw-translate-x: 0; --tw-translate-y: 0; border: 0px solid rgba(0, 0, 0, 0.08); box-sizing: border-box; color: #262626; font-weight: 700; overflow-wrap: break-word;&quot;&gt;Input:&lt;/span&gt; cost = [1,2,3]
&lt;span style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-text-opacity: 1; --tw-translate-x: 0; --tw-translate-y: 0; border: 0px solid rgba(0, 0, 0, 0.08); box-sizing: border-box; color: #262626; font-weight: 700; overflow-wrap: break-word;&quot;&gt;Output:&lt;/span&gt; 5
&lt;span style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-text-opacity: 1; --tw-translate-x: 0; --tw-translate-y: 0; border: 0px solid rgba(0, 0, 0, 0.08); box-sizing: border-box; color: #262626; font-weight: 700; overflow-wrap: break-word;&quot;&gt;Explanation:&lt;/span&gt; We buy the candies with costs 2 and 3, and take the candy with cost 1 for free.
The total cost of buying all candies is 2 + 3 = 5. This is the &lt;span style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-text-opacity: 1; --tw-translate-x: 0; --tw-translate-y: 0; border: 0px solid rgba(0, 0, 0, 0.08); box-sizing: border-box; color: #262626; font-weight: 700; overflow-wrap: break-word;&quot;&gt;only&lt;/span&gt; way we can buy the candies.
Note that we cannot buy candies with costs 1 and 3, and then take the candy with cost 2 for free.
The cost of the free candy has to be less than or equal to the minimum cost of the purchased candies.&lt;/pre&gt;&lt;pre style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-translate-x: 0; --tw-translate-y: 0; background-color: #f0f0f0; border-color: rgba(0, 0, 0, 0.08); border-image: initial; border-style: solid; border-width: 0px 0px 0px 2px; box-sizing: border-box; color: rgba(0, 0, 0, 0.55); font-family: Menlo, sans-serif; font-size: 14px; line-height: 1.25rem; margin: 1rem 0px; overflow-wrap: break-word; overflow: visible; padding-left: 1rem; text-wrap-mode: wrap;&quot;&gt;&lt;span style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-text-opacity: 1; --tw-translate-x: 0; --tw-translate-y: 0; border: 0px solid rgba(0, 0, 0, 0.08); box-sizing: border-box; color: #262626; font-weight: 700; overflow-wrap: break-word;&quot;&gt;Input:&lt;/span&gt; cost = [6,5,7,9,2,2]
&lt;span style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-text-opacity: 1; --tw-translate-x: 0; --tw-translate-y: 0; border: 0px solid rgba(0, 0, 0, 0.08); box-sizing: border-box; color: #262626; font-weight: 700; overflow-wrap: break-word;&quot;&gt;Output:&lt;/span&gt; 23
&lt;span style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-text-opacity: 1; --tw-translate-x: 0; --tw-translate-y: 0; border: 0px solid rgba(0, 0, 0, 0.08); box-sizing: border-box; color: #262626; font-weight: 700; overflow-wrap: break-word;&quot;&gt;Explanation:&lt;/span&gt; The way in which we can get the minimum cost is described below:
- Buy candies with costs 9 and 7
- Take the candy with cost 6 for free
- We buy candies with costs 5 and 2
- Take the last remaining candy with cost 2 for free
Hence, the minimum cost to buy all candies is 9 + 7 + 5 + 2 = 23.&lt;/pre&gt;&lt;pre style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-translate-x: 0; --tw-translate-y: 0; background-color: #f0f0f0; border-color: rgba(0, 0, 0, 0.08); border-image: initial; border-style: solid; border-width: 0px 0px 0px 2px; box-sizing: border-box; color: rgba(0, 0, 0, 0.55); font-family: Menlo, sans-serif; font-size: 14px; line-height: 1.25rem; margin: 1rem 0px; overflow-wrap: break-word; overflow: visible; padding-left: 1rem; text-wrap-mode: wrap;&quot;&gt;&lt;span style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-text-opacity: 1; --tw-translate-x: 0; --tw-translate-y: 0; border: 0px solid rgba(0, 0, 0, 0.08); box-sizing: border-box; color: #262626; font-weight: 700; overflow-wrap: break-word;&quot;&gt;Input:&lt;/span&gt; cost = [5,5]
&lt;span style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-text-opacity: 1; --tw-translate-x: 0; --tw-translate-y: 0; border: 0px solid rgba(0, 0, 0, 0.08); box-sizing: border-box; color: #262626; font-weight: 700; overflow-wrap: break-word;&quot;&gt;Output:&lt;/span&gt; 10
&lt;span style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-text-opacity: 1; --tw-translate-x: 0; --tw-translate-y: 0; border: 0px solid rgba(0, 0, 0, 0.08); box-sizing: border-box; color: #262626; font-weight: 700; overflow-wrap: break-word;&quot;&gt;Explanation:&lt;/span&gt; Since there are only 2 candies, we buy both of them. There is not a third candy we can take for free.
Hence, the minimum cost to buy all candies is 5 + 5 = 10.&lt;/pre&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;Approach:&lt;/b&gt; The question is to get the minimum cost possible. Given we can exclude the cost of every third candy, we need to exclude the maximum cost candy possible. Given we can only &lt;i&gt;exclude a candy from the triplet if the cost of other two candies are more or equal to the excluded candy&lt;/i&gt;. That means we can exclude 3rd maximum, 6th maximum, 9th maximum and so on.&lt;/p&gt;&lt;p&gt;Given we need to exclude the maximum cost candy possible given the above condition, what we can do is to sort the array in descending order and then it becomes simple to exclude cost[2], cost[5], cost[8] and so on. Remaining sum of the array is our answer.&lt;/p&gt;&lt;p&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;Implementation in C#:&lt;/b&gt;&lt;/p&gt;&lt;div style=&quot;background-color: white; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 13px; line-height: 18px; white-space: pre;&quot;&gt;&lt;div&gt;&lt;span style=&quot;color: blue;&quot;&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;/span&gt;public&lt;/span&gt; &lt;span style=&quot;color: blue;&quot;&gt;int&lt;/span&gt; &lt;span style=&quot;color: #795e26;&quot;&gt;MinimumCost&lt;/span&gt;(&lt;span style=&quot;color: blue;&quot;&gt;int&lt;/span&gt;[] &lt;span style=&quot;color: #001080;&quot;&gt;cost&lt;/span&gt;)&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; {&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: blue;&quot;&gt;int&lt;/span&gt; &lt;span style=&quot;color: #001080;&quot;&gt;length&lt;/span&gt; = &lt;span style=&quot;color: #001080;&quot;&gt;cost&lt;/span&gt;?.&lt;span style=&quot;color: #001080;&quot;&gt;Length&lt;/span&gt; ?? &lt;span style=&quot;color: #098658;&quot;&gt;0&lt;/span&gt;;&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #af00db;&quot;&gt;if&lt;/span&gt; (&lt;span style=&quot;color: #001080;&quot;&gt;length&lt;/span&gt; == &lt;span style=&quot;color: #098658;&quot;&gt;0&lt;/span&gt;)&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; {&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #af00db;&quot;&gt;return&lt;/span&gt; &lt;span style=&quot;color: #098658;&quot;&gt;0&lt;/span&gt;;&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #001080;&quot;&gt;Array&lt;/span&gt;.&lt;span style=&quot;color: #795e26;&quot;&gt;Sort&lt;/span&gt;(&lt;span style=&quot;color: #001080;&quot;&gt;cost&lt;/span&gt;, (&lt;span style=&quot;color: #001080;&quot;&gt;i&lt;/span&gt;, &lt;span style=&quot;color: #001080;&quot;&gt;j&lt;/span&gt;) =&amp;gt; {&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #af00db;&quot;&gt;return&lt;/span&gt; &lt;span style=&quot;color: #001080;&quot;&gt;j&lt;/span&gt;.&lt;span style=&quot;color: #795e26;&quot;&gt;CompareTo&lt;/span&gt;(&lt;span style=&quot;color: #001080;&quot;&gt;i&lt;/span&gt;);&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; });&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: blue;&quot;&gt;int&lt;/span&gt; &lt;span style=&quot;color: #001080;&quot;&gt;minCost&lt;/span&gt; = &lt;span style=&quot;color: #098658;&quot;&gt;0&lt;/span&gt;;&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #af00db;&quot;&gt;for&lt;/span&gt; (&lt;span style=&quot;color: blue;&quot;&gt;int&lt;/span&gt; &lt;span style=&quot;color: #001080;&quot;&gt;i&lt;/span&gt; = &lt;span style=&quot;color: #098658;&quot;&gt;1&lt;/span&gt;; &lt;span style=&quot;color: #001080;&quot;&gt;i&lt;/span&gt; &amp;lt;= &lt;span style=&quot;color: #001080;&quot;&gt;length&lt;/span&gt;; ++&lt;span style=&quot;color: #001080;&quot;&gt;i&lt;/span&gt;)&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; {&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #af00db;&quot;&gt;if&lt;/span&gt; (&lt;span style=&quot;color: #001080;&quot;&gt;i&lt;/span&gt; % &lt;span style=&quot;color: #098658;&quot;&gt;3&lt;/span&gt; == &lt;span style=&quot;color: #098658;&quot;&gt;0&lt;/span&gt;)&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; {&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #af00db;&quot;&gt;continue&lt;/span&gt;;&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #001080;&quot;&gt;minCost&lt;/span&gt; += &lt;span style=&quot;color: #001080;&quot;&gt;cost&lt;/span&gt;[&lt;span style=&quot;color: #001080;&quot;&gt;i&lt;/span&gt; - &lt;span style=&quot;color: #098658;&quot;&gt;1&lt;/span&gt;];&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #af00db;&quot;&gt;return&lt;/span&gt; &lt;span style=&quot;color: #001080;&quot;&gt;minCost&lt;/span&gt;;&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; }&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;Complexity:&lt;/b&gt; O(nlogn)&lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='http://algods-cracker.blogspot.com/feeds/5388096620674630578/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://algods-cracker.blogspot.com/2026/01/leetcode-minimum-cost-of-buying-candies.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7496974970329409400/posts/default/5388096620674630578'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7496974970329409400/posts/default/5388096620674630578'/><link rel='alternate' type='text/html' href='http://algods-cracker.blogspot.com/2026/01/leetcode-minimum-cost-of-buying-candies.html' title='[LeetCode] Minimum Cost of Buying Candies With Discount'/><author><name>Nishant Saxena</name><uri>http://www.blogger.com/profile/17860524009847591950</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjOdjS62BAEI1iMG_zd6lew4qyFGpfJhWHp0AJWQhiJvxQpSGg0AFZ5euJG7tK0D-EGQFno32hF-i1x4E2A49re_8-b9r0QHwXQ-9X_EvlAcekIjUYMaA1v6dWzDqzkBg/s220/2d230a1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7496974970329409400.post-5571946508482641584</id><published>2026-01-25T19:40:00.003+05:30</published><updated>2026-01-25T19:40:59.455+05:30</updated><category scheme="http://www.blogger.com/atom/ns#" term="LeetCode"/><title type='text'>[LeetCode] Array Partition</title><content type='html'>&lt;p&gt;&lt;b&gt;Problem:&lt;/b&gt;&amp;nbsp;Given an integer array nums of 2n integers, group these integers into n pairs (a1, b1), (a2, b2), ..., (an, bn) such that the sum of min(ai, bi) for all i is maximized. Return the maximized sum.&lt;/p&gt;&lt;p&gt;Example:&lt;/p&gt;&lt;pre style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-translate-x: 0; --tw-translate-y: 0; background-color: #f0f0f0; border-color: rgba(0, 0, 0, 0.08); border-image: initial; border-style: solid; border-width: 0px 0px 0px 2px; box-sizing: border-box; color: rgba(0, 0, 0, 0.55); font-family: Menlo, sans-serif; font-size: 14px; line-height: 1.25rem; margin: 1rem 0px; overflow-wrap: break-word; overflow: visible; padding-left: 1rem; text-wrap-mode: wrap;&quot;&gt;&lt;span style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-text-opacity: 1; --tw-translate-x: 0; --tw-translate-y: 0; border: 0px solid rgba(0, 0, 0, 0.08); box-sizing: border-box; color: #262626; font-weight: 700; overflow-wrap: break-word;&quot;&gt;Input:&lt;/span&gt; nums = [1,4,3,2]
&lt;span style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-text-opacity: 1; --tw-translate-x: 0; --tw-translate-y: 0; border: 0px solid rgba(0, 0, 0, 0.08); box-sizing: border-box; color: #262626; font-weight: 700; overflow-wrap: break-word;&quot;&gt;Output:&lt;/span&gt; 4
&lt;span style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-text-opacity: 1; --tw-translate-x: 0; --tw-translate-y: 0; border: 0px solid rgba(0, 0, 0, 0.08); box-sizing: border-box; color: #262626; font-weight: 700; overflow-wrap: break-word;&quot;&gt;Explanation:&lt;/span&gt; All possible pairings (ignoring the ordering of elements) are:
1. (1, 4), (2, 3) -&amp;gt; min(1, 4) + min(2, 3) = 1 + 2 = 3
2. (1, 3), (2, 4) -&amp;gt; min(1, 3) + min(2, 4) = 1 + 2 = 3
3. (1, 2), (3, 4) -&amp;gt; min(1, 2) + min(3, 4) = 1 + 3 = 4
So the maximum possible sum is 4.&lt;/pre&gt;&lt;pre style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-translate-x: 0; --tw-translate-y: 0; background-color: #f0f0f0; border-color: rgba(0, 0, 0, 0.08); border-image: initial; border-style: solid; border-width: 0px 0px 0px 2px; box-sizing: border-box; color: rgba(0, 0, 0, 0.55); font-family: Menlo, sans-serif; font-size: 14px; line-height: 1.25rem; margin: 1rem 0px; overflow-wrap: break-word; overflow: visible; padding-left: 1rem; text-wrap-mode: wrap;&quot;&gt;&lt;span style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-text-opacity: 1; --tw-translate-x: 0; --tw-translate-y: 0; border: 0px solid rgba(0, 0, 0, 0.08); box-sizing: border-box; color: #262626; font-weight: 700; overflow-wrap: break-word;&quot;&gt;Input:&lt;/span&gt; nums = [6,2,6,5,1,2]
&lt;span style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-text-opacity: 1; --tw-translate-x: 0; --tw-translate-y: 0; border: 0px solid rgba(0, 0, 0, 0.08); box-sizing: border-box; color: #262626; font-weight: 700; overflow-wrap: break-word;&quot;&gt;Output:&lt;/span&gt; 9
&lt;span style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-text-opacity: 1; --tw-translate-x: 0; --tw-translate-y: 0; border: 0px solid rgba(0, 0, 0, 0.08); box-sizing: border-box; color: #262626; font-weight: 700; overflow-wrap: break-word;&quot;&gt;Explanation:&lt;/span&gt; The optimal pairing is (2, 1), (2, 5), (6, 6). min(2, 1) + min(2, 5) + min(6, 6) = 1 + 2 + 6 = 9.&lt;/pre&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;Approach:&lt;/b&gt; The catch here is to get the maximum sum possible. That means we need to get the maximum n values possible from the array but the problem here is we need to get the minimum value of the pair so what we can get is 2nd maximum, 4th maximum, 6th maximum and so on.&lt;/p&gt;&lt;p&gt;To get this efficiently, we can sort the array and then take nums[0], nums[2], nums[4] and so on. We just need to add these values and return it.&lt;/p&gt;&lt;p&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;Implementation in C#:&lt;/b&gt;&lt;/p&gt;&lt;div style=&quot;background-color: white; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 13px; line-height: 18px; white-space: pre;&quot;&gt;&lt;div&gt;&lt;span style=&quot;color: blue;&quot;&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;/span&gt;public&lt;/span&gt; &lt;span style=&quot;color: blue;&quot;&gt;int&lt;/span&gt; &lt;span style=&quot;color: #795e26;&quot;&gt;ArrayPairSum&lt;/span&gt;(&lt;span style=&quot;color: blue;&quot;&gt;int&lt;/span&gt;[] &lt;span style=&quot;color: #001080;&quot;&gt;nums&lt;/span&gt;)&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; {&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: blue;&quot;&gt;int&lt;/span&gt; &lt;span style=&quot;color: #001080;&quot;&gt;length&lt;/span&gt; = &lt;span style=&quot;color: #001080;&quot;&gt;nums&lt;/span&gt;?.&lt;span style=&quot;color: #001080;&quot;&gt;Length&lt;/span&gt; ?? &lt;span style=&quot;color: #098658;&quot;&gt;0&lt;/span&gt;;&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #af00db;&quot;&gt;if&lt;/span&gt; (&lt;span style=&quot;color: #001080;&quot;&gt;length&lt;/span&gt; == &lt;span style=&quot;color: #098658;&quot;&gt;0&lt;/span&gt; || &lt;span style=&quot;color: #001080;&quot;&gt;length&lt;/span&gt; % &lt;span style=&quot;color: #098658;&quot;&gt;2&lt;/span&gt; != &lt;span style=&quot;color: #098658;&quot;&gt;0&lt;/span&gt;)&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; {&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #af00db;&quot;&gt;return&lt;/span&gt; &lt;span style=&quot;color: #098658;&quot;&gt;0&lt;/span&gt;;&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #001080;&quot;&gt;Array&lt;/span&gt;.&lt;span style=&quot;color: #795e26;&quot;&gt;Sort&lt;/span&gt;(&lt;span style=&quot;color: #001080;&quot;&gt;nums&lt;/span&gt;);&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: blue;&quot;&gt;int&lt;/span&gt; &lt;span style=&quot;color: #001080;&quot;&gt;sum&lt;/span&gt; = &lt;span style=&quot;color: #098658;&quot;&gt;0&lt;/span&gt;;&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #af00db;&quot;&gt;for&lt;/span&gt; (&lt;span style=&quot;color: blue;&quot;&gt;int&lt;/span&gt; &lt;span style=&quot;color: #001080;&quot;&gt;i&lt;/span&gt; = &lt;span style=&quot;color: #098658;&quot;&gt;0&lt;/span&gt;; &lt;span style=&quot;color: #001080;&quot;&gt;i&lt;/span&gt; &amp;lt; &lt;span style=&quot;color: #001080;&quot;&gt;length&lt;/span&gt;; &lt;span style=&quot;color: #001080;&quot;&gt;i&lt;/span&gt; += &lt;span style=&quot;color: #098658;&quot;&gt;2&lt;/span&gt;)&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; {&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #001080;&quot;&gt;sum&lt;/span&gt; += &lt;span style=&quot;color: #001080;&quot;&gt;nums&lt;/span&gt;[&lt;span style=&quot;color: #001080;&quot;&gt;i&lt;/span&gt;];&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #af00db;&quot;&gt;return&lt;/span&gt; &lt;span style=&quot;color: #001080;&quot;&gt;sum&lt;/span&gt;;&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; }&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;Complexity:&lt;/b&gt; O(nlogn)&lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='http://algods-cracker.blogspot.com/feeds/5571946508482641584/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://algods-cracker.blogspot.com/2026/01/leetcode-array-partition.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7496974970329409400/posts/default/5571946508482641584'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7496974970329409400/posts/default/5571946508482641584'/><link rel='alternate' type='text/html' href='http://algods-cracker.blogspot.com/2026/01/leetcode-array-partition.html' title='[LeetCode] Array Partition'/><author><name>Nishant Saxena</name><uri>http://www.blogger.com/profile/17860524009847591950</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjOdjS62BAEI1iMG_zd6lew4qyFGpfJhWHp0AJWQhiJvxQpSGg0AFZ5euJG7tK0D-EGQFno32hF-i1x4E2A49re_8-b9r0QHwXQ-9X_EvlAcekIjUYMaA1v6dWzDqzkBg/s220/2d230a1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7496974970329409400.post-4858628752206033762</id><published>2026-01-25T19:24:00.002+05:30</published><updated>2026-01-25T19:24:22.431+05:30</updated><category scheme="http://www.blogger.com/atom/ns#" term="LeetCode"/><title type='text'>[LeetCode] Minimum Difference Between Highest and Lowest of K Scores</title><content type='html'>&lt;p&gt;&lt;b&gt;Problem:&lt;/b&gt; You are given a 0-indexed integer array nums, where nums[i] represents the score of the ith student. You are also given an integer k.&lt;/p&gt;&lt;p&gt;Pick the scores of any k students from the array so that the difference between the highest and the lowest of the k scores is minimized.&lt;/p&gt;&lt;p&gt;Return the minimum possible difference.&lt;/p&gt;&lt;p&gt;Example:&lt;/p&gt;&lt;pre style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-translate-x: 0; --tw-translate-y: 0; background-color: #f0f0f0; border-color: rgba(0, 0, 0, 0.08); border-image: initial; border-style: solid; border-width: 0px 0px 0px 2px; box-sizing: border-box; color: rgba(0, 0, 0, 0.55); font-family: Menlo, sans-serif; font-size: 14px; line-height: 1.25rem; margin: 1rem 0px; overflow-wrap: break-word; overflow: visible; padding-left: 1rem; text-wrap-mode: wrap;&quot;&gt;&lt;span style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-text-opacity: 1; --tw-translate-x: 0; --tw-translate-y: 0; border: 0px solid rgba(0, 0, 0, 0.08); box-sizing: border-box; color: #262626; font-weight: 700; overflow-wrap: break-word;&quot;&gt;Input:&lt;/span&gt; nums = [90], k = 1
&lt;span style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-text-opacity: 1; --tw-translate-x: 0; --tw-translate-y: 0; border: 0px solid rgba(0, 0, 0, 0.08); box-sizing: border-box; color: #262626; font-weight: 700; overflow-wrap: break-word;&quot;&gt;Output:&lt;/span&gt; 0
&lt;span style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-text-opacity: 1; --tw-translate-x: 0; --tw-translate-y: 0; border: 0px solid rgba(0, 0, 0, 0.08); box-sizing: border-box; color: #262626; font-weight: 700; overflow-wrap: break-word;&quot;&gt;Explanation:&lt;/span&gt; There is one way to pick score(s) of one student:
- [&lt;span style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-text-opacity: 1; --tw-translate-x: 0; --tw-translate-y: 0; border: 0px solid rgba(0, 0, 0, 0.08); box-sizing: border-box; color: #262626; font-weight: 700; overflow-wrap: break-word;&quot;&gt;&lt;u style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-translate-x: 0; --tw-translate-y: 0; border: 0px solid rgba(0, 0, 0, 0.08); box-sizing: border-box; overflow-wrap: break-word;&quot;&gt;90&lt;/u&gt;&lt;/span&gt;]. The difference between the highest and lowest score is 90 - 90 = 0.
The minimum possible difference is 0.&lt;/pre&gt;&lt;pre style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-translate-x: 0; --tw-translate-y: 0; background-color: #f0f0f0; border-color: rgba(0, 0, 0, 0.08); border-image: initial; border-style: solid; border-width: 0px 0px 0px 2px; box-sizing: border-box; color: rgba(0, 0, 0, 0.55); font-family: Menlo, sans-serif; font-size: 14px; line-height: 1.25rem; margin: 1rem 0px; overflow-wrap: break-word; overflow: visible; padding-left: 1rem; text-wrap-mode: wrap;&quot;&gt;&lt;span style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-text-opacity: 1; --tw-translate-x: 0; --tw-translate-y: 0; border: 0px solid rgba(0, 0, 0, 0.08); box-sizing: border-box; color: #262626; font-weight: 700; overflow-wrap: break-word;&quot;&gt;Input:&lt;/span&gt; nums = [9,4,1,7], k = 2
&lt;span style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-text-opacity: 1; --tw-translate-x: 0; --tw-translate-y: 0; border: 0px solid rgba(0, 0, 0, 0.08); box-sizing: border-box; color: #262626; font-weight: 700; overflow-wrap: break-word;&quot;&gt;Output:&lt;/span&gt; 2
&lt;span style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-text-opacity: 1; --tw-translate-x: 0; --tw-translate-y: 0; border: 0px solid rgba(0, 0, 0, 0.08); box-sizing: border-box; color: #262626; font-weight: 700; overflow-wrap: break-word;&quot;&gt;Explanation:&lt;/span&gt; There are six ways to pick score(s) of two students:
- [&lt;span style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-text-opacity: 1; --tw-translate-x: 0; --tw-translate-y: 0; border: 0px solid rgba(0, 0, 0, 0.08); box-sizing: border-box; color: #262626; font-weight: 700; overflow-wrap: break-word;&quot;&gt;&lt;u style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-translate-x: 0; --tw-translate-y: 0; border: 0px solid rgba(0, 0, 0, 0.08); box-sizing: border-box; overflow-wrap: break-word;&quot;&gt;9&lt;/u&gt;&lt;/span&gt;,&lt;span style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-text-opacity: 1; --tw-translate-x: 0; --tw-translate-y: 0; border: 0px solid rgba(0, 0, 0, 0.08); box-sizing: border-box; color: #262626; font-weight: 700; overflow-wrap: break-word;&quot;&gt;&lt;u style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-translate-x: 0; --tw-translate-y: 0; border: 0px solid rgba(0, 0, 0, 0.08); box-sizing: border-box; overflow-wrap: break-word;&quot;&gt;4&lt;/u&gt;&lt;/span&gt;,1,7]. The difference between the highest and lowest score is 9 - 4 = 5.
- [&lt;span style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-text-opacity: 1; --tw-translate-x: 0; --tw-translate-y: 0; border: 0px solid rgba(0, 0, 0, 0.08); box-sizing: border-box; color: #262626; font-weight: 700; overflow-wrap: break-word;&quot;&gt;&lt;u style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-translate-x: 0; --tw-translate-y: 0; border: 0px solid rgba(0, 0, 0, 0.08); box-sizing: border-box; overflow-wrap: break-word;&quot;&gt;9&lt;/u&gt;&lt;/span&gt;,4,&lt;span style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-text-opacity: 1; --tw-translate-x: 0; --tw-translate-y: 0; border: 0px solid rgba(0, 0, 0, 0.08); box-sizing: border-box; color: #262626; font-weight: 700; overflow-wrap: break-word;&quot;&gt;&lt;u style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-translate-x: 0; --tw-translate-y: 0; border: 0px solid rgba(0, 0, 0, 0.08); box-sizing: border-box; overflow-wrap: break-word;&quot;&gt;1&lt;/u&gt;&lt;/span&gt;,7]. The difference between the highest and lowest score is 9 - 1 = 8.
- [&lt;span style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-text-opacity: 1; --tw-translate-x: 0; --tw-translate-y: 0; border: 0px solid rgba(0, 0, 0, 0.08); box-sizing: border-box; color: #262626; font-weight: 700; overflow-wrap: break-word;&quot;&gt;&lt;u style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-translate-x: 0; --tw-translate-y: 0; border: 0px solid rgba(0, 0, 0, 0.08); box-sizing: border-box; overflow-wrap: break-word;&quot;&gt;9&lt;/u&gt;&lt;/span&gt;,4,1,&lt;span style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-text-opacity: 1; --tw-translate-x: 0; --tw-translate-y: 0; border: 0px solid rgba(0, 0, 0, 0.08); box-sizing: border-box; color: #262626; font-weight: 700; overflow-wrap: break-word;&quot;&gt;&lt;u style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-translate-x: 0; --tw-translate-y: 0; border: 0px solid rgba(0, 0, 0, 0.08); box-sizing: border-box; overflow-wrap: break-word;&quot;&gt;7&lt;/u&gt;&lt;/span&gt;]. The difference between the highest and lowest score is 9 - 7 = 2.
- [9,&lt;span style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-text-opacity: 1; --tw-translate-x: 0; --tw-translate-y: 0; border: 0px solid rgba(0, 0, 0, 0.08); box-sizing: border-box; color: #262626; font-weight: 700; overflow-wrap: break-word;&quot;&gt;&lt;u style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-translate-x: 0; --tw-translate-y: 0; border: 0px solid rgba(0, 0, 0, 0.08); box-sizing: border-box; overflow-wrap: break-word;&quot;&gt;4&lt;/u&gt;&lt;/span&gt;,&lt;span style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-text-opacity: 1; --tw-translate-x: 0; --tw-translate-y: 0; border: 0px solid rgba(0, 0, 0, 0.08); box-sizing: border-box; color: #262626; font-weight: 700; overflow-wrap: break-word;&quot;&gt;&lt;u style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-translate-x: 0; --tw-translate-y: 0; border: 0px solid rgba(0, 0, 0, 0.08); box-sizing: border-box; overflow-wrap: break-word;&quot;&gt;1&lt;/u&gt;&lt;/span&gt;,7]. The difference between the highest and lowest score is 4 - 1 = 3.
- [9,&lt;span style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-text-opacity: 1; --tw-translate-x: 0; --tw-translate-y: 0; border: 0px solid rgba(0, 0, 0, 0.08); box-sizing: border-box; color: #262626; font-weight: 700; overflow-wrap: break-word;&quot;&gt;&lt;u style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-translate-x: 0; --tw-translate-y: 0; border: 0px solid rgba(0, 0, 0, 0.08); box-sizing: border-box; overflow-wrap: break-word;&quot;&gt;4&lt;/u&gt;&lt;/span&gt;,1,&lt;span style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-text-opacity: 1; --tw-translate-x: 0; --tw-translate-y: 0; border: 0px solid rgba(0, 0, 0, 0.08); box-sizing: border-box; color: #262626; font-weight: 700; overflow-wrap: break-word;&quot;&gt;&lt;u style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-translate-x: 0; --tw-translate-y: 0; border: 0px solid rgba(0, 0, 0, 0.08); box-sizing: border-box; overflow-wrap: break-word;&quot;&gt;7&lt;/u&gt;&lt;/span&gt;]. The difference between the highest and lowest score is 7 - 4 = 3.
- [9,4,&lt;span style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-text-opacity: 1; --tw-translate-x: 0; --tw-translate-y: 0; border: 0px solid rgba(0, 0, 0, 0.08); box-sizing: border-box; color: #262626; font-weight: 700; overflow-wrap: break-word;&quot;&gt;&lt;u style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-translate-x: 0; --tw-translate-y: 0; border: 0px solid rgba(0, 0, 0, 0.08); box-sizing: border-box; overflow-wrap: break-word;&quot;&gt;1&lt;/u&gt;&lt;/span&gt;,&lt;span style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-text-opacity: 1; --tw-translate-x: 0; --tw-translate-y: 0; border: 0px solid rgba(0, 0, 0, 0.08); box-sizing: border-box; color: #262626; font-weight: 700; overflow-wrap: break-word;&quot;&gt;&lt;u style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-translate-x: 0; --tw-translate-y: 0; border: 0px solid rgba(0, 0, 0, 0.08); box-sizing: border-box; overflow-wrap: break-word;&quot;&gt;7&lt;/u&gt;&lt;/span&gt;]. The difference between the highest and lowest score is 7 - 1 = 6.
The minimum possible difference is 2.&lt;/pre&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;Approach:&lt;/b&gt; We have to find the maximum and minimum value of each k size subarray so we can sort the array. Now what we just need to do is to take the subarray in sequence like nums[0...k-1], nums[1...k], nums[2...k+1] etc. Now if you see its easy to find the max and min value of these subarray as 1st value will be the minimum value and last value is the maximum value.&lt;/p&gt;&lt;p&gt;Now we just need to take the difference of these value and get the minimum of these differences which will be our answer.&lt;/p&gt;&lt;p&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;Implementation in C#:&lt;/b&gt;&lt;/p&gt;&lt;div style=&quot;background-color: white; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 13px; line-height: 18px; white-space: pre;&quot;&gt;&lt;div&gt;&lt;span style=&quot;color: blue;&quot;&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;/span&gt;public&lt;/span&gt; &lt;span style=&quot;color: blue;&quot;&gt;int&lt;/span&gt; &lt;span style=&quot;color: #795e26;&quot;&gt;MinimumDifference&lt;/span&gt;(&lt;span style=&quot;color: blue;&quot;&gt;int&lt;/span&gt;[] &lt;span style=&quot;color: #001080;&quot;&gt;nums&lt;/span&gt;, &lt;span style=&quot;color: blue;&quot;&gt;int&lt;/span&gt; &lt;span style=&quot;color: #001080;&quot;&gt;k&lt;/span&gt;)&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; {&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: blue;&quot;&gt;int&lt;/span&gt; &lt;span style=&quot;color: #001080;&quot;&gt;length&lt;/span&gt; = &lt;span style=&quot;color: #001080;&quot;&gt;nums&lt;/span&gt;?.&lt;span style=&quot;color: #001080;&quot;&gt;Length&lt;/span&gt; ?? &lt;span style=&quot;color: #098658;&quot;&gt;0&lt;/span&gt;;&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #af00db;&quot;&gt;if&lt;/span&gt; (&lt;span style=&quot;color: #001080;&quot;&gt;k&lt;/span&gt; &amp;gt; &lt;span style=&quot;color: #001080;&quot;&gt;length&lt;/span&gt;)&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; {&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #af00db;&quot;&gt;return&lt;/span&gt; &lt;span style=&quot;color: #098658;&quot;&gt;0&lt;/span&gt;;&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #001080;&quot;&gt;Array&lt;/span&gt;.&lt;span style=&quot;color: #795e26;&quot;&gt;Sort&lt;/span&gt;(&lt;span style=&quot;color: #001080;&quot;&gt;nums&lt;/span&gt;);&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: blue;&quot;&gt;int&lt;/span&gt; &lt;span style=&quot;color: #001080;&quot;&gt;min&lt;/span&gt; = &lt;span style=&quot;color: #001080;&quot;&gt;int&lt;/span&gt;.&lt;span style=&quot;color: #001080;&quot;&gt;MaxValue&lt;/span&gt;; &amp;nbsp; &amp;nbsp;&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #af00db;&quot;&gt;for&lt;/span&gt; (&lt;span style=&quot;color: blue;&quot;&gt;int&lt;/span&gt; &lt;span style=&quot;color: #001080;&quot;&gt;i&lt;/span&gt; = &lt;span style=&quot;color: #098658;&quot;&gt;0&lt;/span&gt;; &lt;span style=&quot;color: #001080;&quot;&gt;i&lt;/span&gt; + &lt;span style=&quot;color: #001080;&quot;&gt;k&lt;/span&gt; &amp;lt;= &lt;span style=&quot;color: #001080;&quot;&gt;length&lt;/span&gt;; ++&lt;span style=&quot;color: #001080;&quot;&gt;i&lt;/span&gt;)&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; {&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #af00db;&quot;&gt;if&lt;/span&gt; (&lt;span style=&quot;color: #001080;&quot;&gt;min&lt;/span&gt; &amp;gt; &lt;span style=&quot;color: #001080;&quot;&gt;nums&lt;/span&gt;[&lt;span style=&quot;color: #001080;&quot;&gt;i&lt;/span&gt; + &lt;span style=&quot;color: #001080;&quot;&gt;k&lt;/span&gt; - &lt;span style=&quot;color: #098658;&quot;&gt;1&lt;/span&gt;] - &lt;span style=&quot;color: #001080;&quot;&gt;nums&lt;/span&gt;[&lt;span style=&quot;color: #001080;&quot;&gt;i&lt;/span&gt;])&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; {&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #001080;&quot;&gt;min&lt;/span&gt; = &lt;span style=&quot;color: #001080;&quot;&gt;nums&lt;/span&gt;[&lt;span style=&quot;color: #001080;&quot;&gt;i&lt;/span&gt; + &lt;span style=&quot;color: #001080;&quot;&gt;k&lt;/span&gt; - &lt;span style=&quot;color: #098658;&quot;&gt;1&lt;/span&gt;] - &lt;span style=&quot;color: #001080;&quot;&gt;nums&lt;/span&gt;[&lt;span style=&quot;color: #001080;&quot;&gt;i&lt;/span&gt;];&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #af00db;&quot;&gt;return&lt;/span&gt; &lt;span style=&quot;color: #001080;&quot;&gt;min&lt;/span&gt;; &amp;nbsp; &amp;nbsp; &lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; }&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;Complexity:&lt;/b&gt; O(nlogn)&lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='http://algods-cracker.blogspot.com/feeds/4858628752206033762/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://algods-cracker.blogspot.com/2026/01/leetcode-minimum-difference-between.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7496974970329409400/posts/default/4858628752206033762'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7496974970329409400/posts/default/4858628752206033762'/><link rel='alternate' type='text/html' href='http://algods-cracker.blogspot.com/2026/01/leetcode-minimum-difference-between.html' title='[LeetCode] Minimum Difference Between Highest and Lowest of K Scores'/><author><name>Nishant Saxena</name><uri>http://www.blogger.com/profile/17860524009847591950</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjOdjS62BAEI1iMG_zd6lew4qyFGpfJhWHp0AJWQhiJvxQpSGg0AFZ5euJG7tK0D-EGQFno32hF-i1x4E2A49re_8-b9r0QHwXQ-9X_EvlAcekIjUYMaA1v6dWzDqzkBg/s220/2d230a1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7496974970329409400.post-4036642550993678222</id><published>2025-10-29T21:06:00.002+05:30</published><updated>2025-10-29T21:06:09.214+05:30</updated><category scheme="http://www.blogger.com/atom/ns#" term="Bits magic"/><category scheme="http://www.blogger.com/atom/ns#" term="LeetCode"/><title type='text'>[LeetCode] Smallest Number With All Set Bits</title><content type='html'>&lt;p&gt;&lt;b&gt;Problem:&lt;/b&gt; You are given a positive number n.&lt;/p&gt;&lt;p&gt;Return the smallest number x greater than or equal to n, such that the binary representation of x contains only set bits&lt;/p&gt;&lt;p&gt;Example:&lt;/p&gt;&lt;pre style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-translate-x: 0; --tw-translate-y: 0; background-color: #f0f0f0; border-color: rgb(102, 102, 102); border-image: initial; border-style: solid; border-width: 0px 0px 0px 2px; box-sizing: border-box; color: #666666; font-family: Menlo, sans-serif; font-size: 14px; line-height: 1.25rem; margin-bottom: 1rem; margin-top: 1rem; overflow-wrap: break-word; overflow: visible; padding-left: 1rem; text-wrap: wrap;&quot;&gt;&lt;span style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-text-opacity: 1; --tw-translate-x: 0; --tw-translate-y: 0; border: 0px solid rgb(38, 38, 38); box-sizing: border-box; color: #262626; font-weight: 700; overflow-wrap: break-word;&quot;&gt;Input:&lt;/span&gt; &lt;span style=&quot;color: rgba(0, 0, 0, 0.55); font-size: 13.6px; white-space-collapse: collapse;&quot;&gt;n = 5&lt;/span&gt;
&lt;span style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-text-opacity: 1; --tw-translate-x: 0; --tw-translate-y: 0; border: 0px solid rgb(38, 38, 38); box-sizing: border-box; color: #262626; font-weight: 700; overflow-wrap: break-word;&quot;&gt;Output:&lt;/span&gt; 7
&lt;span style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-text-opacity: 1; --tw-translate-x: 0; --tw-translate-y: 0; border: 0px solid rgb(38, 38, 38); box-sizing: border-box; color: #262626; font-weight: 700; overflow-wrap: break-word;&quot;&gt;Explanation: &lt;/span&gt;
&lt;span style=&quot;color: rgba(0, 0, 0, 0.55); font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe UI&amp;quot;, Helvetica, Arial, sans-serif, &amp;quot;Apple Color Emoji&amp;quot;, &amp;quot;Segoe UI Emoji&amp;quot;; white-space-collapse: collapse;&quot;&gt;The binary representation of 7 is&amp;nbsp;&lt;/span&gt;&lt;code style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-translate-x: 0; --tw-translate-y: 0; background-color: rgba(0, 10, 32, 0.03); border-radius: 5px; border: 1px solid rgba(0, 0, 0, 0.05); box-sizing: border-box; color: rgba(38, 38, 38, 0.75); font-family: Menlo, sans-serif; font-size: 0.75rem; line-height: 1rem; overflow-wrap: break-word; padding: 0.125rem;&quot;&gt;&quot;111&quot;&lt;/code&gt;&lt;span style=&quot;color: rgba(0, 0, 0, 0.55); font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe UI&amp;quot;, Helvetica, Arial, sans-serif, &amp;quot;Apple Color Emoji&amp;quot;, &amp;quot;Segoe UI Emoji&amp;quot;; white-space-collapse: collapse;&quot;&gt;.&lt;/span&gt;&lt;/pre&gt;&lt;pre style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-translate-x: 0; --tw-translate-y: 0; background-color: #f0f0f0; border-color: rgb(102, 102, 102); border-image: initial; border-style: solid; border-width: 0px 0px 0px 2px; box-sizing: border-box; color: #666666; font-family: Menlo, sans-serif; font-size: 14px; line-height: 1.25rem; margin-bottom: 1rem; margin-top: 1rem; overflow-wrap: break-word; overflow: visible; padding-left: 1rem; text-wrap: wrap;&quot;&gt;&lt;span style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-text-opacity: 1; --tw-translate-x: 0; --tw-translate-y: 0; border: 0px solid rgb(38, 38, 38); box-sizing: border-box; color: #262626; font-weight: 700; overflow-wrap: break-word;&quot;&gt;Input:&lt;/span&gt; &lt;span style=&quot;color: rgba(0, 0, 0, 0.55); font-size: 13.6px; white-space-collapse: collapse;&quot;&gt;n = 10&lt;/span&gt;
&lt;span style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-text-opacity: 1; --tw-translate-x: 0; --tw-translate-y: 0; border: 0px solid rgb(38, 38, 38); box-sizing: border-box; color: #262626; font-weight: 700; overflow-wrap: break-word;&quot;&gt;Output:&lt;/span&gt; 15
&lt;span style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-text-opacity: 1; --tw-translate-x: 0; --tw-translate-y: 0; border: 0px solid rgb(38, 38, 38); box-sizing: border-box; color: #262626; font-weight: 700; overflow-wrap: break-word;&quot;&gt;Explanation: &lt;/span&gt;
&lt;span style=&quot;color: rgba(0, 0, 0, 0.55); font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe UI&amp;quot;, Helvetica, Arial, sans-serif, &amp;quot;Apple Color Emoji&amp;quot;, &amp;quot;Segoe UI Emoji&amp;quot;; white-space-collapse: collapse;&quot;&gt;The binary representation of 15 is&amp;nbsp;&lt;/span&gt;&lt;code style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-translate-x: 0; --tw-translate-y: 0; background-color: rgba(0, 10, 32, 0.03); border-radius: 5px; border: 1px solid rgba(0, 0, 0, 0.05); box-sizing: border-box; color: rgba(38, 38, 38, 0.75); font-family: Menlo, sans-serif; font-size: 0.75rem; line-height: 1rem; overflow-wrap: break-word; padding: 0.125rem;&quot;&gt;&quot;1111&quot;&lt;/code&gt;&lt;span style=&quot;color: rgba(0, 0, 0, 0.55); font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe UI&amp;quot;, Helvetica, Arial, sans-serif, &amp;quot;Apple Color Emoji&amp;quot;, &amp;quot;Segoe UI Emoji&amp;quot;; white-space-collapse: collapse;&quot;&gt;.&lt;/span&gt;&lt;/pre&gt;&lt;pre style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-translate-x: 0; --tw-translate-y: 0; background-color: #f0f0f0; border-color: rgb(102, 102, 102); border-image: initial; border-style: solid; border-width: 0px 0px 0px 2px; box-sizing: border-box; color: #666666; font-family: Menlo, sans-serif; font-size: 14px; line-height: 1.25rem; margin-bottom: 1rem; margin-top: 1rem; overflow-wrap: break-word; overflow: visible; padding-left: 1rem; text-wrap: wrap;&quot;&gt;&lt;span style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-text-opacity: 1; --tw-translate-x: 0; --tw-translate-y: 0; border: 0px solid rgb(38, 38, 38); box-sizing: border-box; color: #262626; font-weight: 700; overflow-wrap: break-word;&quot;&gt;Input:&lt;/span&gt; &lt;span style=&quot;color: rgba(0, 0, 0, 0.55); font-size: 13.6px; white-space-collapse: collapse;&quot;&gt;n = 3&lt;/span&gt;
&lt;span style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-text-opacity: 1; --tw-translate-x: 0; --tw-translate-y: 0; border: 0px solid rgb(38, 38, 38); box-sizing: border-box; color: #262626; font-weight: 700; overflow-wrap: break-word;&quot;&gt;Output:&lt;/span&gt; 3
&lt;span style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-text-opacity: 1; --tw-translate-x: 0; --tw-translate-y: 0; border: 0px solid rgb(38, 38, 38); box-sizing: border-box; color: #262626; font-weight: 700; overflow-wrap: break-word;&quot;&gt;Explanation: &lt;/span&gt;
&lt;span style=&quot;color: rgba(0, 0, 0, 0.55); font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe UI&amp;quot;, Helvetica, Arial, sans-serif, &amp;quot;Apple Color Emoji&amp;quot;, &amp;quot;Segoe UI Emoji&amp;quot;; white-space-collapse: collapse;&quot;&gt;The binary representation of 3 is&amp;nbsp;&lt;/span&gt;&lt;code style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-translate-x: 0; --tw-translate-y: 0; background-color: rgba(0, 10, 32, 0.03); border-radius: 5px; border: 1px solid rgba(0, 0, 0, 0.05); box-sizing: border-box; color: rgba(38, 38, 38, 0.75); font-family: Menlo, sans-serif; font-size: 0.75rem; line-height: 1rem; overflow-wrap: break-word; padding: 0.125rem;&quot;&gt;&quot;11&quot;&lt;/code&gt;&lt;span style=&quot;color: rgba(0, 0, 0, 0.55); font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe UI&amp;quot;, Helvetica, Arial, sans-serif, &amp;quot;Apple Color Emoji&amp;quot;, &amp;quot;Segoe UI Emoji&amp;quot;; white-space-collapse: collapse;&quot;&gt;.&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;Approach:&lt;/b&gt; One simple way to think about it is we just need to get the number of bits requird to (like 5 is 000...0101 so number of bits are 3 in number 5) represent the current number and get to the number which is having same number of bits with all the bits set.&lt;/p&gt;&lt;p&gt;To get the number of bits, we can simply take the log base 2 of the given number. Say the result is b so the result will be 2^b - 1.&lt;/p&gt;&lt;p&gt;Now say we are not given the log method and also we want to make it more performant using biwise operations.&amp;nbsp;&lt;/p&gt;&lt;p&gt;Key is if the a number has all the bits set then n &amp;amp; (n + 1) will be 0 so what we just need to do is keep setting the unset bit set using n | (n + 1) till we get n &amp;amp; (n + 1) is 0.&lt;/p&gt;&lt;p&gt;Question is how n | (n + 1) will set the bit.? It&#39;s because adding 1 to a number will always set the first unset bit so if we OR with the original number, we are setting the next unset bit in the original number.&lt;/p&gt;&lt;p&gt;&lt;b&gt;Implementation in C#:&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;Approach 1: Using Log2:&lt;/b&gt;&lt;/p&gt;&lt;div style=&quot;background-color: white; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 13px; line-height: 18px; white-space: pre;&quot;&gt;&lt;div&gt;&lt;span style=&quot;color: blue;&quot;&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;/span&gt;public&lt;/span&gt; &lt;span style=&quot;color: blue;&quot;&gt;int&lt;/span&gt; &lt;span style=&quot;color: #795e26;&quot;&gt;SmallestNumber&lt;/span&gt;(&lt;span style=&quot;color: blue;&quot;&gt;int&lt;/span&gt; &lt;span style=&quot;color: #001080;&quot;&gt;n&lt;/span&gt;) &lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; {&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: blue;&quot;&gt;int&lt;/span&gt; &lt;span style=&quot;color: #001080;&quot;&gt;numBits&lt;/span&gt; = (&lt;span style=&quot;color: blue;&quot;&gt;int&lt;/span&gt;)&lt;span style=&quot;color: #001080;&quot;&gt;Math&lt;/span&gt;.&lt;span style=&quot;color: #795e26;&quot;&gt;Floor&lt;/span&gt;(&lt;span style=&quot;color: #001080;&quot;&gt;Math&lt;/span&gt;.&lt;span style=&quot;color: #795e26;&quot;&gt;Log2&lt;/span&gt;(&lt;span style=&quot;color: #001080;&quot;&gt;n&lt;/span&gt;)) + &lt;span style=&quot;color: #098658;&quot;&gt;1&lt;/span&gt;;&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #af00db;&quot;&gt;return&lt;/span&gt; ((&lt;span style=&quot;color: blue;&quot;&gt;int&lt;/span&gt;)&lt;span style=&quot;color: #001080;&quot;&gt;Math&lt;/span&gt;.&lt;span style=&quot;color: #795e26;&quot;&gt;Pow&lt;/span&gt;(&lt;span style=&quot;color: #098658;&quot;&gt;2&lt;/span&gt;, &lt;span style=&quot;color: #001080;&quot;&gt;numBits&lt;/span&gt;)) - &lt;span style=&quot;color: #098658;&quot;&gt;1&lt;/span&gt;;&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; }&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&lt;b&gt;Approach 2: Using Bitwise operators:&lt;/b&gt;&lt;/p&gt;&lt;div style=&quot;background-color: white; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 13px; line-height: 18px; white-space: pre;&quot;&gt;&lt;div&gt;&lt;span style=&quot;color: blue;&quot;&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;/span&gt;public&lt;/span&gt; &lt;span style=&quot;color: blue;&quot;&gt;int&lt;/span&gt; &lt;span style=&quot;color: #795e26;&quot;&gt;SmallestNumber&lt;/span&gt;(&lt;span style=&quot;color: blue;&quot;&gt;int&lt;/span&gt; &lt;span style=&quot;color: #001080;&quot;&gt;n&lt;/span&gt;) &lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; {&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #af00db;&quot;&gt;while&lt;/span&gt; ((&lt;span style=&quot;color: #001080;&quot;&gt;n&lt;/span&gt; &amp;amp; (&lt;span style=&quot;color: #001080;&quot;&gt;n&lt;/span&gt; + &lt;span style=&quot;color: #098658;&quot;&gt;1&lt;/span&gt;)) != &lt;span style=&quot;color: #098658;&quot;&gt;0&lt;/span&gt;)&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; {&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #001080;&quot;&gt;n&lt;/span&gt; |= (&lt;span style=&quot;color: #001080;&quot;&gt;n&lt;/span&gt; + &lt;span style=&quot;color: #098658;&quot;&gt;1&lt;/span&gt;);&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #af00db;&quot;&gt;return&lt;/span&gt; &lt;span style=&quot;color: #001080;&quot;&gt;n&lt;/span&gt;;&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; }&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&lt;b&gt;Complexity:&lt;/b&gt; O(logn)&lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='http://algods-cracker.blogspot.com/feeds/4036642550993678222/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://algods-cracker.blogspot.com/2025/10/leetcode-smallest-number-with-all-set.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7496974970329409400/posts/default/4036642550993678222'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7496974970329409400/posts/default/4036642550993678222'/><link rel='alternate' type='text/html' href='http://algods-cracker.blogspot.com/2025/10/leetcode-smallest-number-with-all-set.html' title='[LeetCode] Smallest Number With All Set Bits'/><author><name>Nishant Saxena</name><uri>http://www.blogger.com/profile/17860524009847591950</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjOdjS62BAEI1iMG_zd6lew4qyFGpfJhWHp0AJWQhiJvxQpSGg0AFZ5euJG7tK0D-EGQFno32hF-i1x4E2A49re_8-b9r0QHwXQ-9X_EvlAcekIjUYMaA1v6dWzDqzkBg/s220/2d230a1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7496974970329409400.post-5203458186445549400</id><published>2025-08-01T21:23:00.003+05:30</published><updated>2025-08-01T22:05:54.080+05:30</updated><category scheme="http://www.blogger.com/atom/ns#" term="Netflix Tech Blog"/><title type='text'>[Netflix Tech Blog] Behind the Scenes of Pushy - Netflix’s Real-Time WebSocket Proxy (Part 1)</title><content type='html'>&lt;div&gt;In today’s connected world, user experiences are expected to be instant, interactive, and deeply personalized. Whether it’s a mobile notification about a new episode, a voice command to your smart TV, or a prompt to resume your last show; the ability to &lt;b&gt;push messages in real-time&lt;/b&gt; has become critical.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;At Netflix’s scale, serving hundreds of millions of devices across the globe, building and maintaining a real-time communication layer isn’t just desirable, it’s mission-critical.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;That’s where&amp;nbsp; &lt;b&gt;Pushy&lt;/b&gt; comes in which is Netflix’s in-house WebSocket proxy, designed to reliably deliver &lt;b&gt;low-latency&lt;/b&gt;, &lt;b&gt;bi-directional&lt;/b&gt; communication between client devices (TVs, phones, browsers, game consoles) and backend services. Originally created to support use cases like &lt;b&gt;voice search&lt;/b&gt;, &lt;b&gt;remote control pairing&lt;/b&gt;, &lt;b&gt;casting&lt;/b&gt;, and other &lt;b&gt;interactive UI elements&lt;/b&gt;, Pushy quickly became a foundational service for Netflix.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;But as the streaming giant continued evolving its product and infrastructure, cracks began to appear in Pushy’s original design and some of them are scalability, observability, and operational resilience needed a rethinking.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;In this two-part breakdown series, I’ll walk you through:&lt;/div&gt;&lt;div&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;What Pushy is and why Netflix built it&lt;/li&gt;&lt;li&gt;The original architecture and its role in powering interactive features&lt;/li&gt;&lt;li&gt;What worked well and where it started to show strain&lt;/li&gt;&lt;li&gt;And in Part 2: how Netflix rearchitected Pushy to meet the future head-on&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div&gt;📖 &lt;i&gt;Reference: &lt;a href=&quot;https://netflixtechblog.com/pushy-to-the-limit-evolving-netflixs-websocket-proxy-for-the-future-b468bc0ff658&quot; target=&quot;_blank&quot;&gt;Pushy to the Limit: Evolving Netflix’s WebSocket Proxy for the Future&lt;/a&gt;&lt;/i&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Let’s start by understanding the need for Pushy in the first place.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;b&gt;💡&amp;nbsp;Why Netflix Needed Pushy in the First Place&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;As Netflix expanded from being a content streaming service to an interactive entertainment platform, the demands on its device communication infrastructure grew rapidly. Simple HTTP-based polling or long-polling mechanisms were no longer sufficient for the level of interactivity users expected.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Here are the emerging use cases that demanded &lt;b&gt;real-time&lt;/b&gt;, &lt;b&gt;low-latency communication&lt;/b&gt;&amp;nbsp;between Netflix devices and backend services:&lt;/div&gt;&lt;div&gt;&lt;ol style=&quot;text-align: left;&quot;&gt;&lt;li&gt;&lt;b&gt;Voice Search &amp;amp; Navigation:&lt;/b&gt; Smart TVs and streaming devices increasingly support voice commands. Users expect their spoken input to be recognized, interpreted, and acted upon in real-time, requiring a persistent, fast channel between device and service.&lt;/li&gt;&lt;li&gt;&lt;b&gt;Second-Screen Experiences &amp;amp; Remote Control Pairing:&lt;/b&gt; Netflix enables pairing between mobile devices and TVs, allowing the phone to act as a remote or companion device. This requires devices to discover each other and exchange information instantly.&lt;/li&gt;&lt;li&gt;&lt;b&gt;Casting:&lt;/b&gt; When users cast Netflix content from their phones to another device (like Chromecast or a Smart TV), there’s a need for near-instant coordination between devices.&lt;/li&gt;&lt;li&gt;&lt;b&gt;Interactive UI Elements&lt;/b&gt;:&amp;nbsp; Think of countdowns, real-time error reporting, or UI nudges (e.g., &quot;Resume from where you left off&quot;) , these need to be delivered to the client immediately and reliably.&lt;/li&gt;&lt;/ol&gt;&lt;/div&gt;&lt;div&gt;To power these experiences, Netflix needed a solution that:&lt;/div&gt;&lt;div&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;Could &lt;b&gt;maintain persistent&lt;/b&gt;, &lt;b&gt;bidirectional connections&lt;/b&gt;&amp;nbsp;at scale.&lt;/li&gt;&lt;li&gt;Worked across &lt;b&gt;millions of heterogeneous devices&lt;/b&gt;.&lt;/li&gt;&lt;li&gt;Offered &lt;b&gt;low-latency delivery&lt;/b&gt;&amp;nbsp;for time-sensitive events.&lt;/li&gt;&lt;li&gt;Could be &lt;b&gt;centrally managed&lt;/b&gt;, &lt;b&gt;observed&lt;/b&gt;, and &lt;b&gt;extended&lt;/b&gt; to future use cases.&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div&gt;That solution was &lt;b&gt;Pushy,&lt;/b&gt;&amp;nbsp;a custom-built WebSocket proxy service that sits between client devices and backend systems, managing long-lived connections and ensuring seamless real-time communication.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;Here is one example of alexa voice commands where pushy played a vital role:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/a/AVvXsEhxT3XbToO3nZFf9xlOJBPO85bpEZGct1Ral05sX5wt0ylRTTTJ_M5XY6BWFfSZNdAZK1PGnC1kJQRiw98nigxk5hJunieUPoiXBMkAtNQ4o8e7eMyuSNKv9A-gxajvfauXY_dMLaDiAdW5v-5gVWDBlQ1w8CrsXA0LWX1g1CxDiArsYlnxHl20ua37ulo&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img alt=&quot;&quot; data-original-height=&quot;432&quot; data-original-width=&quot;776&quot; height=&quot;259&quot; src=&quot;https://blogger.googleusercontent.com/img/a/AVvXsEhxT3XbToO3nZFf9xlOJBPO85bpEZGct1Ral05sX5wt0ylRTTTJ_M5XY6BWFfSZNdAZK1PGnC1kJQRiw98nigxk5hJunieUPoiXBMkAtNQ4o8e7eMyuSNKv9A-gxajvfauXY_dMLaDiAdW5v-5gVWDBlQ1w8CrsXA0LWX1g1CxDiArsYlnxHl20ua37ulo=w465-h259&quot; width=&quot;465&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both;&quot;&gt;📡 &lt;b&gt;Pushy’s Original Architecture — End-to-End Overview&lt;/b&gt;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both;&quot;&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both;&quot;&gt;Pushy was Netflix’s custom-built WebSocket proxy designed to maintain persistent, low-latency, bidirectional communication between millions of client devices and backend services.&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;p data-end=&quot;736&quot; data-start=&quot;431&quot;&gt;At a high level, Pushy accepted WebSocket connections from clients (TVs, mobile devices, etc.), maintained their sessions, and routed messages to the appropriate backend services over gRPC. However, under the hood, it contained several sophisticated components that enabled it to operate at Netflix scale.&lt;/p&gt;
&lt;p data-end=&quot;773&quot; data-start=&quot;738&quot;&gt;Here’s how it worked, step-by-step:&lt;/p&gt;&lt;p data-end=&quot;773&quot; data-start=&quot;738&quot;&gt;&lt;/p&gt;&lt;ol style=&quot;text-align: left;&quot;&gt;&lt;li&gt;&lt;b&gt;Client Connection&lt;/b&gt;&lt;/li&gt;&lt;ul&gt;&lt;li&gt;A client (e.g., a smart TV) initiates a WebSocket connection to Pushy.&lt;/li&gt;&lt;li&gt;Pushy authenticates the client and establishes a session.&lt;/li&gt;&lt;li&gt;It stores routing metadata (e.g., region, app version, device ID) for the session.&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;&lt;b&gt;Session Registration in Push Registry&lt;/b&gt;&lt;/li&gt;&lt;ul&gt;&lt;li&gt;Pushy registers the client session in a &lt;b&gt;Push Registry&lt;/b&gt;, which acts as an in-memory mapping of client sessions to backend service instances or logical partitions.&lt;/li&gt;&lt;li&gt;This registry is consulted for routing incoming and outgoing messages.&lt;/li&gt;&lt;li&gt;Initially, Netflix used &lt;b&gt;Dynomite&lt;/b&gt; (a high-availability Redis wrapper) to back this registry.&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;&lt;b&gt;Message Ingestion via Queue &amp;amp; Processor&lt;/b&gt;&lt;/li&gt;&lt;ul&gt;&lt;li&gt;Client sends a message over the WebSocket connection.&lt;/li&gt;&lt;li&gt;The message is queued in an internal &lt;b&gt;Message Queue&lt;/b&gt; to absorb bursts and prevent backpressure from backend systems.&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;&lt;b&gt;Processing via Message Processor&lt;/b&gt;&lt;/li&gt;&lt;ul&gt;&lt;li&gt;The &lt;b&gt;Message Processor&lt;/b&gt; consumes messages from the queue.&lt;/li&gt;&lt;li&gt;It applies session-specific logic, enrichment, or transformation.&lt;/li&gt;&lt;li&gt;Messages are then serialized into gRPC-compatible formats.&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;&lt;b&gt;Routing to Backend Services&lt;/b&gt;&lt;/li&gt;&lt;ul&gt;&lt;li&gt;Based on the Push Registry’s mapping and routing rules from the Control Plane, the message is routed to the correct backend service over gRPC.&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;&lt;b&gt;Outbound Messaging&lt;/b&gt;&lt;/li&gt;&lt;ul&gt;&lt;li&gt;Backend services can also push messages to clients.&lt;/li&gt;&lt;li&gt;Pushy uses the same registry to identify the client session and deliver the message over the existing WebSocket connection.&lt;/li&gt;&lt;/ul&gt;&lt;/ol&gt;&lt;div&gt;🔍 &lt;b&gt;Supporting Control Plane (External)&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Pushy constantly syncs with an external Control Plane, which provides:&lt;/div&gt;&lt;p&gt;&lt;/p&gt;&lt;div&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;Dynamic routing rules&lt;/li&gt;&lt;li&gt;Backend service discovery&lt;/li&gt;&lt;li&gt;Deployment topology&lt;/li&gt;&lt;li&gt;Traffic shaping configs&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/a/AVvXsEhdpmoXcNP2DOPNlHApapvOudwnETbOKxn6iNHBiD1-ItDXu-SupioIQCWzrw_qIUHRfxQAe3kem_5jPVa-D1rCvcPuxDv6PHOk3EMQTLEM375ajfCkS32f6BNJAOi8B8G7uaPWA2nVklDWHDhdkB6O9poDGDQWSmXvLl1M2mMeiHnUy6BRNDhFPw4qJlM&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img alt=&quot;&quot; data-original-height=&quot;283&quot; data-original-width=&quot;600&quot; height=&quot;227&quot; src=&quot;https://blogger.googleusercontent.com/img/a/AVvXsEhdpmoXcNP2DOPNlHApapvOudwnETbOKxn6iNHBiD1-ItDXu-SupioIQCWzrw_qIUHRfxQAe3kem_5jPVa-D1rCvcPuxDv6PHOk3EMQTLEM375ajfCkS32f6BNJAOi8B8G7uaPWA2nVklDWHDhdkB6O9poDGDQWSmXvLl1M2mMeiHnUy6BRNDhFPw4qJlM=w481-h227&quot; width=&quot;481&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;🛡️&lt;b&gt;What is Dynomite&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Dynomite is a &lt;b&gt;plugin layer&lt;/b&gt;&amp;nbsp;built by Netflix to transform existing, standalone storage engines like Redis or Memcached into a fully distributed, highly available, and multi‑data‑center system. Designed around concepts from Amazon’s Dynamo architecture, it enables:&lt;/div&gt;&lt;div&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;&lt;b&gt;Active‑active replication&lt;/b&gt;&amp;nbsp;across data centers&lt;/li&gt;&lt;li&gt;&lt;b&gt;Auto‑sharding&lt;/b&gt;, linear horizontal scalability&lt;/li&gt;&lt;li&gt;Configurable &lt;b&gt;consistency levels&lt;/b&gt;, &lt;b&gt;node‑warmup&lt;/b&gt;, and backup/restore support&lt;/li&gt;&lt;/ul&gt;Netflix has used Dynomite in production extensively, up to 1,000+ nodes, serving over a million operations per second at peak, with clusters reaching multiple terabytes in size.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;A standard Redis or Memcached instance is a single‑server cache. Dynomite allows Netflix to:&lt;/div&gt;&lt;div&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;Seamlessly scale to many servers and data centers&lt;/li&gt;&lt;li&gt;Replicate data synchronously across regions for &lt;b&gt;high availability&lt;/b&gt;&lt;/li&gt;&lt;li&gt;Avoid a single point of failure while maintaining low latency and consistent behavior under heavy load.&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div&gt;There is also a management tool called &lt;b&gt;Dynomite Manager&amp;nbsp;&lt;/b&gt;that helps automate tasks like node replacement and bootstrap, especially useful when deploying via AWS Auto Scaling.&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;🔁 &lt;b&gt;Scalability and Auto-Panning&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;To deal with global scale, Pushy’s initial strategy was to scale out WebSocket servers horizontally across availability zones. But this wasn’t enough, some zones still ended up with more load due to device churn and reconnect storms.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Netflix introduced auto-panning, a strategy where incoming connections would be balanced based on current server load and connection counts, not just simple round-robin DNS-based routing.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;This was a precursor to what would become a more intelligent, connection-aware load balancing strategy in the evolved architecture.&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;✅&amp;nbsp;&lt;b&gt;Summary&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Pushy wasn’t just a simple proxy but it was a&amp;nbsp;&lt;b&gt;session-aware, fault-tolerant, scalable message router&lt;/b&gt;&amp;nbsp;for real-time device communication. By combining message queuing, smart session routing, and dynamic discovery, it helped Netflix deliver seamless user experiences across millions of connected devices.&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;⚠️&lt;b&gt; Challenges with the Original Pushy Architecture&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;While Pushy’s original design served Netflix well at first, it began to &lt;b&gt;strain under the weight of scale, evolving use cases, and operational demands&lt;/b&gt;. As the number of connected devices grew into the millions, and as Pushy became central to real-time features across multiple Netflix applications, a range of technical and architectural issues surfaced.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Let’s break them down:&lt;/div&gt;&lt;div&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/div&gt;&lt;div&gt;1.&amp;nbsp;&lt;b&gt;Frequent Reconnect Storms&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Netflix devices tend to &lt;b&gt;reconnect all at once&lt;/b&gt;:&lt;/div&gt;&lt;div&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;Power outages, Wi-Fi changes, or Netflix app updates often trigger mass reconnects.&lt;/li&gt;&lt;li&gt;WebSocket servers had to handle a &lt;b&gt;spike of TLS handshakes&lt;/b&gt;, registry updates, and message backlog replays and all within seconds.&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div&gt;This led to:&lt;/div&gt;&lt;div&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;&lt;b&gt;Thundering herd problems&lt;/b&gt;&lt;/li&gt;&lt;li&gt;Sudden &lt;b&gt;CPU and memory pressure&lt;/b&gt;&amp;nbsp;on specific nodes&lt;/li&gt;&lt;li&gt;Occasional &lt;b&gt;partial outages&lt;/b&gt;&amp;nbsp;during large-scale reconnects&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div&gt;2.&amp;nbsp; &lt;b&gt;Push Registry Memory Pressure and Latency&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The &lt;b&gt;Push Registry&lt;/b&gt;, backed by &lt;b&gt;Dynomite&lt;/b&gt;, became a bottleneck:&lt;/div&gt;&lt;div&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;Every message delivery required &lt;b&gt;low-latency lookups&lt;/b&gt;&amp;nbsp;in the registry to identify active sessions.&lt;/li&gt;&lt;li&gt;With millions of devices, memory usage ballooned.&lt;/li&gt;&lt;li&gt;Dynomite’s replication overhead and Redis-like architecture couldn’t scale linearly, resulting in &lt;b&gt;lookup slowdowns and stale data&lt;/b&gt;.&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div&gt;3. &lt;b&gt;Limited Fault Isolation&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;A major issue was &lt;b&gt;no strong isolation between customers or device types&lt;/b&gt;:&lt;/div&gt;&lt;div&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;A bug or reconnection surge in one type of client (say, Android TVs) could affect Pushy performance globally.&lt;/li&gt;&lt;li&gt;Without &lt;b&gt;sharding or tenant separation&lt;/b&gt;, a misbehaving device model could overwhelm shared infrastructure.&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div&gt;4. &lt;b&gt;Insufficient Observability and Debuggability&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;The original message processor had limited metrics and retry intelligence.&lt;/li&gt;&lt;li&gt;Operators lacked visibility into &lt;b&gt;where messages got stuck&lt;/b&gt;&amp;nbsp;or &lt;b&gt;which sessions were stale&lt;/b&gt;.&lt;/li&gt;&lt;li&gt;Diagnosing delivery failures required deep dives across multiple logs and systems.&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;This made it hard to:&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;Guarantee message delivery SLAs&lt;/li&gt;&lt;li&gt;Track end-to-end latency&lt;/li&gt;&lt;li&gt;Quickly respond to production issues&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div&gt;5. &lt;b&gt;Network Topology Challenges&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Since WebSocket servers needed to stay globally distributed and session-aware:&lt;/div&gt;&lt;div&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;&lt;b&gt;Load balancing&lt;/b&gt;&amp;nbsp;at the TCP level was tricky (WebSockets aren’t natively friendly to CDN-style routing).&lt;/li&gt;&lt;li&gt;Auto-scaling had to preserve &lt;b&gt;session stickiness&lt;/b&gt;.&lt;/li&gt;&lt;li&gt;Edge nodes required careful management of memory, state, and connection churn.&lt;/li&gt;&lt;/ul&gt;6. &lt;b&gt;New Use Cases Were Outgrowing the Architecture&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Pushy started with basic notifications, but:&lt;/div&gt;&lt;div&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;Features like &lt;b&gt;real-time device sync&lt;/b&gt;, &lt;b&gt;voice input responsiveness&lt;/b&gt;&amp;nbsp;and &lt;b&gt;cross-device experiences&lt;/b&gt;&amp;nbsp;demanded &lt;b&gt;ultra-low latency&lt;/b&gt;&amp;nbsp;and &lt;b&gt;higher delivery guarantees&lt;/b&gt;.&lt;/li&gt;&lt;li&gt;The original system wasn’t optimized for &lt;b&gt;delivery retry, QoS policies, or global message routing&lt;/b&gt;.&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div&gt;🔚 &lt;b&gt;Wrapping Up Part 1: The Rise and Limits of Pushy&lt;/b&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;In this first part, we explored &lt;b&gt;why&lt;/b&gt;&amp;nbsp;Netflix needed a solution like Pushy in the first place and how it enabled seamless, real-time interactivity across devices, from second-screen controls to voice-based commands. We broke down the architecture that powered this WebSocket-based infrastructure, including its registry, message queues, and processors.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Pushy served Netflix exceptionally well for years, supporting a growing range of use cases and hundreds of millions of concurrent connections. But as we saw, scale and diversity came with operational trade-offs. From resource fragmentation to uneven scaling, the cracks began to show, not because Pushy was inadequate, but because Netflix’s needs had fundamentally evolved.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;In &lt;b&gt;Part 2&lt;/b&gt;, we’ll dive into how Netflix re-architected Pushy to meet these new demands: the innovations they introduced, how they tackled each bottleneck systematically, and what benefits the evolved system now unlocks—including hints of what might come next.&lt;/div&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://algods-cracker.blogspot.com/feeds/5203458186445549400/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://algods-cracker.blogspot.com/2025/08/netflix-tech-blog-behind-scenes-of.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7496974970329409400/posts/default/5203458186445549400'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7496974970329409400/posts/default/5203458186445549400'/><link rel='alternate' type='text/html' href='http://algods-cracker.blogspot.com/2025/08/netflix-tech-blog-behind-scenes-of.html' title='[Netflix Tech Blog] Behind the Scenes of Pushy - Netflix’s Real-Time WebSocket Proxy (Part 1)'/><author><name>Nishant Saxena</name><uri>http://www.blogger.com/profile/17860524009847591950</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjOdjS62BAEI1iMG_zd6lew4qyFGpfJhWHp0AJWQhiJvxQpSGg0AFZ5euJG7tK0D-EGQFno32hF-i1x4E2A49re_8-b9r0QHwXQ-9X_EvlAcekIjUYMaA1v6dWzDqzkBg/s220/2d230a1.jpg'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/a/AVvXsEhxT3XbToO3nZFf9xlOJBPO85bpEZGct1Ral05sX5wt0ylRTTTJ_M5XY6BWFfSZNdAZK1PGnC1kJQRiw98nigxk5hJunieUPoiXBMkAtNQ4o8e7eMyuSNKv9A-gxajvfauXY_dMLaDiAdW5v-5gVWDBlQ1w8CrsXA0LWX1g1CxDiArsYlnxHl20ua37ulo=s72-w465-h259-c" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7496974970329409400.post-8525392327113165583</id><published>2025-07-22T12:14:00.013+05:30</published><updated>2025-10-29T18:48:27.626+05:30</updated><category scheme="http://www.blogger.com/atom/ns#" term="Deliveroo"/><category scheme="http://www.blogger.com/atom/ns#" term="System Design"/><title type='text'>[Deliveroo] Design Swiggy</title><content type='html'>&lt;p&gt;Designing a highly scalable food delivery application like Swiggy or Zomato is a complex challenge that involves optimizing for scale, consistency, low latency, and real-time tracking. These apps handle millions of users, orders, and real-time delivery updates across cities, all while ensuring a seamless user experience.&lt;/p&gt;&lt;p&gt;In this post, I’ll walk through a step-by-step architectural design of a food delivery system, starting from functional and non-functional requirements to API design, services, data modeling, and finally addressing performance, availability, and consistency trade-offs.&lt;/p&gt;&lt;p&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;Requirements:&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;1. Functional requirements:&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;ol style=&quot;text-align: left;&quot;&gt;&lt;li&gt;It&#39;s an app only system.&lt;/li&gt;&lt;li&gt;Only registered users can order food.&lt;/li&gt;&lt;ul&gt;&lt;li&gt;Delivery partner registration is manual and out of scope&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;User and delivery partners need to login to order food and deliver food.&lt;/li&gt;&lt;li&gt;Delivery partners need to make themselves available to receive the delivery order.&lt;/li&gt;&lt;li&gt;Restuarants need to register and upload the menu to receive the food order.&lt;/li&gt;&lt;li&gt;Restaurants need to make themselves available to receive the order.&lt;/li&gt;&lt;li&gt;We need to minimize the:&lt;/li&gt;&lt;ul&gt;&lt;li&gt;Wait time for the users&lt;/li&gt;&lt;li&gt;Distance / Time for delivery partners to deliver the food.&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;User should be able to search the dishes, cuisines and restaurants.&lt;/li&gt;&lt;li&gt;User should be able to see the top rated nearby restaurants on home page.&lt;/li&gt;&lt;li&gt;Collect payment information from user.&lt;/li&gt;&lt;li&gt;Collect bank information from restaurant to pay them&lt;/li&gt;&lt;li&gt;Delivery Partner should be able to mark the order state like in transit, delivered&lt;/li&gt;&lt;li&gt;Users should be able to track their order.&lt;/li&gt;&lt;li&gt;Users should be able to rate restaurants and delivery partners.&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;2. Non functional requirements:&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;ol style=&quot;text-align: left;&quot;&gt;&lt;li&gt;Scalability&lt;/li&gt;&lt;ul&gt;&lt;li&gt;100 M total users.&lt;/li&gt;&lt;ul&gt;&lt;li&gt;10 M daily orders. ~ 115 orders / seconds or 1000 - 2000/second during peak hours.&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;100 K delivery partners&lt;/li&gt;&lt;li&gt;Collect delivery partner&#39;s location every 5 seconds i.e. 20 K messages / second.&lt;/li&gt;&lt;li&gt;300 K total restaurants&lt;/li&gt;&lt;li&gt;100 items per restaurant menu so total menu items are 30 M.&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;&amp;nbsp;Availability&lt;/li&gt;&lt;ul&gt;&lt;li&gt;99.99 or higher&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;Performance&lt;/li&gt;&lt;ul&gt;&lt;li&gt;Search &amp;lt; 200 ms&lt;/li&gt;&lt;li&gt;Loading home screen &amp;lt; 500 ms&lt;/li&gt;&lt;li&gt;Loading Menu &amp;lt; 500 ms&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;CP over AP&lt;/li&gt;&lt;ul&gt;&lt;li&gt;Consistency is imporant over availability here.&amp;nbsp;&lt;/li&gt;&lt;li&gt;Can&#39;t have older menu or older addresses etc.&lt;/li&gt;&lt;/ul&gt;&lt;/ol&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;Design:&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;Step 1: API design:&lt;/b&gt;&lt;/p&gt;&lt;p&gt;As usual, for the api design let&#39;s first translate our functional requirements in a sequence diagram which should look like follows:&lt;/p&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgtCsf0MJO03A_Uk1sAC3Z6zguZrK6UOBNs9LD-l-KbRideP-lfkY6njp8QrzpQ_oD9WQW3amDR-6O-ObzQmkIv4vwX6DTos8UkAVAur6gSxsHks4yGz5ZBRf9BK5PfNGzLkCRPpVUVej_4VL_WlZBbH_qRUBzoE9S6hh6oMhyphenhyphenOxukbPjX1KvcJzmHTghI/s2765/Untitled%20(1).png&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;2765&quot; data-original-width=&quot;1111&quot; height=&quot;1182&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgtCsf0MJO03A_Uk1sAC3Z6zguZrK6UOBNs9LD-l-KbRideP-lfkY6njp8QrzpQ_oD9WQW3amDR-6O-ObzQmkIv4vwX6DTos8UkAVAur6gSxsHks4yGz5ZBRf9BK5PfNGzLkCRPpVUVej_4VL_WlZBbH_qRUBzoE9S6hh6oMhyphenhyphenOxukbPjX1KvcJzmHTghI/w476-h1182/Untitled%20(1).png&quot; width=&quot;476&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;p&gt;Given the sequence diagram, we can see the need of having a bidirection connection between server &amp;amp; delivery partners and also server &amp;amp; users.&lt;/p&gt;&lt;p&gt;We now have clear APIs:&lt;/p&gt;&lt;p&gt;&lt;b&gt;Restaurants:&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;POST /restaurants&lt;/li&gt;&lt;li&gt;GET /restaurants&lt;/li&gt;&lt;li&gt;GET /restaurants/{restaurant_id}&lt;/li&gt;&lt;li&gt;PUT /restaurants/{restaurant_id}&lt;/li&gt;&lt;li&gt;POST /restaurants/login&lt;/li&gt;&lt;li&gt;POST /restaurants/{restaurant_id}/menu&lt;/li&gt;&lt;li&gt;GET /restaurants/{restaurant_id}/menu&lt;/li&gt;&lt;li&gt;POST /restaurants/{restaurant_id}/join&lt;/li&gt;&lt;li&gt;POST /restaurants/{restaurant_id}/state&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;&lt;b&gt;Delivery Partners:&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;POST /dpartners/login&lt;/li&gt;&lt;li&gt;POST /dpartners/{partner_id}/state&lt;/li&gt;&lt;li&gt;POST /dpartners/{partner_id}/location&lt;/li&gt;&lt;li&gt;POST /dpartners/{partner_id}/rate&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;&lt;b&gt;Users:&lt;/b&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;POST /users&lt;/li&gt;&lt;li&gt;POST /users/login&lt;/li&gt;&lt;li&gt;PUT /users/&amp;lt;user_id&amp;gt;&lt;/li&gt;&lt;li&gt;GET /users/&amp;lt;user_id&amp;gt;&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;&lt;b&gt;Order:&lt;/b&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;POST /orders&lt;/li&gt;&lt;li&gt;GET /orders?restaurant_id=&amp;lt;id&amp;gt;&lt;/li&gt;&lt;li&gt;GET /orders?partner_id=&amp;lt;id&amp;gt;&lt;/li&gt;&lt;li&gt;GET /orders?user_id=&amp;lt;id&amp;gt;&lt;/li&gt;&lt;li&gt;POST /orders/{order_id&amp;gt;/state&lt;/li&gt;&lt;li&gt;GET /orders/{order_id&amp;gt;&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;&lt;b&gt;Search:&lt;/b&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;GET /search/restaurants&lt;/li&gt;&lt;li&gt;GET /search/dishes&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;Step 2: Mapping functional requirments to architectural diagram:&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;1. User need to register and login to order food, Should be able to update the info&lt;/b&gt;&lt;/p&gt;&lt;p&gt;We will have a &lt;b&gt;User service&lt;/b&gt;&amp;nbsp;to serve these two requirements. we can collect the payment info while registeration. User service will use a &lt;b&gt;SQL DB&lt;/b&gt; which will have two tables:&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;ol style=&quot;text-align: left;&quot;&gt;&lt;li&gt;User:&lt;/li&gt;&lt;ul&gt;&lt;li&gt;user_id&lt;/li&gt;&lt;li&gt;user_name&lt;/li&gt;&lt;li&gt;password&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;User_Profile:&lt;/li&gt;&lt;ul&gt;&lt;li&gt;user_id&lt;/li&gt;&lt;li&gt;phone_no&lt;/li&gt;&lt;li&gt;email&lt;/li&gt;&lt;li&gt;address&lt;/li&gt;&lt;li&gt;PIN&lt;/li&gt;&lt;/ul&gt;&lt;/ol&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;div&gt;User Payment information will be sent to another service that is &lt;b&gt;Payment service&lt;/b&gt; from User Service. This service will have its own &lt;b&gt;SQL DB&lt;/b&gt; which will have following table:&lt;/div&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;ol style=&quot;text-align: left;&quot;&gt;&lt;li&gt;UserPaymentInfo:&lt;/li&gt;&lt;ul&gt;&lt;li&gt;user_id&lt;/li&gt;&lt;li&gt;credit_card&lt;/li&gt;&lt;li&gt;billing_address&lt;/li&gt;&lt;/ul&gt;&lt;/ol&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/a/AVvXsEgxfOE8Tg_yoI2Rmsiq2CKwTQwsRXKocQ2YbT4ILk7MxMr4sdKwQtIQcTdg3zsfm5lA_IyjnucxympQW63UVSu162X3e_WkXKcWwTy_iCoOp1yxacdqjajQH6l8dCRoLGvIKOxT80wowDUGHNuCz0MDISMEH1yohffHT3OgZapT1vWhSzgdE-nWRLd03Vw&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img alt=&quot;&quot; data-original-height=&quot;511&quot; data-original-width=&quot;701&quot; height=&quot;311&quot; src=&quot;https://blogger.googleusercontent.com/img/a/AVvXsEgxfOE8Tg_yoI2Rmsiq2CKwTQwsRXKocQ2YbT4ILk7MxMr4sdKwQtIQcTdg3zsfm5lA_IyjnucxympQW63UVSu162X3e_WkXKcWwTy_iCoOp1yxacdqjajQH6l8dCRoLGvIKOxT80wowDUGHNuCz0MDISMEH1yohffHT3OgZapT1vWhSzgdE-nWRLd03Vw=w427-h311&quot; width=&quot;427&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;2. Restaurant registration, login, upload menu and update these details:&lt;/b&gt;&lt;/p&gt;&lt;p&gt;We will have a separate service say &lt;b&gt;Restaurant Service &lt;/b&gt;which will have its own &lt;b&gt;SQL DB&lt;/b&gt;. It will have following tables:&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;ol style=&quot;text-align: left;&quot;&gt;&lt;li&gt;Restaurants&lt;/li&gt;&lt;ul&gt;&lt;li&gt;id&lt;/li&gt;&lt;li&gt;user_name&lt;/li&gt;&lt;li&gt;password&lt;/li&gt;&lt;li&gt;name&lt;/li&gt;&lt;li&gt;location&lt;/li&gt;&lt;li&gt;address&lt;/li&gt;&lt;li&gt;pin&lt;/li&gt;&lt;li&gt;IsActive&lt;/li&gt;&lt;li&gt;menu_id&lt;/li&gt;&lt;li&gt;avg_rating&lt;/li&gt;&lt;li&gt;num_rating&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;RestaurantMenu&lt;/li&gt;&lt;ul&gt;&lt;li&gt;id&lt;/li&gt;&lt;li&gt;restaurant_id&lt;/li&gt;&lt;li&gt;name&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;RestaurantMenuItem&lt;/li&gt;&lt;ul&gt;&lt;li&gt;id&lt;/li&gt;&lt;li&gt;menu_id&lt;/li&gt;&lt;li&gt;item_id&lt;/li&gt;&lt;li&gt;price&lt;/li&gt;&lt;li&gt;IsAvailable&lt;/li&gt;&lt;li&gt;avg_rating&lt;/li&gt;&lt;li&gt;num_rating&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;MenuItem&lt;/li&gt;&lt;ul&gt;&lt;li&gt;id&lt;/li&gt;&lt;li&gt;Name&lt;/li&gt;&lt;li&gt;Description&lt;/li&gt;&lt;/ul&gt;&lt;/ol&gt;&lt;div&gt;The payment info will be sent to &lt;b&gt;Payment Service&lt;/b&gt; to store the bank details. Payment Service will have another table in its &lt;b&gt;SQL DB&lt;/b&gt; to store this info:&lt;/div&gt;&lt;div&gt;&lt;ol style=&quot;text-align: left;&quot;&gt;&lt;li&gt;RestaurantPaymentInfo&lt;/li&gt;&lt;ul&gt;&lt;li&gt;restaurant_id&lt;/li&gt;&lt;li&gt;bank_details&lt;/li&gt;&lt;/ul&gt;&lt;/ol&gt;The menu and restaurant metadata will be sent to a new &lt;b&gt;Search service&lt;/b&gt;. Search service will store this metadata in it&#39;s &lt;b&gt;Elastic Search&lt;/b&gt; database.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;p&gt;&lt;b&gt;3. Restaurants need to make themselves available to receive the order.:&lt;/b&gt;&lt;/p&gt;&lt;p&gt;Restaurant admin simply call Restarant service. Restaurant service will mark the restaurant&#39;s &lt;i&gt;IsActive&lt;/i&gt; as True. The diagram for both 2 and 3 FRs is as below:&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/a/AVvXsEhYpMSEkRXFmC0YmPhnDXOo353lZTx57usmJq-ohCknRbXBEFp88V3hbueqCF6BFOG3Y_U9x8naZFu3DTubrZE_91FJaxUSEpWtglXjLjlxR0Dkx39vIYXAiVzOOW9r9K1Sl4rslYHL_T_iJDFIMaLF3VZq4CE0lxSzkF39cXXkWf3lUFIQfZ0BXgUXXBA&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img alt=&quot;&quot; data-original-height=&quot;771&quot; data-original-width=&quot;721&quot; height=&quot;576&quot; src=&quot;https://blogger.googleusercontent.com/img/a/AVvXsEhYpMSEkRXFmC0YmPhnDXOo353lZTx57usmJq-ohCknRbXBEFp88V3hbueqCF6BFOG3Y_U9x8naZFu3DTubrZE_91FJaxUSEpWtglXjLjlxR0Dkx39vIYXAiVzOOW9r9K1Sl4rslYHL_T_iJDFIMaLF3VZq4CE0lxSzkF39cXXkWf3lUFIQfZ0BXgUXXBA=w538-h576&quot; width=&quot;538&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;4. Delivery Partners need to login and make themeselves available to recieve the orders:&lt;/b&gt;&lt;/p&gt;&lt;p&gt;To support delivery partners, we will have another service say &lt;b&gt;DPartner Service&lt;/b&gt;. This has its own &lt;b&gt;SQL DB&lt;/b&gt; to store the delivery partners info. Here are the tables:&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;ol style=&quot;text-align: left;&quot;&gt;&lt;li&gt;DeliveryPartner&amp;nbsp;&lt;/li&gt;&lt;ul&gt;&lt;li&gt;id&lt;/li&gt;&lt;li&gt;name&lt;/li&gt;&lt;li&gt;user_name&lt;/li&gt;&lt;li&gt;password&lt;/li&gt;&lt;li&gt;rating&lt;/li&gt;&lt;li&gt;is_active&lt;/li&gt;&lt;li&gt;num_deliveries&lt;/li&gt;&lt;/ul&gt;&lt;/ol&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;Deliver Partners can make themselves available using &lt;b&gt;DPartner Service&lt;/b&gt;. It will just change the state in the DeliveryPartner table. Once they made themselves available, DPartner service will create a bidireactional connection using &lt;i&gt;web socket&lt;/i&gt;. This will have following benefits:&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;Delivery Partners need to send location very frequently so it will remove the overhead of TCP connection every time.&lt;/li&gt;&lt;li&gt;Server can also push messages like pick_up order etc.&amp;nbsp;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;To record these location we will use a new service say &lt;b&gt;Location Service&lt;/b&gt;. DPartner service will continue to &lt;i&gt;queue&lt;/i&gt; these locations to Location service. We will use a write performant &lt;b&gt;LSM tree based NoSQL&lt;/b&gt; &lt;b&gt;DB &lt;/b&gt;to store these locations updates. This will contain partner_id and location like lat and long and we continue to update this record until the partner is active. Here is the schema of the collection:&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;partner_id&lt;/li&gt;&lt;li&gt;latitude&lt;/li&gt;&lt;li&gt;longitude&lt;/li&gt;&lt;li&gt;order_id&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;We are going to have another service say &lt;b&gt;ConnectionManager Service&lt;/b&gt;. It will store user_id and connection_id in a highly performant KeyValue pair DB like redis so once the WSS connection is established, DPartner service will call ConnectionManager service to store this info. For now it is not required but it will be required when server push some mesage to delivery partner or user to know which connection to use.&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/a/AVvXsEiwIEzBKnnp8b2Dk7ahyp0Cu56qmrfSOgIHOMBMn8KlUNQRmwsaAz1eflcK19aBcFJOfyRPqH85Y63FOW1ZWyDggx5ZkGMGKGKE7xnotySYTfKUhyWPqs41LQypikUTWnV8yJmmfQam3vDMW8PMYqQG398-ZCDAPdxm9GAA5Q_rbUIKfN3euBrUx7mLC3U&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img alt=&quot;&quot; data-original-height=&quot;771&quot; data-original-width=&quot;1214&quot; height=&quot;379&quot; src=&quot;https://blogger.googleusercontent.com/img/a/AVvXsEiwIEzBKnnp8b2Dk7ahyp0Cu56qmrfSOgIHOMBMn8KlUNQRmwsaAz1eflcK19aBcFJOfyRPqH85Y63FOW1ZWyDggx5ZkGMGKGKE7xnotySYTfKUhyWPqs41LQypikUTWnV8yJmmfQam3vDMW8PMYqQG398-ZCDAPdxm9GAA5Q_rbUIKfN3euBrUx7mLC3U=w599-h379&quot; width=&quot;599&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;5. When user order the food, system assign the best possible Delivery Partner:&lt;/p&gt;&lt;p&gt;As mention in the functional requirement, user should get the order in minimum time and delivery partner must travel as less as possible.&lt;/p&gt;&lt;p&gt;To order the food, we will have a new service say &lt;b&gt;Order service&lt;/b&gt;. Order service will have its own &lt;b&gt;SQL DB&lt;/b&gt;. Here are the tables:&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;ol style=&quot;text-align: left;&quot;&gt;&lt;li&gt;Order&lt;/li&gt;&lt;ul&gt;&lt;li&gt;id&lt;/li&gt;&lt;li&gt;user_id&lt;/li&gt;&lt;li&gt;restaurant_id&lt;/li&gt;&lt;li&gt;payment_id&lt;/li&gt;&lt;li&gt;dpartner_id&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;OrderDetails:&lt;/li&gt;&lt;ul&gt;&lt;li&gt;order_id&lt;/li&gt;&lt;li&gt;restaurant_menu_item_id&lt;/li&gt;&lt;/ul&gt;&lt;/ol&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;For the order to complete, the payment will be done using &lt;b&gt;Payment Service&lt;/b&gt;. Payment Service will connect with credit card company and restaurant&#39;s bank to complete the payment using &lt;b&gt;third party payment service&lt;/b&gt;.&lt;/p&gt;&lt;p&gt;Once the payment is done, order service queue the message to &lt;b&gt;Notification service&lt;/b&gt; and Notification service push the notification to Retaurant. Restaurant then fetch the order details from order service and set the state of order as approved by calling Order Service API.&lt;/p&gt;&lt;p&gt;To match the delivery partner, we will have a new service &lt;b&gt;Matching Service&lt;/b&gt;. Let&#39;s see what it does to match the delivery partner to an order.&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;Matching service send the user&#39;s and restaurant&#39;s location to Location service&lt;/li&gt;&lt;li&gt;Location service finds all the closed available delivery partners by drawing a circle of 2 - 3 KMs. Restaurant could be the center of the circle.&lt;/li&gt;&lt;li&gt;Location service now sends the triplet {partner_location, restaurant_location, user_location} to a third party service.&lt;/li&gt;&lt;li&gt;Third party service sends the ETA for every every triplet.&lt;/li&gt;&lt;li&gt;Location service then send the {partner_id, ETA} to matching service.&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;&lt;p&gt;&lt;i&gt;Matching service&lt;/i&gt; will then match the partner with order based on ETAs and other criterias. Once matched, &lt;i&gt;Matching service&lt;/i&gt; will send the &lt;i&gt;Location service&lt;/i&gt; {partner_id, order_id} and Location Service will save order_id corresponding to partner_id to indicate that delivery partner is serving an order.&lt;/p&gt;&lt;p&gt;Now Matching Service will send {order_id, partner_id} to Order Service which will update the partner_id corresponding to order_id.&amp;nbsp;&lt;/p&gt;&lt;p&gt;Once the partner_id is saved, Order Service queue another message with order info like restaurant location, user location and order_id to &lt;i&gt;Notification service&lt;/i&gt; which pushes these details to delivery partners.&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;6. User should be able to track their orders&lt;/b&gt;&lt;/p&gt;&lt;p&gt;Once the User reaches to order tracking page, user app creates an &lt;i&gt;WSS &lt;/i&gt;connection with a new service say &lt;b&gt;Order Tracking Service&lt;/b&gt;. Here is the flow:&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;ol style=&quot;text-align: left;&quot;&gt;&lt;li&gt;Once the order is confirmed and delivery partner is assigned, it queues the order_info like order_id, user_id, state, dpartner_id etc to Order Tracking Service.&lt;/li&gt;&lt;li&gt;Whenever restaurant update order state using Order Service API, Order Service also queue this order_info to Order Tracking Service.&lt;/li&gt;&lt;li&gt;Location Service when it sees that and order_id is attached the delivery partner id, then it queues the order_id, location to Order Tracking Service.&lt;/li&gt;&lt;li&gt;Order Tracking Service maintains redis cache to store this info.&amp;nbsp;&lt;/li&gt;&lt;li&gt;When user creates an WSS with Order Tracking Service, it also sends it to Connection Manager Service to store it.&lt;/li&gt;&lt;li&gt;When Order Tracking Service receives any messages, it first checks with Connection Manager to get the connection id and use the connection id to send the update to User.&amp;nbsp;&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;So this is architectural diagram for order placement and tracking:&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/a/AVvXsEjAGVBf_W6bUGm2hBMWB2kRIAmZKW8-pN1OudNQ8fWDv2I46YZ3EGFHObcf_yEkipcNRjN2um11reatxmmbjxdixSHKRLX9f68CsxneK3gCPMjVpy62--_bp5qvZXYsx_GE5m_6qam9yU-APIw5ISYVcuj7IU7xuoFQfuUyUTal02sIZ4gXu_rpdhQuPck&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img alt=&quot;&quot; data-original-height=&quot;911&quot; data-original-width=&quot;1390&quot; height=&quot;398&quot; src=&quot;https://blogger.googleusercontent.com/img/a/AVvXsEjAGVBf_W6bUGm2hBMWB2kRIAmZKW8-pN1OudNQ8fWDv2I46YZ3EGFHObcf_yEkipcNRjN2um11reatxmmbjxdixSHKRLX9f68CsxneK3gCPMjVpy62--_bp5qvZXYsx_GE5m_6qam9yU-APIw5ISYVcuj7IU7xuoFQfuUyUTal02sIZ4gXu_rpdhQuPck=w606-h398&quot; width=&quot;606&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;7. Delivery partner should be able to mark the order state:&lt;p&gt;&lt;/p&gt;&lt;p&gt;Delivery partners can simply call Order service to mark the order state. With this, this is the compelet flow of Orders:&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/a/AVvXsEhay-uOlfB_K59ZzTTCOCoXkQx11Jd_Xx0JqkJ4ud2vWjjO6nU4jK96vvyzrOOzcs9syLYEMFaeAbnF2qYjEs_tGEPnLqzARRRQ-n4yKpThLwufnN2hy6hG9qX4abzx5B78HS6qNTwtYDufj99gNJSHtoL8FUDi0zkmJeQcjU5pTYfSdwAJqmh9GQWO9X4&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img alt=&quot;&quot; data-original-height=&quot;911&quot; data-original-width=&quot;1390&quot; height=&quot;388&quot; src=&quot;https://blogger.googleusercontent.com/img/a/AVvXsEhay-uOlfB_K59ZzTTCOCoXkQx11Jd_Xx0JqkJ4ud2vWjjO6nU4jK96vvyzrOOzcs9syLYEMFaeAbnF2qYjEs_tGEPnLqzARRRQ-n4yKpThLwufnN2hy6hG9qX4abzx5B78HS6qNTwtYDufj99gNJSHtoL8FUDi0zkmJeQcjU5pTYfSdwAJqmh9GQWO9X4=w590-h388&quot; width=&quot;590&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;8. User should be able to rate delivery partners and restaurants:&lt;/p&gt;&lt;p&gt;For this FR we can have another service say &lt;b&gt;Rating service&lt;/b&gt;. It will have its own &lt;b&gt;SQL DB&lt;/b&gt;. We can have different tables or we can use the same table for both restaurants and delivery partners with one more column say type but I am going to use different tables.&lt;/p&gt;&lt;p&gt;Both tables have the same schema:&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;ol style=&quot;text-align: left;&quot;&gt;&lt;li&gt;RestaurantRating&lt;/li&gt;&lt;ul&gt;&lt;li&gt;user_id&lt;/li&gt;&lt;li&gt;restaurant_id&lt;/li&gt;&lt;li&gt;rating&lt;/li&gt;&lt;li&gt;created_at&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;DPartnerRating&lt;/li&gt;&lt;ul&gt;&lt;li&gt;user_id&lt;/li&gt;&lt;li&gt;dpartner_id&lt;/li&gt;&lt;li&gt;rating&lt;/li&gt;&lt;li&gt;created_at&lt;/li&gt;&lt;/ul&gt;&lt;/ol&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;In this way we can also restrict same user to rate restaurants or delivery Partners multiple times. Now we also show restaurant&#39;s and delivery partner&#39;s rating to users. I know we are not handling NFRs for now but I am handling little performance right now. Otherwise to show details of restaurants or partners we need to make 2 calls (restaurant/dpartner and rating). We are going to use &lt;b&gt;timer jobs at Restaurant Service and DPartner Service&lt;/b&gt; which will run at scheduled interval say every 1/2/4/8 hours and fetch the data from Rating service using &lt;i&gt;created_at &lt;/i&gt;field and then calculate rating and save it in their own DB.&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/a/AVvXsEho9NeB_6InRMRMd3WJFzaG3GfnJb0CWB7QlWyqzAigpkKKTYKWRV9VEZACW0X-elmbbm5cls_ilFxgtkBzCMvSCQ9Xt0tTeABQA1uTC77kYvkFRXkW1FFQljzhqmJ5Bg_ykzx9_Cyr4U3dYXW-_qmNgceSwOM67h_SOGrizWRTTTy7uDmrOqL1zwX6Jdw&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img alt=&quot;&quot; data-original-height=&quot;911&quot; data-original-width=&quot;621&quot; height=&quot;568&quot; src=&quot;https://blogger.googleusercontent.com/img/a/AVvXsEho9NeB_6InRMRMd3WJFzaG3GfnJb0CWB7QlWyqzAigpkKKTYKWRV9VEZACW0X-elmbbm5cls_ilFxgtkBzCMvSCQ9Xt0tTeABQA1uTC77kYvkFRXkW1FFQljzhqmJ5Bg_ykzx9_Cyr4U3dYXW-_qmNgceSwOM67h_SOGrizWRTTTy7uDmrOqL1zwX6Jdw=w388-h568&quot; width=&quot;388&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;9. User should be able to search restaurants and menu items.&lt;/b&gt;&lt;/p&gt;&lt;p&gt;For this we have already a &lt;b&gt;Search Service&lt;/b&gt; which is using &lt;b&gt;Elastic Search&lt;/b&gt;. Restaurant Service is already pushing the data there on onboarding or updates.&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/a/AVvXsEj2yWKUOUU-tm5jCbngOXKKDrqr9eMQxXt-y-Bg_Rf_5rGLrOk6JO8oeE63dkXgBCl8rDSicIyvwCkSCXieVy5k0AETuf9kjFyTyf27pjDjtuDcB61jOzmqAsDe-o519Llv7bEg3JeyofV1MeKcAszI2zTp6kQddpkSMbe3XvXp-iN7-NuhiGmAFYtaJd4&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img alt=&quot;&quot; data-original-height=&quot;911&quot; data-original-width=&quot;660&quot; height=&quot;467&quot; src=&quot;https://blogger.googleusercontent.com/img/a/AVvXsEj2yWKUOUU-tm5jCbngOXKKDrqr9eMQxXt-y-Bg_Rf_5rGLrOk6JO8oeE63dkXgBCl8rDSicIyvwCkSCXieVy5k0AETuf9kjFyTyf27pjDjtuDcB61jOzmqAsDe-o519Llv7bEg3JeyofV1MeKcAszI2zTp6kQddpkSMbe3XvXp-iN7-NuhiGmAFYtaJd4=w338-h467&quot; width=&quot;338&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;/p&gt;&lt;/div&gt;&lt;p&gt;&lt;/p&gt;&lt;/div&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;10. User should be able to see the top rated nearby restaurants on home page:&lt;/b&gt;&lt;/p&gt;&lt;p&gt;This is &lt;i&gt;little tricky &lt;/i&gt;but we will deal with it during NFRs handling for now, you can see we have every data available at &lt;b&gt;Restaurant Service&lt;/b&gt; DB and we can fetch this from its DB only and show it to user.&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/a/AVvXsEiIznE3eJcb-FMTP2bQAtQDx1AoJIJkfXMUMVuBhvm94YTTN-jP_xfXOX0DEyK8blQbYeFukhHSB0dgVxR_Pvss-2nnUqZbbeedqK4FoltcmDdYlbPEDuaLO0jGwc32ZIePmwu668Re7ZJJ-8xEZ5h4_Wg1o3WU4zmPRjPAu7u-p00XpCXCqlppvHaCHJk&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img alt=&quot;&quot; data-original-height=&quot;911&quot; data-original-width=&quot;660&quot; height=&quot;565&quot; src=&quot;https://blogger.googleusercontent.com/img/a/AVvXsEiIznE3eJcb-FMTP2bQAtQDx1AoJIJkfXMUMVuBhvm94YTTN-jP_xfXOX0DEyK8blQbYeFukhHSB0dgVxR_Pvss-2nnUqZbbeedqK4FoltcmDdYlbPEDuaLO0jGwc32ZIePmwu668Re7ZJJ-8xEZ5h4_Wg1o3WU4zmPRjPAu7u-p00XpCXCqlppvHaCHJk=w409-h565&quot; width=&quot;409&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;Step 3: Mapping non functional requirments to architectural diagram:&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;1. Scalability:&lt;/b&gt;&lt;/p&gt;&lt;p&gt;For achieving the scalability we need to have multiple instances of each service and also replicas of DBs.&lt;/p&gt;&lt;p&gt;&lt;b&gt;2. Availabilty:&lt;/b&gt;&lt;/p&gt;&lt;p&gt;We have already achieved it using multiple instances and replicas of DBs,&lt;/p&gt;&lt;p&gt;&lt;b&gt;3. Performance:&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;a. Search &amp;lt; 200 ms&lt;/b&gt;&lt;/p&gt;&lt;p&gt;For search performance we already are using Elastic search which should serve the purpose. If required we can add additional details like rating, state in the Elasic Search.&lt;/p&gt;&lt;p&gt;&lt;b&gt;b. Home page load &amp;lt; 500 ms&lt;/b&gt;&lt;/p&gt;&lt;p&gt;Here we need to show the Top rated nearby restaurants around the user location but as of now it is not possible as we are storing lat and long.&amp;nbsp;&lt;/p&gt;&lt;p&gt;We can use &lt;a href=&quot;https://en.wikipedia.org/wiki/Geohash&quot; target=&quot;_blank&quot;&gt;Geohash &lt;/a&gt;here to divide the earch into geo cells. Now these geo cell ids will be stored in the Restaurant DB as per the restaurant&#39;s locations. That means we are going to add a new table &lt;b&gt;RestaurantLocation table&lt;/b&gt;&amp;nbsp;in the&amp;nbsp;&lt;b&gt;Restaurant DB&lt;/b&gt;. Here is the schema:&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;geo_cell_id&lt;/li&gt;&lt;li&gt;restaurant_id&lt;/li&gt;&lt;li&gt;restaurant_name&lt;/li&gt;&lt;li&gt;restaurant_rating&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;Now the circle which we are drawing centered at User&#39;s location can have around 3 or 4 geo cells. Here is how the flow looks like for getting the nearby restaurants:&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;Get the geo cell id as per the user&#39;s location.&lt;/li&gt;&lt;li&gt;Get all the geo cell ids which is covered by 2 KM radius circle&lt;/li&gt;&lt;li&gt;Now the query to DB will be something like SELECT * from Location where geo_cell_ids in [list of geo cells]&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;To make this query efficient, we can partition this table based on geo_cell_id.&amp;nbsp;&lt;/p&gt;&lt;p&gt;If it is still required we can &lt;i&gt;cache top restaurnts of geo_cell_ids in the Redis&lt;/i&gt;.&lt;/p&gt;&lt;p&gt;*&lt;i&gt; For matching Delivery Partners we will use the same approach of geo hash and a column &quot;geo_hash_id&quot; will be added&amp;nbsp; to Location DB. Just like what we did in &lt;a href=&quot;https://algods-cracker.blogspot.com/2024/10/design-uber.html&quot; target=&quot;_blank&quot;&gt;design of uber.&lt;/a&gt;&lt;/i&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;c. Menu load &amp;lt; 500 ms&lt;/b&gt;&lt;/p&gt;&lt;p&gt;There are four tables; Restaurants, RestarantMenu, RestaurantMenuItem and MenuItems, we need to join if we want to get the whole menu which is making this very inefficient. What we can do is maintain another table, &lt;b&gt;RestaurantMenuCache &lt;/b&gt;which will just have following fields:&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;restaurant_id&lt;/li&gt;&lt;li&gt;menu_blob&lt;/li&gt;&lt;li&gt;last_updated_at&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;We can partition based on &lt;i&gt;restaurant_ids &lt;/i&gt;but on &lt;i&gt;range based&lt;/i&gt; method to make it more efficient.&lt;/div&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;d. CP over AP&lt;/b&gt;&lt;/p&gt;&lt;p&gt;We are already using SQL DB where consistency is required.&lt;/p&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;In this post, we methodically designed a scalable, consistent, and performant food delivery application from scratch. We identified critical services, database designs, WebSocket communication for real-time updates, and employed techniques like Geohashing for efficient geo-based queries.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;We also mapped our non-functional requirements (NFRs) like scalability, performance, availability, and consistency across the architecture, ensuring that the system remains robust even at 100M users and 10M daily orders scale.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;This design is a strong foundation. In a real-world scenario, we can extend it further by adding observability, security layers, fallback mechanisms and cost optimizations.&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://algods-cracker.blogspot.com/feeds/8525392327113165583/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://algods-cracker.blogspot.com/2025/07/design-swiggy.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7496974970329409400/posts/default/8525392327113165583'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7496974970329409400/posts/default/8525392327113165583'/><link rel='alternate' type='text/html' href='http://algods-cracker.blogspot.com/2025/07/design-swiggy.html' title='[Deliveroo] Design Swiggy'/><author><name>Nishant Saxena</name><uri>http://www.blogger.com/profile/17860524009847591950</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjOdjS62BAEI1iMG_zd6lew4qyFGpfJhWHp0AJWQhiJvxQpSGg0AFZ5euJG7tK0D-EGQFno32hF-i1x4E2A49re_8-b9r0QHwXQ-9X_EvlAcekIjUYMaA1v6dWzDqzkBg/s220/2d230a1.jpg'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgtCsf0MJO03A_Uk1sAC3Z6zguZrK6UOBNs9LD-l-KbRideP-lfkY6njp8QrzpQ_oD9WQW3amDR-6O-ObzQmkIv4vwX6DTos8UkAVAur6gSxsHks4yGz5ZBRf9BK5PfNGzLkCRPpVUVej_4VL_WlZBbH_qRUBzoE9S6hh6oMhyphenhyphenOxukbPjX1KvcJzmHTghI/s72-w476-h1182-c/Untitled%20(1).png" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7496974970329409400.post-4620906558033997513</id><published>2025-06-20T17:33:00.003+05:30</published><updated>2025-07-03T01:07:21.428+05:30</updated><category scheme="http://www.blogger.com/atom/ns#" term="Netflix Tech Blog"/><title type='text'>[Netflix Tech Blog] Inside Netflix&#39;s Ads Event Engine: A Deep Dive (Part 2)</title><content type='html'>&lt;p&gt;&lt;/p&gt;&lt;p data-end=&quot;618&quot; data-start=&quot;295&quot;&gt;In &lt;a class=&quot;cursor-pointer&quot; data-end=&quot;321&quot; data-start=&quot;298&quot; href=&quot;https://algods-cracker.blogspot.com/2025/06/netflix-tech-blog-inside-netflixs-ads.html&quot; rel=&quot;noopener&quot; target=&quot;_blank&quot;&gt;Part 1&lt;/a&gt;, we explored how Netflix moved from a bloated token model to a more elegant, scalable architecture using a centralized &lt;strong data-end=&quot;476&quot; data-start=&quot;441&quot;&gt;Metadata Registry Service (MRS)&lt;/strong&gt;. That shift allowed Netflix to scale its ad event tracking system across vendors, while keeping client payloads small and observability high.&lt;/p&gt;
&lt;p data-end=&quot;648&quot; data-start=&quot;620&quot;&gt;But Netflix wasn’t done yet.&lt;/p&gt;&lt;b&gt;Netflix built it&#39;s own Ad tech platform: Ad Decision Server:&lt;/b&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;Netflix made a strategic bet to build an in-house advertising technology platform, including its own &lt;i&gt;&lt;b&gt;Ad Decision Server (ADS)&lt;/b&gt;&lt;/i&gt;. This was about more than just cost or speed, it was about &lt;i&gt;control, flexibility, and future-proofing&lt;/i&gt;. It actually began with a clear inventory of business and technical use cases:&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;In-house frequency capping&lt;/li&gt;&lt;li&gt;Pricing and billing for impression events&lt;/li&gt;&lt;li&gt;Robust campaign reporting and analytics&lt;/li&gt;&lt;li&gt;Scalable, multi-vendor tracking via event handler&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;But this&amp;nbsp;Ad Event Processing Pipeline needed a significant overhaul to:&lt;/div&gt;&lt;div&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;Match or exceed the capabilities of existing third-party solutions&lt;/li&gt;&lt;li&gt;Rapidly support new ad formats like Pause/Display ads&lt;/li&gt;&lt;li&gt;Enable advanced features like frequency capping and billing events&lt;/li&gt;&lt;li&gt;Consolidate and centralize telemetry pipelines across use cases&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;Road to a versatile and unified pipeline:&lt;/b&gt;&lt;/p&gt;&lt;div&gt;&lt;p&gt;Netflix recognized future ad types like &lt;strong data-end=&quot;63&quot; data-start=&quot;42&quot;&gt;Pause/Display ads&lt;/strong&gt;&amp;nbsp;that would introduce variant telemetry. That means the upstream telemetry pipelines might vary, but downstream use‑cases remain largely consistent.&amp;nbsp;&lt;/p&gt;&lt;p&gt;So what is upstream and what is downstream in this Netflix event processing context:&lt;/p&gt;&lt;p&gt;&lt;b&gt;&lt;span data-end=&quot;43&quot; data-is-only-node=&quot;&quot; data-start=&quot;0&quot;&gt;Upstream&amp;nbsp;&lt;/span&gt;&lt;span data-end=&quot;43&quot; data-is-only-node=&quot;&quot; data-start=&quot;0&quot;&gt;(&lt;/span&gt;&lt;span data-end=&quot;43&quot; data-is-only-node=&quot;&quot; data-start=&quot;0&quot;&gt;Producers of telemetry / Events&lt;/span&gt;&lt;span data-end=&quot;43&quot; data-is-only-node=&quot;&quot; data-start=&quot;0&quot;&gt;)&lt;/span&gt;:&lt;/b&gt;&amp;nbsp;This refers to the systems and sources that generate or send ad-related telemetry data into the event processing pipeline.&lt;/p&gt;&lt;p&gt;Example of upstream in this context:&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Devices (Phones, TVs, Browsers)&lt;/li&gt;&lt;li&gt;Different Ad Types (eg. Video Ads, Display Ads, Pause Ads)&lt;/li&gt;&lt;li&gt;Ad Media Players&lt;/li&gt;&lt;li&gt;Ad Servers&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;These upstream systems send events like:&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;Ad Started&lt;/li&gt;&lt;li&gt;Ad Paused&lt;/li&gt;&lt;li&gt;Ad Clicked&lt;/li&gt;&lt;li&gt;Token for ad metadata&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;These system may:&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;Use different formats&lt;/li&gt;&lt;li&gt;Have different logging behavior&lt;/li&gt;&lt;li&gt;Be customized per ad type or region&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;&lt;span data-end=&quot;43&quot; data-is-only-node=&quot;&quot; data-start=&quot;0&quot;&gt;Downstream&amp;nbsp;&lt;/span&gt;&lt;span data-end=&quot;43&quot; data-is-only-node=&quot;&quot; data-start=&quot;0&quot;&gt;(&lt;/span&gt;&lt;span data-end=&quot;43&quot; data-is-only-node=&quot;&quot; data-start=&quot;0&quot;&gt;Consumers of processed data&lt;/span&gt;&lt;span data-end=&quot;43&quot; data-is-only-node=&quot;&quot; data-start=&quot;0&quot;&gt;)&lt;/span&gt;:&lt;/b&gt;&amp;nbsp;This refers to the systems that consume the processed ad events for various business use cases.&lt;/p&gt;&lt;div&gt;&lt;p&gt;Example of downstream in this context:&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Frquency capping service&lt;/li&gt;&lt;li&gt;Billing and pricing engine&lt;/li&gt;&lt;li&gt;Reporting dashboards for advertisers&lt;/li&gt;&lt;li&gt;Anlytical systems (like Druid)&lt;/li&gt;&lt;li&gt;Ad session generators&lt;/li&gt;&lt;li&gt;External vendor tracking&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;These downstream consumers:&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;Expect standardized, enriched, reliable event data&lt;/li&gt;&lt;li&gt;Rely on consistent schema&lt;/li&gt;&lt;li&gt;Need latency and correctness guarantees&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;p&gt;&lt;/p&gt;&lt;/div&gt;&lt;p&gt;So &quot;upstream telemetry pipelines might vary, but downstream use‑cases remain largely consistent&quot; means:&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;Even if ad events come from diverse sources, with different formats and behaviors (upstream variation),&lt;/li&gt;&lt;li&gt;The core processing needs (like billing, metrics, sessionization, and reporting) remain the same (downstream consistency).&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;Based on that they outline a vision:&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;&lt;strong data-end=&quot;43&quot; data-is-only-node=&quot;&quot; data-start=&quot;0&quot;&gt;Centralized ad event collection service&lt;/strong&gt; that:&lt;/li&gt;&lt;ul&gt;&lt;li&gt;Decrypts tokens&lt;/li&gt;&lt;li&gt;Enriches metadata (via the Registry)&lt;/li&gt;&lt;li&gt;Hashes identifiers&lt;/li&gt;&lt;li&gt;Publishes a &lt;strong data-end=&quot;37&quot; data-start=&quot;12&quot;&gt;unified data contract&lt;/strong&gt;&lt;span data-end=&quot;37&quot; data-start=&quot;12&quot;&gt;,&lt;/span&gt;&amp;nbsp;agnostic of ad type or server&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;&lt;span class=&quot;relative -mx-px my-[-0.2rem] rounded px-px py-[0.2rem] transition-colors duration-100 ease-in-out&quot;&gt;&lt;strong data-end=&quot;17&quot; data-is-only-node=&quot;&quot; data-start=&quot;0&quot;&gt;All consumers&lt;/strong&gt; (for reporting, capping, billing)/read from this central service, ensuring clean separation and consistency.&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;&lt;p&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;Building Ad sessions &amp;amp; Downstream Pipelines:&lt;/b&gt;&lt;/p&gt;&lt;p&gt;A key architectural decision was &lt;i&gt;&quot;Sessionization happens downstream, not in the ingestion flow&quot;&lt;/i&gt; but what does that mean? Lets break it down:&lt;/p&gt;&lt;p&gt;&lt;b&gt;Ingestion flow (Upstream):&lt;/b&gt; This is the intial (real time) path&amp;nbsp;where raw ad telemetry events are ingested into the system, like:&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;&amp;nbsp;Ad started playing&lt;/li&gt;&lt;li&gt;User clicked&lt;/li&gt;&lt;li&gt;25% of video watched&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;&lt;p&gt;These events are lightweight, real time and are not yet grouped into a meaningful session. Think of it as raw, granular events flying into Kafka or a central service.&lt;/p&gt;&lt;p&gt;&lt;b&gt;Sessionization (Downstream Processing):&lt;/b&gt;&amp;nbsp;This is a batch or stream aggregation process where the system:&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;Looks at multiple ad events from the same ad playback session&lt;/li&gt;&lt;li&gt;Groups them together&lt;/li&gt;&lt;li&gt;Creates a &lt;strong data-end=&quot;877&quot; data-start=&quot;830&quot;&gt;meaningful structure called an &quot;Ad Session&quot;&lt;/strong&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;An Ad session might include:&lt;/p&gt;&lt;div&gt;&lt;p&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;When did the ad start and end&lt;/li&gt;&lt;li&gt;What was the user&#39;s interaction (viewed / clicked / skipped)&lt;/li&gt;&lt;li&gt;Was it complete or partial view&lt;/li&gt;&lt;li&gt;What was pricing and vendor context&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;So &lt;i&gt;&quot;Sessionization happens downstream, not in the ingestion flow&quot;&lt;/i&gt; means:&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;The ingestion system just collects and stores raw events quickly and reliably.&lt;/li&gt;&lt;li&gt;The heavier work of aggregating these into a complete session (sessionization) happens later, in the downstream pipeline where there is:&lt;/li&gt;&lt;ul&gt;&lt;li&gt;More time&lt;/li&gt;&lt;li&gt;Access to more context&lt;/li&gt;&lt;li&gt;Better processiong capabilities&lt;/li&gt;&lt;/ul&gt;&lt;/ul&gt;&lt;div&gt;&lt;b&gt;Why it was required?&lt;/b&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;&lt;b&gt;Separation of concerns:&lt;/b&gt; Ingestion stays fast and simple; sessionization logic is centralized and easier to iterate on.&lt;/li&gt;&lt;li&gt;&lt;b&gt;Extensibility:&lt;/b&gt; You can add new logic to sessionization without touching ingestion.&lt;/li&gt;&lt;li&gt;&lt;b&gt;Scalability:&lt;/b&gt; Real time pipelines stay light; heavy lifting is done downstream.&lt;/li&gt;&lt;li&gt;&lt;b&gt;Consistency:&lt;/b&gt; One place to define and compute what an &quot;ad session&quot; means.&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjZcOAtGP13JmVDUeyXGZXXw2NXextUao-Y9Py3JFpEWxGQAqaqmIz9iFBzZSZmpLs7fOcJarTWakB3eLf-tGPEdX3zteoaut3Kb6cZ7wz7LRM7oTx-j7PKF1LIQutTJMpEH1yKJ7HumXeuq2yeYrIzrNd8dzFnqGePOrosMCWE2Ge39XdrIU7s08IkbZk/s1024/NetflixSessionization.png&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;1024&quot; data-original-width=&quot;1024&quot; height=&quot;320&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjZcOAtGP13JmVDUeyXGZXXw2NXextUao-Y9Py3JFpEWxGQAqaqmIz9iFBzZSZmpLs7fOcJarTWakB3eLf-tGPEdX3zteoaut3Kb6cZ7wz7LRM7oTx-j7PKF1LIQutTJMpEH1yKJ7HumXeuq2yeYrIzrNd8dzFnqGePOrosMCWE2Ge39XdrIU7s08IkbZk/s320/NetflixSessionization.png&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;br /&gt;&lt;/div&gt;They also built out a &lt;b&gt;suite of downstream systems&lt;/b&gt;:&lt;/div&gt;&lt;div&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;Frequency Capping&lt;/li&gt;&lt;li&gt;Ads Metrics&amp;nbsp;&lt;/li&gt;&lt;li&gt;Ads Sessionizer&lt;/li&gt;&lt;li&gt;Ads Event Handler&amp;nbsp;&lt;/li&gt;&lt;li&gt;Billing and revenue jobs&lt;/li&gt;&lt;li&gt;Reporting &amp;amp; Metrics APIs&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;Final Architecture of Ad Event Processing:&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjxZa7xB0KKsgwk-YnZORU5SeVy4iTCaDylPlpQCU5t-ZHb_RbnF3XNNkU6g784n2AasiSUyR67d4DBm3U5bZZUlbBEHOfRpp76gxf3tvsSdsnetJfuJNM_cdgf_RxKAV4o_r1ougG2a1QttLcYxbt_ctLYyX0ih7DaKGSfnYUA1tKwiaXk6ltPQ8Q9BCM/s1633/NetflixFinalAdsFlow.drawio.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;611&quot; data-original-width=&quot;1633&quot; height=&quot;241&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjxZa7xB0KKsgwk-YnZORU5SeVy4iTCaDylPlpQCU5t-ZHb_RbnF3XNNkU6g784n2AasiSUyR67d4DBm3U5bZZUlbBEHOfRpp76gxf3tvsSdsnetJfuJNM_cdgf_RxKAV4o_r1ougG2a1QttLcYxbt_ctLYyX0ih7DaKGSfnYUA1tKwiaXk6ltPQ8Q9BCM/w645-h241/NetflixFinalAdsFlow.drawio.png&quot; width=&quot;645&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;div style=&quot;text-align: center;&quot;&gt;&lt;b&gt;Ad Event Processing Pipeline&lt;/b&gt;&lt;/div&gt;&lt;div style=&quot;text-align: center;&quot;&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/div&gt;&lt;div style=&quot;text-align: left;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style=&quot;text-align: left;&quot;&gt;Here is the breakdown of the flow:&lt;/div&gt;&lt;div style=&quot;text-align: left;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style=&quot;text-align: left;&quot;&gt;&lt;ol style=&quot;text-align: left;&quot;&gt;&lt;li&gt;&lt;b&gt;Netflix Player -&amp;gt; Netflix Edge:&lt;/b&gt;&lt;/li&gt;&lt;ul&gt;&lt;li&gt;The client (TV, browser, mobile app) plays an ad and emits telemetry (e.g., impression, quartile events).&lt;/li&gt;&lt;li&gt;These events are forwarded to Netflix’s &lt;strong data-end=&quot;911&quot; data-start=&quot;903&quot;&gt;Edge&lt;/strong&gt; infrastructure, ensuring low-latency ingestion globally.&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;&lt;b&gt;Telemetry Infrastructure:&lt;/b&gt;&lt;/li&gt;&lt;ul&gt;&lt;li&gt;Once events hit the edge, they are processed by a &lt;strong data-end=&quot;1091&quot; data-start=&quot;1063&quot;&gt;Telemetry Infrastructure&lt;/strong&gt; service.&lt;/li&gt;&lt;li&gt;This layer is responsible for:&lt;/li&gt;&lt;ul&gt;&lt;li&gt;Validating events&lt;/li&gt;&lt;li&gt;Attaching metadata (e.g., device info, playback context)&lt;/li&gt;&lt;li&gt;Interfacing with the &lt;strong data-end=&quot;1271&quot; data-start=&quot;1242&quot;&gt;Metadata Registry Service&lt;/strong&gt; (MRS) to enrich events with ad context based on token references.&lt;/li&gt;&lt;/ul&gt;&lt;/ul&gt;&lt;li&gt;&lt;b&gt;Kafka:&lt;/b&gt;&lt;/li&gt;&lt;ul&gt;&lt;li&gt;Events are published to a &lt;strong data-end=&quot;1425&quot; data-start=&quot;1410&quot;&gt;Kafka topic&lt;/strong&gt;.&lt;/li&gt;&lt;li&gt;This decouples ingestion from downstream processing and allows multiple consumers to operate in parallel.&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;&lt;b&gt;Ads Event Publisher:&lt;/b&gt;&lt;/li&gt;&lt;ul&gt;&lt;li&gt;This is the &lt;strong data-end=&quot;1617&quot; data-start=&quot;1586&quot;&gt;central orchestration layer&lt;/strong&gt;.&lt;/li&gt;&lt;li&gt;It performs:&lt;/li&gt;&lt;ul&gt;&lt;li&gt;Token decryption&lt;/li&gt;&lt;li&gt;Metadata enrichment (macros, tracking URLs)&lt;/li&gt;&lt;li&gt;Identifier hashing&lt;/li&gt;&lt;li&gt;Emits a &lt;strong data-end=&quot;1778&quot; data-start=&quot;1738&quot;&gt;unified and extensible data contract&lt;/strong&gt; for downstream use&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;Also writes select events to the &lt;strong data-end=&quot;1851&quot; data-start=&quot;1833&quot;&gt;data warehouse&lt;/strong&gt; to support &lt;strong data-end=&quot;1900&quot; data-start=&quot;1863&quot;&gt;Ads Finance and Billing workflows&lt;/strong&gt;.&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;&lt;b&gt;Kafka -&amp;gt; Downstream Consumers:&lt;/b&gt;&lt;/li&gt;&lt;ul&gt;&lt;li&gt;Once enriched, the events are republished to Kafka for the following &lt;strong data-end=&quot;2030&quot; data-start=&quot;2017&quot;&gt;consumers&lt;/strong&gt;:&lt;/li&gt;&lt;ul&gt;&lt;li&gt;&lt;b&gt;Frequency Capping:&lt;/b&gt;&lt;/li&gt;&lt;ul&gt;&lt;li&gt;Records ad views in a &lt;strong data-end=&quot;2112&quot; data-start=&quot;2087&quot;&gt;Key-Value abstraction&lt;/strong&gt; layer.&lt;/li&gt;&lt;li&gt;Helps enforce logic like “don’t show the same ad more than 3 times per day per user.”&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;&lt;b&gt;Ads Metrics Processor:&lt;/b&gt;&lt;/li&gt;&lt;ul&gt;&lt;li&gt;Processes delivery metrics (e.g., impressions, completion rates).&lt;/li&gt;&lt;li&gt;Writes real-time data to &lt;strong data-end=&quot;2347&quot; data-start=&quot;2338&quot;&gt;Druid&lt;/strong&gt; for interactive analytics.&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;&lt;b&gt;Ads Sessionizer:&lt;/b&gt;&lt;/li&gt;&lt;ul&gt;&lt;li&gt;Groups related telemetry events into &lt;strong data-end=&quot;2458&quot; data-start=&quot;2443&quot;&gt;ad sessions&lt;/strong&gt; (e.g., full playback window).&lt;/li&gt;&lt;li&gt;Feeds both &lt;strong data-end=&quot;2520&quot; data-start=&quot;2502&quot;&gt;data warehouse&lt;/strong&gt; and &lt;strong data-end=&quot;2556&quot; data-start=&quot;2525&quot;&gt;offline vendor integrations&lt;/strong&gt;.&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;&lt;b&gt;Ads Event Handler:&lt;/b&gt;&lt;/li&gt;&lt;ul&gt;&lt;li&gt;Responsible for &lt;strong data-end=&quot;2661&quot; data-start=&quot;2607&quot;&gt;firing external tracking pixels and HTTP callbacks&lt;/strong&gt; to third-party vendors (like Nielsen, DoubleVerify).&lt;/li&gt;&lt;li&gt;Ensures vendors get event pings per their integration needs.&lt;/li&gt;&lt;/ul&gt;&lt;/ul&gt;&lt;/ul&gt;&lt;li&gt;&lt;b&gt;Analytics &amp;amp; Offline Exchange:&lt;/b&gt;&lt;/li&gt;&lt;ul&gt;&lt;li&gt;The sessionized and aggregated data from the warehouse is used for:&lt;/li&gt;&lt;ul&gt;&lt;li&gt;Offline measurement&lt;/li&gt;&lt;li&gt;Revenue analytics&lt;/li&gt;&lt;li&gt;Advertiser reporting&lt;/li&gt;&lt;/ul&gt;&lt;/ul&gt;&lt;/ol&gt;&lt;div&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;Benefits of design:&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;table style=&quot;width: 100%;&quot;&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th style=&quot;text-align: left; width: 30%;&quot;&gt;Principle&lt;/th&gt;
&lt;th style=&quot;text-align: left; width: 70%;&quot;&gt;Implementation&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Separation of concerns&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Ingestion (Telemetry Infra) ≠ Enrichment (Publisher) ≠ Consumption (Consumers)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Scalability&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Kafka enables multi-consumer, partitioned scaling&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Extensibility&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Central Ads Event Publisher emits a unified schema&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Observability&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Real-time metrics via Druid; sessionized logs via warehouse&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Partner-friendly&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Vendor hooks via Event Handler + Offline exchange&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;&lt;/div&gt;&lt;div style=&quot;text-align: left;&quot;&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/div&gt;&lt;p&gt;&lt;/p&gt;&lt;/div&gt;&lt;div&gt;By centralizing sessionization and metadata logic, Netflix ensures that:&lt;/div&gt;&lt;div&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;Client-side logic remains lightweight and stable&lt;/li&gt;&lt;li&gt;Backend systems remain flexible to change and easy to audit&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;Few clarificatons:&lt;/b&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;1. What is the Key-Value (KV) abstraction in Frequency Capping?&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;In Netflix’s Ad Event Processing Pipeline, frequency capping is the mechanism that ensures a user doesn’t see the same ad (or type of ad) more than a specified number of times e.g., “&lt;i&gt;Don’t show Ad X to user Y more than 3 times a day.&lt;/i&gt;”&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;To implement this efficiently, Netflix uses a &lt;b&gt;Key-Value abstraction&lt;/b&gt;, which is essentially a highly scalable key-value store optimized for fast reads and writes.&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;How it works:&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;Key:&amp;nbsp;&amp;nbsp;A unique identifier for the &quot;audience + ad + context&quot;&lt;/li&gt;&lt;ul&gt;&lt;li&gt;Example:&amp;nbsp;&lt;span style=&quot;background-color: #cccccc;&quot;&gt;user_id:ad_id:date&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;Value:&amp;nbsp;A counter or timestamp that tracks views or interactions&lt;/li&gt;&lt;ul&gt;&lt;li&gt;Example:&amp;nbsp;&lt;span style=&quot;background-color: #cccccc;&quot;&gt;{count: 2, last_shown: 2025-06-20T12:15:30}&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/ul&gt;&lt;div&gt;Let&#39;s understand it by example:&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;table style=&quot;width: 668.667px;&quot;&gt;&lt;thead&gt;&lt;tr&gt;&lt;th style=&quot;text-align: left; width: 196.792px;&quot;&gt;Key&lt;/th&gt;&lt;th style=&quot;text-align: left; width: 461.875px;&quot;&gt;Value&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;user123:ad789:2025-06-20&lt;/td&gt;&lt;td&gt;{ count: 2, last_shown: 12:15 }&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;user123:ad456:2025-06-20&lt;/td&gt;&lt;td&gt;{ count: 1, last_shown: 10:04 }&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;When a new ad event comes in:&lt;/div&gt;&lt;div&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;Netflix looks up the key&lt;/li&gt;&lt;li&gt;Checks the &lt;i&gt;count&lt;/i&gt;&lt;/li&gt;&lt;li&gt;If under the cap (e.g., 3), they allow it and increment the counter&lt;/li&gt;&lt;li&gt;If at or above cap, the ad is &lt;strong data-end=&quot;1256&quot; data-start=&quot;1233&quot;&gt;skipped or replaced&lt;/strong&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;&lt;b&gt;Why &quot;Abstraction&quot;?&lt;/b&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Netflix may use multiple underlying KV stores (like Redis, Cassandra, or custom services), but &lt;strong data-end=&quot;1428&quot; data-start=&quot;1385&quot;&gt;abstracts it behind a unified interface&lt;/strong&gt; so:&lt;/div&gt;&lt;div&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;Ad engineers don’t worry about implementation&lt;/li&gt;&lt;li&gt;Multiple ad systems can share the same cap logic&lt;/li&gt;&lt;li&gt;It can scale across regions and millions of users&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;&lt;b&gt;Benefits:&lt;/b&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;table style=&quot;width: 668.667px;&quot;&gt;&lt;thead&gt;&lt;tr&gt;&lt;th style=&quot;text-align: left; width: 196.792px;&quot;&gt;Feature&lt;/th&gt;&lt;th style=&quot;text-align: left; width: 461.875px;&quot;&gt;Why it matters&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;b&gt;Speed&lt;/b&gt;&lt;/td&gt;&lt;td&gt;Real-time lookups for every ad play&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;strong&gt;Scalability&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;Handles millions of users per day&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;b&gt;Flexibility&lt;/b&gt;&lt;/td&gt;&lt;td&gt;Supports different capping rules&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;b&gt;Multi-tenancy&lt;/b&gt;&lt;/td&gt;&lt;td&gt;Can cap by user, device, campaign, etc.&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;2. What is Druid and why it is getting used here?&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;a href=&quot;https://druid.apache.org/&quot; target=&quot;_blank&quot;&gt;Apache Druid&lt;/a&gt; is a real-time analytics database designed for low-latency, high-concurrency, OLAP-style queries on large volumes of streaming or batch data.&lt;/div&gt;&lt;div&gt;It’s built for interactive dashboards, slice-and-dice analytics, and fast aggregations over time-series or event data.&lt;/div&gt;&lt;div&gt;Think of it as a high-performance hybrid of a data warehouse and a time-series database.&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Netflix uses Druid in the &lt;strong data-end=&quot;726&quot; data-start=&quot;701&quot;&gt;Ads Metrics Processor&lt;/strong&gt; and &lt;strong data-end=&quot;750&quot; data-start=&quot;731&quot;&gt;Analytics layer&lt;/strong&gt;. Here’s what it powers:&lt;/div&gt;&lt;div&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;&lt;b&gt;Streaming Ad Delivery Metrics&lt;/b&gt;&lt;/li&gt;&lt;ul&gt;&lt;li&gt;As ads are played, Netflix captures events like:&lt;/li&gt;&lt;ul&gt;&lt;li&gt;Impressions&lt;/li&gt;&lt;li&gt;Quartile completions (25%, 50%, etc.)&lt;/li&gt;&lt;li&gt;Clicks, errors, skips&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;These events are streamed and aggregated in near-real-time via Flink or similar streaming processors&lt;/li&gt;&lt;li&gt;Druid ingests these metrics for &lt;strong data-end=&quot;1113&quot; data-start=&quot;1089&quot;&gt;interactive querying.&lt;/strong&gt;&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;&lt;b&gt;Advertiser Reporting and Internal Dashboards&lt;/b&gt;&lt;/li&gt;&lt;ul&gt;&lt;li&gt;Ad operations teams and partners want to know:&lt;/li&gt;&lt;ul&gt;&lt;li&gt;&quot;How many impressions did Ad X get in Region Y yesterday?&quot;&lt;/li&gt;&lt;li&gt;&quot;What&#39;s the completion rate for Campaign Z?&quot;&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;These queries are run against Druid and &lt;strong data-end=&quot;1400&quot; data-start=&quot;1374&quot;&gt;return in milliseconds&lt;/strong&gt;, even over billions of records&lt;/li&gt;&lt;/ul&gt;&lt;/ul&gt;&lt;b&gt;Why Nerflix uses Druid (instead of just a data warehouse like Redshift or BigQuery)?&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&amp;nbsp;&lt;/div&gt;&lt;table style=&quot;width: 668.667px;&quot;&gt;&lt;thead&gt;&lt;tr&gt;&lt;th style=&quot;text-align: left; width: 196.792px;&quot;&gt;Feature&lt;/th&gt;&lt;th style=&quot;text-align: left; width: 461.875px;&quot;&gt;Why it matters for Netflix Ads&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;b&gt;Real-time ingestion&lt;/b&gt;&lt;/td&gt;&lt;td&gt;Metrics appear in dashboards within seconds of the event&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;b&gt;Sub-second queries&lt;/b&gt;&lt;/td&gt;&lt;td&gt;Advertiser reports and internal dashboards need speed&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;b&gt;High concurrency&lt;/b&gt;&lt;/td&gt;&lt;td&gt;Supports thousands of parallel queries from internal tools&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;b&gt;Flexible aggregation&lt;/b&gt;&lt;/td&gt;&lt;td&gt;Group by ad_id, region, time, device_type, etc. instantly&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;b&gt;Schema-on-read &amp;amp; roll-ups&lt;/b&gt;&lt;/td&gt;&lt;td&gt;Druid efficiently stores pre-aggregated data for common metrics&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;Conclusion:&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;As Netflix shifted toward building its own advertising technology platform, the Ads Event Processing Pipeline evolved into a thoughtfully architected, modular telemetry platform capable of handling diverse ad formats, scaling globally, and meeting the demands of both real-time analytics and long-term reporting.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;This transformation was not just about infrastructure, but about &lt;strong data-end=&quot;590&quot; data-start=&quot;571&quot;&gt;platformization&lt;/strong&gt;:&lt;/div&gt;&lt;div&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;A centralized &lt;strong data-end=&quot;627&quot; data-start=&quot;608&quot;&gt;event publisher&lt;/strong&gt; that abstracts complexity.&lt;/li&gt;&lt;li&gt;A &lt;strong data-end=&quot;677&quot; data-start=&quot;659&quot;&gt;unified schema&lt;/strong&gt; that serves a wide range of downstream consumers.&lt;/li&gt;&lt;li&gt;A clean &lt;strong data-end=&quot;764&quot; data-start=&quot;738&quot;&gt;separation of concerns&lt;/strong&gt; that allows rapid innovation in ad types without touching backend logic.&lt;/li&gt;&lt;li&gt;&lt;strong data-end=&quot;873&quot; data-start=&quot;844&quot;&gt;Observability and control&lt;/strong&gt;, made possible through systems like Druid and the Metadata Registry Service.&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;With this evolution, Netflix ensured:&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;&lt;strong data-end=&quot;1007&quot; data-start=&quot;992&quot;&gt;Scalability&lt;/strong&gt;: Handling billions of ad events across regions and devices&lt;/li&gt;&lt;li&gt;&lt;strong data-end=&quot;1080&quot; data-start=&quot;1069&quot;&gt;Agility&lt;/strong&gt;: Enabling quick integration of new ad formats like Pause/Display Ads&lt;/li&gt;&lt;li&gt;&lt;strong data-end=&quot;1173&quot; data-start=&quot;1152&quot;&gt;Partner alignment&lt;/strong&gt;: Supporting vendor integrations with minimal friction&lt;/li&gt;&lt;li&gt;&lt;strong data-end=&quot;1253&quot; data-start=&quot;1230&quot;&gt;Business confidence&lt;/strong&gt;: Powering frequency capping, billing, and reporting with precision&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;Here is the original &lt;a href=&quot;https://netflixtechblog.com/behind-the-scenes-building-a-robust-ads-event-processing-pipeline-e4e86caf9249&quot; target=&quot;_blank&quot;&gt;Netflix blog&lt;/a&gt;.&amp;nbsp;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;p&gt;&lt;/p&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://algods-cracker.blogspot.com/feeds/4620906558033997513/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://algods-cracker.blogspot.com/2025/06/netflix-tech-blog-inside-netflixs-ads_20.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7496974970329409400/posts/default/4620906558033997513'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7496974970329409400/posts/default/4620906558033997513'/><link rel='alternate' type='text/html' href='http://algods-cracker.blogspot.com/2025/06/netflix-tech-blog-inside-netflixs-ads_20.html' title='[Netflix Tech Blog] Inside Netflix&#39;s Ads Event Engine: A Deep Dive (Part 2)'/><author><name>Nishant Saxena</name><uri>http://www.blogger.com/profile/17860524009847591950</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjOdjS62BAEI1iMG_zd6lew4qyFGpfJhWHp0AJWQhiJvxQpSGg0AFZ5euJG7tK0D-EGQFno32hF-i1x4E2A49re_8-b9r0QHwXQ-9X_EvlAcekIjUYMaA1v6dWzDqzkBg/s220/2d230a1.jpg'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjZcOAtGP13JmVDUeyXGZXXw2NXextUao-Y9Py3JFpEWxGQAqaqmIz9iFBzZSZmpLs7fOcJarTWakB3eLf-tGPEdX3zteoaut3Kb6cZ7wz7LRM7oTx-j7PKF1LIQutTJMpEH1yKJ7HumXeuq2yeYrIzrNd8dzFnqGePOrosMCWE2Ge39XdrIU7s08IkbZk/s72-c/NetflixSessionization.png" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7496974970329409400.post-6349033419261768746</id><published>2025-06-16T20:12:00.000+05:30</published><updated>2025-06-16T20:12:00.814+05:30</updated><category scheme="http://www.blogger.com/atom/ns#" term="Netflix Tech Blog"/><title type='text'>[Netflix Tech Blog] Inside Netflix&#39;s Ads Event Engine: A Deep Dive (Part 1)</title><content type='html'>&lt;p&gt;As Netflix steps into the ad-supported streaming world, its engineering backbone must operate with the same level of scale, reliability, and precision that powers its core viewing experience. But building a system that can track billions of ad events like impressions, clicks, quartile views, across diverse devices and ad partners is anything but trivial.&lt;/p&gt;
&lt;p data-end=&quot;1035&quot; data-start=&quot;588&quot;&gt;In this &lt;b&gt;&lt;i&gt;two-part &lt;/i&gt;&lt;/b&gt;series, I’ll dissect the architecture behind Netflix’s Ads Event Processing Pipeline, inspired by their tech blog. Part 1 focuses on the early phase, from ad request initiation to the evolution of encrypted tokens and the eventual need for a Metadata Registry Service. You&#39;ll see how Netflix tackled key design challenges such as bandwidth optimization, cross-device compatibility, vendor flexibility, and observability at scale.&lt;/p&gt;&lt;p data-end=&quot;1035&quot; data-start=&quot;588&quot;&gt;If you&#39;re interested in distributed systems, real-time telemetry, or just want to peek behind the curtain of Netflix’s ad tech, you’re in the right place.&lt;/p&gt;
&lt;p data-end=&quot;1525&quot; data-start=&quot;1511&quot;&gt;Let’s dive in!&lt;/p&gt;&lt;p data-end=&quot;1525&quot; data-start=&quot;1511&quot;&gt;&lt;b&gt;The Initial System (Pilot) At a Glance:&lt;/b&gt;&lt;/p&gt;&lt;p data-end=&quot;1525&quot; data-start=&quot;1511&quot;&gt;When a Netflix-supported device is ready to show an ad, it doesn’t pick an ad on its own. Instead, the system goes through the following high-level steps:&amp;nbsp;&lt;/p&gt;&lt;p data-end=&quot;1525&quot; data-start=&quot;1511&quot;&gt;&lt;/p&gt;&lt;ol style=&quot;text-align: left;&quot;&gt;&lt;li&gt;&lt;b&gt;Client Ad Request:&lt;/b&gt; The device (TV/mobile/browser) sends a request to Netflix’s &lt;strong data-end=&quot;794&quot; data-start=&quot;779&quot;&gt;Ads Manager&lt;/strong&gt; service when it reaches an ad slot.&lt;/li&gt;&lt;li&gt;&lt;b&gt;VAST Response from Microsoft Ad Server:&lt;/b&gt; Ads Manager forwards this request to the Microsoft’s ad server, which returns a &lt;strong data-end=&quot;1007&quot; data-start=&quot;995&quot;&gt;VAST XML&lt;/strong&gt;. This contains the actual ad media URL, tracking pixels, and metadata like vendor IDs and macros.&lt;/li&gt;&lt;li&gt;&lt;b&gt;Encrypted Token Created:&lt;/b&gt;&amp;nbsp;Instead of sending this raw VAST data to the device, Ads Manager:&lt;/li&gt;&lt;ul&gt;&lt;li&gt;Extracts relevant metadata (e.g., tracking URLs, event triggers, vendor IDs)&lt;/li&gt;&lt;li&gt;Encodes it using &lt;strong data-end=&quot;1326&quot; data-start=&quot;1314&quot;&gt;protobuf&lt;/strong&gt;&lt;/li&gt;&lt;li&gt;&lt;span data-end=&quot;1326&quot; data-start=&quot;1314&quot;&gt;Encrypts it into a compact structure called a &lt;span data-end=&quot;1387&quot; data-start=&quot;1378&quot;&gt;&lt;b&gt;token&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span data-end=&quot;1326&quot; data-start=&quot;1314&quot;&gt;&lt;span data-end=&quot;1387&quot; data-start=&quot;1378&quot;&gt;Sends this token along with the actual &lt;span data-end=&quot;1448&quot; data-start=&quot;1432&quot;&gt;&lt;b&gt;ad video URL&lt;/b&gt;&lt;/span&gt; to the device&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;&lt;b&gt;Ad Playback and Event Emission:&lt;/b&gt; As the ad plays, the device emits &lt;strong data-end=&quot;1562&quot; data-start=&quot;1542&quot;&gt;telemetry events&lt;/strong&gt; like &lt;i&gt;impression&lt;/i&gt;, &lt;i&gt;firstQuartile&lt;/i&gt;, &lt;i&gt;click &lt;/i&gt;etc., attaching the token to each event.&lt;/li&gt;&lt;li&gt;&lt;b&gt;Event Processing via Kafka:&lt;/b&gt; These events are queued in &lt;strong data-end=&quot;1726&quot; data-start=&quot;1717&quot;&gt;Kafka&lt;/strong&gt;, where the &lt;strong data-end=&quot;1759&quot; data-start=&quot;1738&quot;&gt;Ads Event Handler&lt;/strong&gt; service reads them, decrypts the token, interprets the metadata, and fires the appropriate tracking URLs.&lt;/li&gt;&lt;/ol&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/a/AVvXsEi9s-Mk63MhF5AiEPgSV56ue6vzBmyX2TVQSt6g2DAtwC5wGHhYznWF8Oyt4Oglc3jTOUx3tApLI2VetDNz1HgCn8bCDUrZZNJ_G4KXsaiTOGQKo2Pov-KUA85-GA2Ea8gO9vvbbrxkaecZiRECzxYGS2-lMjqe2Z3L302jAShGWq9qp3FOM4mipUXLhZw&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img alt=&quot;&quot; data-original-height=&quot;552&quot; data-original-width=&quot;1009&quot; height=&quot;331&quot; src=&quot;https://blogger.googleusercontent.com/img/a/AVvXsEi9s-Mk63MhF5AiEPgSV56ue6vzBmyX2TVQSt6g2DAtwC5wGHhYznWF8Oyt4Oglc3jTOUx3tApLI2VetDNz1HgCn8bCDUrZZNJ_G4KXsaiTOGQKo2Pov-KUA85-GA2Ea8gO9vvbbrxkaecZiRECzxYGS2-lMjqe2Z3L302jAShGWq9qp3FOM4mipUXLhZw=w606-h331&quot; width=&quot;606&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;b&gt;Ad Events flow&lt;/b&gt;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;&lt;b&gt;What is &lt;a href=&quot;https://en.wikipedia.org/wiki/Video_Ad_Serving_Template&quot; target=&quot;_blank&quot;&gt;VAST&lt;/a&gt;?&lt;/b&gt;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;VAST stands for Video Ad Serving Template. It’s an XML-based standard developed by the IAB (Interactive Advertising Bureau) to standardize the delivery of video ads from ad servers to video players (like Netflix&#39;s video player). In simpler terms:&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both;&quot;&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;VAST is a template that tells the video player:&lt;/li&gt;&lt;li&gt;What ad to play&lt;/li&gt;&lt;li&gt;Where to find it&lt;/li&gt;&lt;li&gt;How to track it (e.g., impressions, clicks, view progress)&lt;/li&gt;&lt;/ul&gt;&lt;b&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both;&quot;&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/div&gt;Key Parts of a VAST Response:&lt;/b&gt;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both;&quot;&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;&lt;b&gt;Ad Media URL&lt;/b&gt;&lt;/li&gt;&lt;ul&gt;&lt;li&gt;Link to the video file&lt;/li&gt;&lt;li&gt;The player will use this to stream the ad.&lt;/li&gt;&lt;/ul&gt;&lt;/ul&gt;&lt;div&gt;&lt;pre style=&quot;background: rgb(247, 249, 250); border-radius: 3px; box-sizing: border-box; line-height: 1.6; margin-bottom: 1em; margin-top: 0px; overflow: auto; padding: 10px 15px;&quot;&gt;&lt;span style=&quot;box-sizing: border-box;&quot;&gt;&lt;span face=&quot;SFMono-Regular, Consolas, Liberation Mono, Menlo, Courier, monospace&quot; style=&quot;color: #263238;&quot;&gt;&lt;span style=&quot;text-wrap-mode: wrap;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;&amp;lt;MediaFile delivery=&quot;progressive&quot; type=&quot;video/mp4&quot; width=&quot;640&quot; height=&quot;360&quot;&amp;gt;
    https://adserver.com/path/to/ad.mp4
&amp;lt;/MediaFile&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;ul data-end=&quot;1216&quot; data-start=&quot;1032&quot; style=&quot;text-align: left;&quot;&gt;&lt;li&gt;&lt;b&gt;Tracking Events&lt;/b&gt;&lt;/li&gt;&lt;ul&gt;&lt;li&gt;URLs the player should &quot;ping&quot; (via HTTP GET) when certain things happen:&lt;/li&gt;&lt;ul&gt;&lt;li&gt;Impression (ad started)&lt;/li&gt;&lt;li&gt;FirstQuartile (25% watched)&lt;/li&gt;&lt;li&gt;Midpoint (50% watched)&lt;/li&gt;&lt;li&gt;ThirdQuartile (75% watched)&lt;/li&gt;&lt;li&gt;Complete (100%)&lt;/li&gt;&lt;li&gt;Click (User clicked the ad)&lt;/li&gt;&lt;/ul&gt;&lt;/ul&gt;&lt;/ul&gt;&lt;pre style=&quot;background: rgb(247, 249, 250); border-radius: 3px; box-sizing: border-box; line-height: 1.6; margin-bottom: 1em; margin-top: 0px; overflow: auto; padding: 10px 15px;&quot;&gt;&lt;span face=&quot;SFMono-Regular, Consolas, Liberation Mono, Menlo, Courier, monospace&quot; style=&quot;color: #263238; font-size: x-small;&quot;&gt;&lt;span style=&quot;text-wrap-mode: wrap;&quot;&gt;&amp;lt;TrackingEvents&amp;gt;
  &amp;lt;Tracking event=&quot;impression&quot;&amp;gt;https://track.com/imp&amp;lt;/Tracking&amp;gt;
  &amp;lt;Tracking event=&quot;firstQuartile&quot;&amp;gt;https://track.com/q1&amp;lt;/Tracking&amp;gt;
  ...
&amp;lt;/TrackingEvents&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;&lt;div&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;&lt;b&gt;Click Tracking&lt;/b&gt;&lt;/li&gt;&lt;ul&gt;&lt;li&gt;URL to notify when the user clicks the ad.&lt;/li&gt;&lt;li&gt;Destination URL (where user is taken on click).&lt;/li&gt;&lt;/ul&gt;&lt;/ul&gt;&lt;pre style=&quot;background: rgb(247, 249, 250); border-radius: 3px; box-sizing: border-box; line-height: 1.6; margin-bottom: 1em; margin-top: 0px; overflow: auto; padding: 10px 15px;&quot;&gt;&lt;span face=&quot;SFMono-Regular, Consolas, Liberation Mono, Menlo, Courier, monospace&quot; style=&quot;color: #263238; font-size: x-small;&quot;&gt;&lt;span style=&quot;text-wrap-mode: wrap;&quot;&gt;&amp;lt;VideoClicks&amp;gt;
  &amp;lt;ClickThrough&amp;gt;https://brand.com&amp;lt;/ClickThrough&amp;gt;
  &amp;lt;ClickTracking&amp;gt;https://track.com/click&amp;lt;/ClickTracking&amp;gt;
&amp;lt;/VideoClicks&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;&lt;div&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;&lt;b&gt;Companion Ads (Optional)&lt;/b&gt;&lt;/li&gt;&lt;ul&gt;&lt;li&gt;Static banner or rich media that shows alongside the video ad&lt;/li&gt;&lt;/ul&gt;&lt;/ul&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;Why VAST?&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;table style=&quot;width: 668.667px;&quot;&gt;&lt;thead&gt;&lt;tr&gt;&lt;th style=&quot;text-align: left;&quot; width=&quot;30%&quot;&gt;Purpose&lt;/th&gt;&lt;th style=&quot;text-align: left;&quot; width=&quot;70%&quot;&gt;How it helps&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;Standardization&lt;/td&gt;&lt;td&gt;All ad servers speak the same language to video players&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Tracking&lt;/td&gt;&lt;td&gt;Advertisers know when/how their ads were shown&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Flexibility&lt;/td&gt;&lt;td&gt;Supports linear, companion, and interactive video ad formats&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Easy integration&lt;/td&gt;&lt;td&gt;Netflix could plug in with Microsoft without building a custom API&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;p&gt;&lt;/p&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;Why Netflix chose protobuf and not Json:&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;&lt;b&gt;Token size matters on client devices:&lt;/b&gt; Protobuf is highly compact, small tokens means less overhead.&amp;nbsp;For example, a JSON payload that’s 1 KB might only be 100–200 bytes in protobuf.&lt;/li&gt;&lt;li&gt;&lt;b&gt;Performance:&lt;/b&gt; Ad events are high volume (billions per day).&amp;nbsp;Protobuf parsing is much faster than JSON, both on backend and client.&lt;/li&gt;&lt;li&gt;&lt;b&gt;Encryption efficiency:&lt;/b&gt;&amp;nbsp;Netflix encrypted the protobuf payload to create the token. Encrypting a compact binary blob is &lt;span data-end=&quot;1746&quot; data-start=&quot;1724&quot;&gt;faster and lighter&lt;/span&gt; than encrypting JSON text.&lt;/li&gt;&lt;li&gt;&lt;b&gt;Schema Evolution and Compatibility:&lt;/b&gt; Protobuf supports versioning, optional/required fields and backward/forward compatibility. That means Netflix could &lt;span data-end=&quot;2060&quot; data-start=&quot;2027&quot;&gt;evolve the ad metadata schema&lt;/span&gt; without breaking clients or backend systems. JSON lacks this.&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;&lt;br /&gt;&lt;table style=&quot;width: 668.667px;&quot;&gt;&lt;thead&gt;&lt;tr&gt;&lt;th style=&quot;text-align: left;&quot; width=&quot;30%&quot;&gt;Feature&lt;/th&gt;&lt;th style=&quot;text-align: left;&quot; width=&quot;35%&quot;&gt;JSON&lt;/th&gt;&lt;th style=&quot;text-align: left;&quot; width=&quot;35%&quot;&gt;Protobuf&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;Format&lt;/td&gt;&lt;td&gt;Text-based&lt;/td&gt;&lt;td&gt;Binary (compact)&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Size&lt;/td&gt;&lt;td&gt;Larger&lt;/td&gt;&lt;td&gt;Much smaller&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Parse performance&lt;/td&gt;&lt;td&gt;Slower&lt;/td&gt;&lt;td&gt;Faster&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Schema enforcement&lt;/td&gt;&lt;td&gt;No (free-form)&lt;/td&gt;&lt;td&gt;Yes (strongly typed schema)&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Encryption impact&lt;/td&gt;&lt;td&gt;Heavier (more bytes to encrypt)&lt;/td&gt;&lt;td&gt;Lighter (smaller encrypted payload)&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Tamper resistance&lt;/td&gt;&lt;td&gt;Weaker (can be read/edited)&lt;/td&gt;&lt;td&gt;Stronger (harder to interpret)&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;Why Kafka over other queues like RabitMQ:&lt;/b&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;&lt;b&gt;Massive Scale and Parallelism&lt;/b&gt;&lt;/li&gt;&lt;ul&gt;&lt;li&gt;Kafka can &lt;strong data-end=&quot;2042&quot; data-start=&quot;2009&quot;&gt;handle billions of events/day&lt;/strong&gt;, easily.&lt;/li&gt;&lt;li&gt;&lt;strong data-end=&quot;2068&quot; data-start=&quot;2054&quot;&gt;Partitions&lt;/strong&gt; allow horizontal scaling of consumers:&lt;/li&gt;&lt;ul&gt;&lt;li&gt;e.g., 100 partitions means 100 consumers i.e. massive parallel processing.&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;RabbitMQ struggles when you need high fan-out and&lt;b&gt;&amp;nbsp;&lt;/b&gt;high throughput.&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;&lt;b&gt;Event Replay and Reliability&lt;/b&gt;&lt;/li&gt;&lt;ul&gt;&lt;li&gt;Ad tracking must be durable (e.g., billing, audits)&lt;/li&gt;&lt;li&gt;Kafka stores messages on disk with configurable retention (e.g., 7 days)&lt;/li&gt;&lt;li&gt;If a service fails, it can &lt;strong data-end=&quot;2474&quot; data-start=&quot;2463&quot;&gt;re-read&lt;/strong&gt; from the last offset i.e. no data lost.&lt;/li&gt;&lt;li&gt;RabbitMQ can lose messages unless you enable heavy persistence (with a perf hit).&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;&amp;nbsp;&lt;b&gt;Built-in Partitioning and Ordering&lt;/b&gt;&lt;/li&gt;&lt;ul&gt;&lt;li&gt;Kafka guarantees &lt;strong data-end=&quot;3041&quot; data-start=&quot;3007&quot;&gt;message ordering per partition&lt;/strong&gt;.&lt;/li&gt;&lt;li&gt;Ads Event Handler can partition by:&lt;/li&gt;&lt;ul&gt;&lt;li&gt;ad_id, device_id, etc.&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;This ensures all related events are processed in order, by the same consumer.&lt;/li&gt;&lt;/ul&gt;&lt;/ul&gt;&lt;div&gt;&lt;pre style=&quot;background: rgb(247, 249, 250); border-radius: 3px; box-sizing: border-box; line-height: 1.6; margin-bottom: 1em; margin-top: 0px; overflow: auto; padding: 10px 15px;&quot;&gt;&lt;span face=&quot;SFMono-Regular, Consolas, Liberation Mono, Menlo, Courier, monospace&quot; style=&quot;color: #263238; font-size: x-small;&quot;&gt;&lt;span style=&quot;text-wrap-mode: wrap;&quot;&gt;Topic: ad_events
Partitions: 100
Key: device_id (events from same device always lands in same partition)&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;Problem in the Pilot System: The Token got too smart&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;In the &lt;strong data-end=&quot;322&quot; data-start=&quot;313&quot;&gt;pilot&lt;/strong&gt;, the Ads Manager was:&lt;/div&gt;&lt;div&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;Extracting &lt;strong data-end=&quot;384&quot; data-start=&quot;359&quot;&gt;all tracking metadata&lt;/strong&gt; from the VAST (like URLs, vendor IDs, event types)&lt;/li&gt;&lt;li&gt;Packing all of it into a &lt;strong data-end=&quot;472&quot; data-start=&quot;463&quot;&gt;token&lt;/strong&gt; (as protobuf)&lt;/li&gt;&lt;li&gt;Encrypting and sending this token to the client&lt;/li&gt;&lt;li&gt;The token was self-contained — everything the backend needed to fire tracking URLs was inside it&lt;/li&gt;&lt;/ul&gt;It worked for small scale but it didn&#39;t scale:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;As Netflix onboarded &lt;strong data-end=&quot;765&quot; data-start=&quot;741&quot;&gt;multiple ad partners&lt;/strong&gt; (e.g., Nielsen, DoubleVerify, Microsoft, etc.), each vendor wanted:&lt;/div&gt;&lt;div&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;Their own &lt;strong data-end=&quot;864&quot; data-start=&quot;846&quot;&gt;tracking logic.&lt;/strong&gt;&lt;/li&gt;&lt;li&gt;&lt;span data-end=&quot;864&quot; data-start=&quot;846&quot;&gt;Unique &lt;span data-end=&quot;899&quot; data-start=&quot;874&quot;&gt;&lt;b&gt;macros to be replaced&lt;/b&gt;&lt;/span&gt; in URLs&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span data-end=&quot;864&quot; data-start=&quot;846&quot;&gt;Complex &lt;b&gt;conditional tracking rules&lt;/b&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span data-end=&quot;864&quot; data-start=&quot;846&quot;&gt;Custom logic based on &lt;strong data-end=&quot;988&quot; data-start=&quot;973&quot;&gt;device type&lt;/strong&gt;, &lt;strong data-end=&quot;1000&quot; data-start=&quot;990&quot;&gt;timing&lt;/strong&gt;, &lt;strong data-end=&quot;1014&quot; data-start=&quot;1002&quot;&gt;campaign&lt;/strong&gt;, etc.&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;What are these macros we are talking about:&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span data-end=&quot;241&quot; data-start=&quot;231&quot;&gt;Macros&lt;/span&gt; are &lt;em data-end=&quot;269&quot; data-start=&quot;246&quot;&gt;placeholder variables&lt;/em&gt; in tracking URLs that get dynamically replaced with actual values &lt;strong data-end=&quot;350&quot; data-start=&quot;336&quot;&gt;at runtime&lt;/strong&gt;, before the URL is fired.&lt;/div&gt;&lt;div&gt;They let ad vendors capture contextual information like:&lt;/div&gt;&lt;div&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;The timestamp when an ad was viewed&lt;/li&gt;&lt;li&gt;The type of device&lt;/li&gt;&lt;li&gt;Whether the user clicked or skipped&lt;/li&gt;&lt;li&gt;The playback position, etc.&lt;/li&gt;&lt;/ul&gt;&lt;b&gt;Example:&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;A vendor might provide a tracking URL like:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;pre style=&quot;background: rgb(247, 249, 250); border-radius: 3px; box-sizing: border-box; line-height: 1.6; margin-bottom: 1em; margin-top: 0px; overflow: auto; padding: 10px 15px;&quot;&gt;&lt;span style=&quot;color: #263238; font-size: x-small;&quot;&gt;&lt;span style=&quot;text-wrap-mode: wrap;&quot;&gt;https://track.vendor.com/pixel?event=impression&amp;amp;ts=[TIMESTAMP]&amp;amp;device=[DEVICE_TYPE]&lt;/span&gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;&lt;div&gt;Here:&lt;/div&gt;&lt;div&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;&lt;code data-end=&quot;771&quot; data-start=&quot;758&quot;&gt;[TIMESTAMP]&lt;/code&gt; is a macro for when the ad started playing&lt;/li&gt;&lt;li&gt;&lt;code data-end=&quot;832&quot; data-start=&quot;817&quot;&gt;[DEVICE_TYPE]&lt;/code&gt; is a macro for the kind of device (TV, phone, etc.)&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;Before this URL is fired, those macros must be &lt;strong data-end=&quot;945&quot; data-start=&quot;933&quot;&gt;resolved&lt;/strong&gt; to actual values:&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;pre style=&quot;background: rgb(247, 249, 250); border-radius: 3px; box-sizing: border-box; line-height: 1.6; margin-bottom: 1em; margin-top: 0px; overflow: auto; padding: 10px 15px;&quot;&gt;&lt;span style=&quot;color: #263238; font-size: x-small;&quot;&gt;&lt;span style=&quot;text-wrap-mode: wrap;&quot;&gt;https://track.vendor.com/pixel?event=impression&amp;amp;ts=1717910340000&amp;amp;device=tv&lt;/span&gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;Why Macros become a problem at scale:&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;ol style=&quot;text-align: left;&quot;&gt;&lt;li&gt;Inconsistent Syntax Across Vendors&lt;/li&gt;&lt;ul&gt;&lt;li&gt;Some used &lt;code data-end=&quot;1511&quot; data-start=&quot;1498&quot;&gt;[TIMESTAMP]&lt;/code&gt;, others used &lt;code data-end=&quot;1531&quot; data-start=&quot;1525&quot;&gt;%ts%&lt;/code&gt;, or even custom placeholders.&lt;/li&gt;&lt;li&gt;Netflix had to implement logic per partner to resolve them correctly.&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;Dynamic Values Grew&lt;/li&gt;&lt;ul&gt;&lt;li&gt;New use cases brought in more macros: region, episode title, ad ID, player version, UI language, etc&lt;/li&gt;&lt;li&gt;Supporting new macros meant:&lt;/li&gt;&lt;ul&gt;&lt;li&gt;Updating the token schema&lt;/li&gt;&lt;li&gt;Updating Ads Manager logic&lt;/li&gt;&lt;li&gt;Sometimes even updating clients&lt;/li&gt;&lt;/ul&gt;&lt;/ul&gt;&lt;li&gt;Difficult to Test or Validate&lt;/li&gt;&lt;ul&gt;&lt;li&gt;Because everything was encrypted in the token, validating whether macros were substituted correctly was hard.&lt;/li&gt;&lt;li&gt;A bug in macro resolution could break tracking silently.&lt;/li&gt;&lt;/ul&gt;&lt;/ol&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;This meant the &lt;strong data-end=&quot;1068&quot; data-start=&quot;1039&quot;&gt;token payload was growing&lt;/strong&gt;&lt;span data-end=&quot;1068&quot; data-start=&quot;1039&quot;&gt;;&lt;/span&gt;&amp;nbsp;more vendors, more metadata, more per-event config.&lt;/div&gt;&lt;/div&gt;&lt;div&gt;So to summarize the problems, here is the table:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;table style=&quot;width: 100%;&quot;&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th style=&quot;text-align: left;&quot; width=&quot;40%&quot;&gt;Problem&lt;/th&gt;
&lt;th style=&quot;text-align: left;&quot; width=&quot;60%&quot;&gt;Why it hurt&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Payload bloat&lt;/td&gt;
&lt;td&gt;Token size increased → slower to transmit → harder to encrypt&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Hard to evolve&lt;/td&gt;
&lt;td&gt;Any schema change required new client logic and re-deployment&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;No dynamic behavior&lt;/td&gt;
&lt;td&gt;Logic was fixed at ad decision time; couldn’t update later&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Redundant processing&lt;/td&gt;
&lt;td&gt;Every token had repeated config for the same vendors&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Hard to debug/troubleshoot&lt;/td&gt;
&lt;td&gt;No human-readable registry of how tokens should behave&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;How did Netflix solve the problem: Meatdata Registry Service (MRS):&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;To overcome the scaling bottlenecks of self-contained tokens, Netflix introduced a new component: &lt;i&gt;the Metadata Registry Service (MRS)&lt;/i&gt;.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Its core idea was simple but powerful, separate the metadata from the token. Instead of encoding everything inside the token, Netflix now stores reusable metadata centrally in MRS, and the token merely references it via an ID.&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;How MRS works:&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;ol style=&quot;text-align: left;&quot;&gt;&lt;li&gt;&lt;b&gt;Ads Manager Gets VAST:&lt;/b&gt;&amp;nbsp;Ads Manager still fetches the VAST response from the ad decisioning system (e.g. Microsoft’s ad server).&lt;/li&gt;&lt;li&gt;&lt;b&gt;Metadata Extracted &amp;amp; Stored:&lt;/b&gt;&amp;nbsp;Instead of encrypting all metadata into a token, Ads Manager:&lt;/li&gt;&lt;ul&gt;&lt;li&gt;Extracts metadata (tracking pixels, macros, event mappings, etc.)&lt;/li&gt;&lt;li&gt;Stores it in &lt;strong data-end=&quot;1467&quot; data-start=&quot;1432&quot;&gt;Metadata Registry Service (MRS)&lt;/strong&gt; with a &lt;strong data-end=&quot;1491&quot; data-start=&quot;1475&quot;&gt;registry key&lt;/strong&gt;&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;&lt;b&gt;Token Now Just an Id:&amp;nbsp;&lt;/b&gt;The token now just contains:&lt;/li&gt;&lt;ul&gt;&lt;li&gt;The &lt;strong data-end=&quot;1580&quot; data-start=&quot;1564&quot;&gt;registry key&lt;/strong&gt;&lt;/li&gt;&lt;li&gt;&lt;span data-end=&quot;1580&quot; data-start=&quot;1564&quot;&gt;A small payload (e.g. dynamic fields like &lt;code data-end=&quot;1643&quot; data-start=&quot;1628&quot;&gt;ad_start_time&lt;/code&gt; or session ID)&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;&lt;b&gt;Device Sends Events with Token:&lt;/b&gt;&amp;nbsp;Devices emit telemetry events with this lightweight token.&lt;/li&gt;&lt;li&gt;&lt;b&gt;Backend Looks Up MRS:&amp;nbsp;&lt;/b&gt;Ads Event Handler uses the registry key to:&lt;/li&gt;&lt;ul&gt;&lt;li&gt;Fetch the tracking metadata from MRS&lt;/li&gt;&lt;li&gt;Apply macros&lt;/li&gt;&lt;li&gt;Fire tracking URLs&lt;/li&gt;&lt;/ul&gt;&lt;/ol&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/a/AVvXsEjEaHqh1xVK4_KNYHSjM0QKMIW_Bgs5EcC-kr_nRPTBBUGdGqFdnbcXKfHVZn4L8GS9GB62dmFkly5VyNFS3aSnivc3CcTMUSsXKYjztwg-Adk6RKMsxfAXuXSjpMdenHKR4Us9vmCzcP3JD_dhreygaugemNwAswYzlx0HiXbUWJbWjQoQM7UZ_2z67KU&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img alt=&quot;&quot; data-original-height=&quot;552&quot; data-original-width=&quot;1009&quot; height=&quot;335&quot; src=&quot;https://blogger.googleusercontent.com/img/a/AVvXsEjEaHqh1xVK4_KNYHSjM0QKMIW_Bgs5EcC-kr_nRPTBBUGdGqFdnbcXKfHVZn4L8GS9GB62dmFkly5VyNFS3aSnivc3CcTMUSsXKYjztwg-Adk6RKMsxfAXuXSjpMdenHKR4Us9vmCzcP3JD_dhreygaugemNwAswYzlx0HiXbUWJbWjQoQM7UZ_2z67KU=w613-h335&quot; width=&quot;613&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;div style=&quot;text-align: center;&quot;&gt;&lt;b&gt;Ad Events flow with MRS&lt;/b&gt;&lt;/div&gt;&lt;/div&gt;&lt;div style=&quot;text-align: center;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;So summary of what exactly changed:&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;table style=&quot;width: 668.667px;&quot;&gt;&lt;thead&gt;&lt;tr&gt;&lt;th style=&quot;text-align: left;&quot; width=&quot;40%&quot;&gt;Before MRS&lt;/th&gt;&lt;th style=&quot;text-align: left;&quot; width=&quot;60%&quot;&gt;After MRS&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;Token = All tracking logic inside&lt;/td&gt;&lt;td&gt;Token = Just a reference id&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Tracking metadata repeated often&lt;/td&gt;&lt;td&gt;Metadata stored once in registry&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Hard to update or debug&lt;/td&gt;&lt;td&gt;Dynamic updates via registry&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Schema tightly coupled to client&lt;/td&gt;&lt;td&gt;Centralized schema owned by server&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;br /&gt;&lt;/td&gt;&lt;td&gt;&lt;br /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;Benefits of MRS approach:&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;ol style=&quot;text-align: left;&quot;&gt;&lt;li&gt;&lt;b&gt;Dynamic Metadata Updates&lt;/b&gt;&lt;/li&gt;&lt;ul&gt;&lt;li&gt;Vendor changes their URLs or macro format? Just update MRS.&lt;/li&gt;&lt;li&gt;No need to redeploy client or regenerate tokens.&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;&lt;b&gt;Improved Performance&lt;/b&gt;&lt;/li&gt;&lt;ul&gt;&lt;li&gt;Tokens are smaller means less encryption overhead, less network cost.&lt;/li&gt;&lt;li&gt;Registry entries are cached means fast and efficient.&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;&lt;b&gt;Better Observability&lt;/b&gt;&lt;/li&gt;&lt;ul&gt;&lt;li&gt;MRS is a source of truth for all campaign metadata.&lt;/li&gt;&lt;li&gt;Easy to search, debug, and trace logic across vendors and campaigns.&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;&lt;b&gt;Reusability&lt;/b&gt;&lt;/li&gt;&lt;ul&gt;&lt;li&gt;Multiple campaigns can reference the same registry entry.&lt;/li&gt;&lt;li&gt;No duplication of tracking logic.&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;&lt;b&gt;Separation of Concerns&lt;/b&gt;&lt;/li&gt;&lt;ul&gt;&lt;li&gt;Client focuses on playback and telemetry.&lt;/li&gt;&lt;li&gt;Backend owns tracking logic and event firing.&lt;/li&gt;&lt;/ul&gt;&lt;/ol&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;* You might be thinking there is no logic in client for tokens i.e. the &lt;strong data-end=&quot;236&quot; data-start=&quot;203&quot;&gt;logic to fire tracking pixels&lt;/strong&gt;&amp;nbsp;was &lt;em data-end=&quot;301&quot; data-start=&quot;296&quot;&gt;not&lt;/em&gt; on the client. The client just played the ad and emitted telemetry events along with the token so why client redeployment is in the picture even without MR. According to me, the protobuf schema can become a bottlenec here as the schema changes, client code also need a change. With MRS we can freeze the client payload schema.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;In this first part of our deep dive into Netflix’s Ads Event Processing Pipeline, we traced the evolution from a tightly-coupled, token-heavy system to a more modular and scalable architecture powered by the &lt;strong data-end=&quot;469&quot; data-start=&quot;434&quot;&gt;Metadata Registry Service (MRS)&lt;/strong&gt;.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;By decoupling metadata from tokens and centralizing macro resolution and tracking logic, Netflix unlocked:&lt;/div&gt;&lt;div&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;Smaller, lighter tokens&lt;/li&gt;&lt;li&gt;Faster and safer iteration&lt;/li&gt;&lt;li&gt;Dynamic partner integration&lt;/li&gt;&lt;li&gt;Debuggability at scale&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;What started as a necessary fix for bloated tokens ended up becoming the foundation for a &lt;strong data-end=&quot;858&quot; data-start=&quot;796&quot;&gt;much more agile and partner-friendly ad tracking ecosystem&lt;/strong&gt;.&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;But Netflix didn’t stop there!&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;In [Part 2], we’ll explore the &lt;strong data-end=&quot;1021&quot; data-start=&quot;1004&quot;&gt;next big leap&lt;/strong&gt;: how Netflix brought ad decisioning &lt;em data-end=&quot;1068&quot; data-start=&quot;1058&quot;&gt;in-house&lt;/em&gt; — giving them end-to-end control over targeting, creative rotation, pacing, and auction logic&amp;nbsp;and how this plugged seamlessly into the MRS-backed pipeline we just explored.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;We will learn how they:&lt;/div&gt;&lt;div&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;Built an &lt;strong data-end=&quot;1227&quot; data-start=&quot;1199&quot;&gt;Ad Decision Server (ADS)&lt;/strong&gt; from scratch&lt;/li&gt;&lt;li&gt;Integrated it with the metadata pipeline&lt;/li&gt;&lt;li&gt;Enabled &lt;strong data-end=&quot;1332&quot; data-start=&quot;1294&quot;&gt;real-time, personalized ad serving&lt;/strong&gt; on a global scale&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;Thanks a lot and stay tuned, the story gets even more fascinating.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://algods-cracker.blogspot.com/feeds/6349033419261768746/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://algods-cracker.blogspot.com/2025/06/netflix-tech-blog-inside-netflixs-ads.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7496974970329409400/posts/default/6349033419261768746'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7496974970329409400/posts/default/6349033419261768746'/><link rel='alternate' type='text/html' href='http://algods-cracker.blogspot.com/2025/06/netflix-tech-blog-inside-netflixs-ads.html' title='[Netflix Tech Blog] Inside Netflix&#39;s Ads Event Engine: A Deep Dive (Part 1)'/><author><name>Nishant Saxena</name><uri>http://www.blogger.com/profile/17860524009847591950</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjOdjS62BAEI1iMG_zd6lew4qyFGpfJhWHp0AJWQhiJvxQpSGg0AFZ5euJG7tK0D-EGQFno32hF-i1x4E2A49re_8-b9r0QHwXQ-9X_EvlAcekIjUYMaA1v6dWzDqzkBg/s220/2d230a1.jpg'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/a/AVvXsEi9s-Mk63MhF5AiEPgSV56ue6vzBmyX2TVQSt6g2DAtwC5wGHhYznWF8Oyt4Oglc3jTOUx3tApLI2VetDNz1HgCn8bCDUrZZNJ_G4KXsaiTOGQKo2Pov-KUA85-GA2Ea8gO9vvbbrxkaecZiRECzxYGS2-lMjqe2Z3L302jAShGWq9qp3FOM4mipUXLhZw=s72-w606-h331-c" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7496974970329409400.post-7530468713728326855</id><published>2024-10-28T20:54:00.000+05:30</published><updated>2024-10-28T20:54:04.745+05:30</updated><category scheme="http://www.blogger.com/atom/ns#" term="System Design"/><title type='text'>Design Uber</title><content type='html'>&lt;p&gt;&lt;b&gt;Problem:&lt;/b&gt; Design a highly scalable rideshare service.&lt;/p&gt;&lt;p&gt;&lt;b&gt;Requirements:&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;1. Functional requirements:&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;ol style=&quot;text-align: left;&quot;&gt;&lt;li&gt;Only registered users can request a cab.&lt;/li&gt;&lt;ul&gt;&lt;li&gt;Driver registration is manual and is out of scope here.&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;Driver and user needs to login to request and receive the ride.&lt;/li&gt;&lt;li&gt;Driver needs to make himself available to receive the rides.&lt;/li&gt;&lt;li&gt;Each driver can be matched to multiple riders depends on users and the occupancy of the car.&lt;/li&gt;&lt;li&gt;Price of the ride depends on base flat fee, distance and duration.&lt;/li&gt;&lt;ul&gt;&lt;li&gt;Exact formula is not given and is subject to change&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;We need to minimize the:&lt;/li&gt;&lt;ol&gt;&lt;li&gt;Wait time of users&lt;/li&gt;&lt;li&gt;Distance / Time for drivers to pickup the user.&lt;/li&gt;&lt;/ol&gt;&lt;li&gt;Collect payment information from users.&lt;/li&gt;&lt;li&gt;Collect bank information of drivers to pay them.&lt;/li&gt;&lt;li&gt;Driver should start/end the trip.&lt;/li&gt;&lt;li&gt;For actual payment process, we can use third party services.&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;2. Nonfunctional requirements:&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;ol style=&quot;text-align: left;&quot;&gt;&lt;li&gt;Scalability:&lt;/li&gt;&lt;ul&gt;&lt;li&gt;100 M to 200 M daily users.&lt;/li&gt;&lt;li&gt;100 K to 200 K drivers.&lt;/li&gt;&lt;li&gt;Peak hours support where demand is 10 times of average.&lt;/li&gt;&lt;li&gt;Collect driver&#39;s location every ~5-10 seconds =~ 3B messages / day&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;Availability:&lt;/li&gt;&lt;ul&gt;&lt;li&gt;99.99% uptime or higher&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;Performance:&lt;/li&gt;&lt;ul&gt;&lt;li&gt;Match users with drivers 10 seconds at 99 percentile&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;AP over CP:&lt;/li&gt;&lt;ul&gt;&lt;li&gt;Higher availability is required here over consistency.&lt;/li&gt;&lt;/ul&gt;&lt;/ol&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;Design:&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;Step 1: API Design:&lt;/b&gt;&lt;/p&gt;&lt;p&gt;This looks like a very complex system which makes it even more difficult to come up with the all the APIs which are needed for the system to work.&lt;/p&gt;&lt;p&gt;However we will use sequence diagram to make it simple which we are doing in our previous design problems:&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjs9F-1u6BCGQDEO1TNpO5l28VMfjFHjrJ-as6OutwoTaHv2ui_QFGQj61l8uU452NKoj0fNFfS_lZVv3yyfplhiI6FINmQ7t3ZtiiM9GWbLH1Ps20P8-koCYYCvZFebJUJksNb1xBrBeQDr4CmaidNW4AoaYqRtdUxQ01583ktqKeY5v_iZD25SDGVVUQ/s2054/UberSeqDiag.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;2054&quot; data-original-width=&quot;922&quot; height=&quot;977&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjs9F-1u6BCGQDEO1TNpO5l28VMfjFHjrJ-as6OutwoTaHv2ui_QFGQj61l8uU452NKoj0fNFfS_lZVv3yyfplhiI6FINmQ7t3ZtiiM9GWbLH1Ps20P8-koCYYCvZFebJUJksNb1xBrBeQDr4CmaidNW4AoaYqRtdUxQ01583ktqKeY5v_iZD25SDGVVUQ/w439-h977/UberSeqDiag.png&quot; width=&quot;439&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;Just one thing to notice, given the sequence diagram, we can see the need of having a bidirection connection between server &amp;amp; drivers and also server &amp;amp; riders.&lt;p&gt;&lt;/p&gt;&lt;p&gt;From the sequence diagram we can now have the clear APIs:&lt;/p&gt;&lt;p&gt;&lt;b&gt;Drivers:&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;POST /drivers/login&lt;/li&gt;&lt;li&gt;POST /drivers/{driver_id}/join&lt;/li&gt;&lt;li&gt;POST /drivers/{driver_id}/location&lt;/li&gt;&lt;li&gt;POST /trips/{trip_id}/start&lt;/li&gt;&lt;li&gt;POST /trips/{trip_id}/end&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;Riders:&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;POST /riders/ - Register a rider&lt;/li&gt;&lt;li&gt;POST /riders/login&lt;/li&gt;&lt;li&gt;POST /rides&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;Step 2: Mapping functional requirements to architectural diagram:&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;1.&amp;nbsp;Only registered users can request a cab.&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;2.&amp;nbsp;Driver and user needs to login to request and receive the ride.&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;7. Collect payment information from users.&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;8. Collect Bank information of drivers to pay them.&lt;/b&gt;&lt;/p&gt;&lt;p&gt;To serve these requirements 1, 2,&amp;nbsp; we can have a single &lt;i&gt;User service&lt;/i&gt;. User service will have a SQL DB which contains two tables:&lt;/p&gt;&lt;p&gt;&lt;b&gt;Rider:&lt;/b&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;rider_id&lt;/li&gt;&lt;li&gt;username&lt;/li&gt;&lt;li&gt;password&lt;/li&gt;&lt;li&gt;age&lt;/li&gt;&lt;li&gt;image_url&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;Driver:&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;driver_id&lt;/li&gt;&lt;li&gt;username&lt;/li&gt;&lt;li&gt;password&lt;/li&gt;&lt;li&gt;license&lt;/li&gt;&lt;li&gt;vehicle&lt;/li&gt;&lt;li&gt;image_url&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;For the profile image we will store the image in &lt;i&gt;object store&lt;/i&gt; and put the image url in DB.&lt;/p&gt;&lt;p&gt;To support requirement 7 and 8, we will have a separate service &lt;i&gt;Payment Service&lt;/i&gt; which will have it&#39;s own SQL DB. This DB will contain the RiderPaymentInfo table and DriverPaymentInfo table.&lt;/p&gt;&lt;p&gt;&lt;b&gt;RiderPaymentInfo:&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;user_id&lt;/li&gt;&lt;li&gt;credit_card&lt;/li&gt;&lt;li&gt;billing address&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;DriverPaymentInfo:&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;driver_id&lt;/li&gt;&lt;li&gt;bank_name&lt;/li&gt;&lt;li&gt;account_number&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;This payment service will connect with credit card companies / banks for the payment processing.&lt;/p&gt;&lt;p&gt;Here is how our architectural diagram looks like:&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjHQyaQQePF9C_mv31Z7mACvtHWwbQBQQFwigB6QWLFRwZPUoQOlB18mOhUMezZJL8MnXcP4StFlcrVuc4dboLq1T8mvCS30d6BA0EH5YWmYE-PgpKrLUU50OshP9DD9tMRMs6_VkzYDoW-uD38yGahr03wDVfzEgstuswVEfm3Ss23p4Osohyphenhyphenq2kE8Ssw/s941/UberHLD.drawio.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;651&quot; data-original-width=&quot;941&quot; height=&quot;400&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjHQyaQQePF9C_mv31Z7mACvtHWwbQBQQFwigB6QWLFRwZPUoQOlB18mOhUMezZJL8MnXcP4StFlcrVuc4dboLq1T8mvCS30d6BA0EH5YWmYE-PgpKrLUU50OshP9DD9tMRMs6_VkzYDoW-uD38yGahr03wDVfzEgstuswVEfm3Ss23p4Osohyphenhyphenq2kE8Ssw/w580-h400/UberHLD.drawio.png&quot; width=&quot;580&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;b&gt;3. Driver needs to make himself available to receive the rides:&lt;/b&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;For this Driver needs to call join API and keep sending it&#39;s location. We need to have a new service say &lt;i&gt;Driver Service&lt;/i&gt; which will create a &lt;i&gt;bidirection connection using web sockets&lt;/i&gt;&amp;nbsp;when Driver call the join API. This will have following benefits:&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;Driver needs to send location very frequently so it will remove the overhead of TCP connection every time.&lt;/li&gt;&lt;li&gt;Server can also push message to driver such as pick_up rider etc.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;To record these location we will use a new service say &lt;i&gt;Location Service&lt;/i&gt;. Driver service will continue to queue these locations to Location service. We will use a write performant &lt;i&gt;LSM&lt;/i&gt; tree based &lt;i&gt;NoSQL DB&lt;/i&gt; to store these locations updates. This will contain driver_id and location like lat and long and we continue to update this record until the driver is booked for a trip.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgIqVEj78HYhOWnZdfLmmmL7T5shOPreNsUK5Y8Xh-8PvXY4hu000CPt0-TLt3RfcL3iuBNOSxPzTbzeC2hUPhWpW_kfNxqwwTg1CkPpxxjMNmAox9t2cywd-IwmdDdDqDbyr3nmi2HWG4zFbo6SIEQvh4zeVD9xuol4kkqT_pik_jWeElJ7siJAzggSx8/s1121/UberHLD.drawio.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;651&quot; data-original-width=&quot;1121&quot; height=&quot;373&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgIqVEj78HYhOWnZdfLmmmL7T5shOPreNsUK5Y8Xh-8PvXY4hu000CPt0-TLt3RfcL3iuBNOSxPzTbzeC2hUPhWpW_kfNxqwwTg1CkPpxxjMNmAox9t2cywd-IwmdDdDqDbyr3nmi2HWG4zFbo6SIEQvh4zeVD9xuol4kkqT_pik_jWeElJ7siJAzggSx8/w642-h373/UberHLD.drawio.png&quot; width=&quot;642&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;b&gt;6. Rider can request the ride and the driver must be matched with minimum wait time:&lt;/b&gt;&lt;p&gt;&lt;/p&gt;&lt;b&gt;4. Each driver can be matched to multiple riders depends on users and the occupancy of the car:&lt;/b&gt;&lt;br /&gt;&lt;p&gt;To request a ride, we will have a new service called &lt;i&gt;Rider Service&lt;/i&gt;. Upon requesting the ride, a &lt;i&gt;bidirectional websocket connection&lt;/i&gt; has been stablished between rider and this service as we need to send the updates to the riders.&amp;nbsp;&lt;/p&gt;&lt;p&gt;To match a rider to a driver we will have a new service &lt;i&gt;Matching Service&lt;/i&gt;. Let&#39;s double click into this matching service to see how to match a driver.&lt;/p&gt;&lt;p&gt;First approach which directly comes into our mind is simple:&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;Take the lat, long of rider.&amp;nbsp;&lt;/li&gt;&lt;li&gt;Draw a circle centered at rider&#39;s location of radius of 2-3 KM and try to find drives within this circle&lt;/li&gt;&lt;li&gt;Given the location of drivers is already present in Location Service DB, we can use this DB to get the list of drivers.&lt;/li&gt;&lt;li&gt;Take the driver with the least distance.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;However the direct distance of two points is not good measure because of road structures, traffic etc.&lt;/p&gt;&lt;p&gt;Given that the ETA calculation is complex and is not our functional requirement, we can use a &lt;i&gt;third party ETA calculation service&lt;/i&gt;. With this third party service here is how our flow changes:&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;Matching service sends the rider location to Location service.&lt;/li&gt;&lt;li&gt;Location service finds all the closed drivers as per our previous approach of 2-3 KM radius circle.&lt;/li&gt;&lt;li&gt;Location service now sends the list of pairs {user location, driver location} to third party service.&lt;/li&gt;&lt;li&gt;Third party service sends the ETA of every pair of locations to Location service.&lt;/li&gt;&lt;li&gt;Location service send these pairs {driver_id, ETA} back to Matching service to make the final decision.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;There are few considerations for matching the driver based on that we can match the driver:&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;Match driver with the lowest ETA&lt;/li&gt;&lt;li&gt;Math the driver who is about to finish the trip nearby rider.&lt;/li&gt;&lt;li&gt;Allow multiple riders to share a ride&lt;/li&gt;&lt;li&gt;Prioritize drivers whose rating is high for high rated rider.&lt;/li&gt;&lt;li&gt;Permium service&lt;/li&gt;&lt;li&gt;Prioritize drivers who have earned very less.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;Once the Matching service matches the driver, it needs to store this info somewhere. For this we will have new service say &lt;i&gt;Trip service&lt;/i&gt; with it&#39;s own SQL DB which will contain source and destination, user_id, driver_id, fare, start_time, end_time, distance etc. Here are the next set of steps:&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;Create a new Trip using the Trip service. Get the trip_id in response.&lt;/li&gt;&lt;li&gt;Send the signal to Location service to tell it that Driver is booked. It will also send the trip_info. The trip_info will contain trip_id and rider_id for sure.&lt;/li&gt;&lt;li&gt;Location service will add two new columns: Driver state and Trip Info.&amp;nbsp;&lt;/li&gt;&lt;li&gt;Matching service now send the trip info and driver details including location to Rider service which will push this info to Rider.&lt;/li&gt;&lt;li&gt;Similarly Matching service send the trip info and rider details including location to Driver service which will push this info to driver&lt;/li&gt;&lt;li&gt;Now when driver send the location to Driver service, Location service append this record to it&#39;s DB and also send this location update to Rider service which will update the rider.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;You can see how much this web socket connection is useful in these scenarios.&lt;/p&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgJsWb-mcIBPMQ4FYsrFkjJ6tyy67yvmeMHfWixDmsVj_xZYyI-ufuwbO_oOkC7HPV_EXueLuOXNbhVMHpjsD7zJZI3jPpZ55JeeklcgIhaiI_kI8xnLkU2yuS3uhJyGNllXgJDhhyphenhyphenN1xazdJJPU3sNLyKsd5uN1semOAs0DDm6p3tZYz7xWoKSFRGsGoY/s1621/UberHLD.drawio.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;834&quot; data-original-width=&quot;1621&quot; height=&quot;330&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgJsWb-mcIBPMQ4FYsrFkjJ6tyy67yvmeMHfWixDmsVj_xZYyI-ufuwbO_oOkC7HPV_EXueLuOXNbhVMHpjsD7zJZI3jPpZ55JeeklcgIhaiI_kI8xnLkU2yuS3uhJyGNllXgJDhhyphenhyphenN1xazdJJPU3sNLyKsd5uN1semOAs0DDm6p3tZYz7xWoKSFRGsGoY/w639-h330/UberHLD.drawio.png&quot; width=&quot;639&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;p&gt;&lt;b&gt;9. Driver should start/end the trip:&lt;/b&gt;&lt;/p&gt;&lt;p&gt;Upon reaching the source/destination or where the user wants a drop, driver will start/end the trip by calling the APIs. This will be redirected to trip service. Now Trip service will notify Location Service to change the status of driver as In_Trip / Free.&amp;nbsp;&lt;/p&gt;&lt;p&gt;Trip service can get the details of locations from Location Service to calculate the distance and everything else for the payments etc.&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiXUqyFRO9iK_Rbv6mCTOE_-PWg62SDjYNDTEi8vIb6wYIS7UUmLkfM1Ru3wS8m8oP7rPR55jcLFk3WNukaE5UlqTG2J16389asXuShw9DO88Y-f57MJE4IZtOlO9DMIBeCEA825wHvDcPUEH3s0jdH8du_7qoKp6C7-iRoLG_WaBRENG5JEOwBKPs5QjM/s1511/UberHLD.drawio.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;834&quot; data-original-width=&quot;1511&quot; height=&quot;355&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiXUqyFRO9iK_Rbv6mCTOE_-PWg62SDjYNDTEi8vIb6wYIS7UUmLkfM1Ru3wS8m8oP7rPR55jcLFk3WNukaE5UlqTG2J16389asXuShw9DO88Y-f57MJE4IZtOlO9DMIBeCEA825wHvDcPUEH3s0jdH8du_7qoKp6C7-iRoLG_WaBRENG5JEOwBKPs5QjM/w642-h355/UberHLD.drawio.png&quot; width=&quot;642&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;p&gt;&lt;/p&gt;&lt;div&gt;&lt;p&gt;&lt;b&gt;5. Price of the ride depends on base flat fee, distance and duration:&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;10. For actual payment process, we can use third party services:&lt;/b&gt;&lt;/p&gt;&lt;p&gt;Let&#39;s come to the Post trip part where we need to collect the payment from rider and send driver fee to driver account. We also need to send this info as an Email to rider and driver.&lt;/p&gt;&lt;p&gt;Here is the flow:&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;Trip servivce will calculate the ride cost and driver fee.&lt;/li&gt;&lt;li&gt;Trip service will queue the trip_info including user_id, driver_id and payment_info to Payment Service.&lt;/li&gt;&lt;li&gt;Payment service will interact with third party service to mak the payment.&lt;/li&gt;&lt;li&gt;Once the payment is successful, It will queue two messages; one for user and one for driver including trip info and their corresponding payment_info to new service &lt;i&gt;Notification Service.&lt;/i&gt;&lt;/li&gt;&lt;li&gt;Notification service will send email to driver and user.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;/p&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhhV5iRq4mRpalxo1sk13BhtXc4ZweeDdUayS0wD5yJWh9vFM8PCqX14xIPGeJBuSdQ13JDsdLBQYBN6DTvG2gWH08NOL8uC-A7DUQkf4-51JxEEL9q1N-iUBZBcVfdJna4j8xpXJbOiNPSOs8vs-A69zrwbK7rceShse473btCYVWmVyT8Eag9NQRqvSs/s2267/UberHLD.drawio.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;1251&quot; data-original-width=&quot;2267&quot; height=&quot;343&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhhV5iRq4mRpalxo1sk13BhtXc4ZweeDdUayS0wD5yJWh9vFM8PCqX14xIPGeJBuSdQ13JDsdLBQYBN6DTvG2gWH08NOL8uC-A7DUQkf4-51JxEEL9q1N-iUBZBcVfdJna4j8xpXJbOiNPSOs8vs-A69zrwbK7rceShse473btCYVWmVyT8Eag9NQRqvSs/w621-h343/UberHLD.drawio.png&quot; width=&quot;621&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;p&gt;That&#39;s all about the functional requirements&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;Step 3: Mapping non functional requirements to architectural diagram:&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;1. Scalability:&lt;/b&gt;&lt;/p&gt;&lt;p&gt;Given the traffic we need to run multiple instances of every service. Even the notification service is not public facing service but still at the time of peak, we might need to scale up this service too.&lt;/p&gt;&lt;p&gt;Now the problem is about the Driver service and Rider service as these are having web socket persistent connections. How the location service will come to know which instance to connect to send driver location to rider or how Matching service will know which instance to connect to send trip info to driver.&lt;/p&gt;&lt;p&gt;To solve this issue, we will have a new service called &lt;i&gt;Connection Manager &lt;/i&gt;which will have its &lt;i&gt;very efficient key value pair NoSql DB like Redis&lt;/i&gt; to maintain this mapping. Now Location Service or Matching Service can query Connection Manager Service to get the right instance.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgy6ILbunncHgivopO6qXCOCpUEvcyCyJrCIweUQKlyiBhvY1shbKPs6HtIgHPy7jNAfJPilfWM6bJxrQCpc-XCik8rscsidGSERhrQ7FTNeQ7Kc_ezaKYA20NMXPjq4IU1Ui9ostYB3GknQ3UPCACKBMVLzLdQL1QEiygWpdPhD84liKbuVYrqhqUqObQ/s1511/UberHLD.jpg&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;1094&quot; data-original-width=&quot;1511&quot; height=&quot;424&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgy6ILbunncHgivopO6qXCOCpUEvcyCyJrCIweUQKlyiBhvY1shbKPs6HtIgHPy7jNAfJPilfWM6bJxrQCpc-XCik8rscsidGSERhrQ7FTNeQ7Kc_ezaKYA20NMXPjq4IU1Ui9ostYB3GknQ3UPCACKBMVLzLdQL1QEiygWpdPhD84liKbuVYrqhqUqObQ/w585-h424/UberHLD.jpg&quot; width=&quot;585&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;b&gt;2. Availability:&lt;/b&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;For this we just need to add replica of our DBs in order to achieve availability.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgxAvkAtIhwpHW1bPmHA9yqzms-_QfZtLxwK77LCOBcUup-H2bTVCrcJNpDxYezW49qRPkXknuybktjjYPTROXNod6MqZ2yN989OjF6Tp10_zcx8YFoahOZ03GMdLkwc3sLvqeRZhj9aol7yib16qpLQrXVY9K2EkgWBeHO4ItNBkGj_uV8Nas8v3EmWUQ/s1511/UberHLD.drawio.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;1141&quot; data-original-width=&quot;1511&quot; height=&quot;448&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgxAvkAtIhwpHW1bPmHA9yqzms-_QfZtLxwK77LCOBcUup-H2bTVCrcJNpDxYezW49qRPkXknuybktjjYPTROXNod6MqZ2yN989OjF6Tp10_zcx8YFoahOZ03GMdLkwc3sLvqeRZhj9aol7yib16qpLQrXVY9K2EkgWBeHO4ItNBkGj_uV8Nas8v3EmWUQ/w592-h448/UberHLD.drawio.png&quot; width=&quot;592&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;p&gt;&lt;br /&gt;&lt;b&gt;3. Performance:&lt;/b&gt;&lt;/p&gt;&lt;p&gt;We need to match Rider to Driver with 10 seconds. Let&#39;s see what are major steps we have for match:&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;ol style=&quot;text-align: left;&quot;&gt;&lt;li&gt;Get the closest drivers list to the rider.&lt;/li&gt;&lt;li&gt;Get the ETA of these drivers from third party service.&lt;/li&gt;&lt;li&gt;Take the Driver with the lowest ETA.&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;If you see we can&#39;t do anything about step 2 and step 3 is fairly simple. Let&#39;s see how we can get the list of closest drivers.&lt;/p&gt;&lt;p&gt;We need to calculate the distance of every free/in_trip driver with the user&#39;s location which is fairly expensive. Say somehow we are able to apply certain index on Location DB over Lat and Long (I am not sure how we will use it), it still be very expensive.&lt;/p&gt;&lt;p&gt;Also these floating point calculations are little time consuming for computers. It looks like we won&#39;t able to achieve our ETA.&lt;/p&gt;&lt;p&gt;We will use &lt;a href=&quot;https://en.wikipedia.org/wiki/Geohash&quot; target=&quot;_blank&quot;&gt;Geohash&lt;/a&gt; here to divide the earch into geo cells. Now these geo cell ids will be stored in the Location DB as per the driver locations. That means we are going to add a new column geo_cell_id in the Location DB.&lt;/p&gt;&lt;p&gt;Now the circle which we are drawing centered at User&#39;s location can have around 3 or 4 geo cells. Here is how the flow looks like for the step 1 of getting the closes drivers:&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;Get the geo cell id as per the user&#39;s location.&lt;/li&gt;&lt;li&gt;Get all the geo cell ids which is covered by 2 KM radius circle&lt;/li&gt;&lt;li&gt;Now the query to DB will be something like SELECT * from Location where geo_cell_ids in [list of geo cells]&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;To make the above query we can &lt;i&gt;shard the Location DB based on geo_cell_id&lt;/i&gt; or create a &lt;i&gt;hash index&lt;/i&gt; over it.&lt;/p&gt;&lt;p&gt;That&#39;s all about the performance. Now that we have covered every functional and non function requirements, here is our final architectural diagram:&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjEiTLT6BAAt6QCDYG3aq1ow4BiRAuE7cG5UWyCcWpkt0CimlPNMZ4KXWr_7P4W7wOMOQlO4vCfi1szQ380YQRN_HOHPNUSFy3Ye9ls_j-wyT2MoxEZoA53aRo0uynTmkUOI2XrWBjPX18hd8uJldxAbg21sHmI6zxPrItZI4tFQGMjHZyRkGX6iI69MXo/s1511/UberHLD.drawio.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;1141&quot; data-original-width=&quot;1511&quot; height=&quot;474&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjEiTLT6BAAt6QCDYG3aq1ow4BiRAuE7cG5UWyCcWpkt0CimlPNMZ4KXWr_7P4W7wOMOQlO4vCfi1szQ380YQRN_HOHPNUSFy3Ye9ls_j-wyT2MoxEZoA53aRo0uynTmkUOI2XrWBjPX18hd8uJldxAbg21sHmI6zxPrItZI4tFQGMjHZyRkGX6iI69MXo/w627-h474/UberHLD.drawio.png&quot; width=&quot;627&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;I know the diagram became a bit messy so I&#39;ll improve it later!&lt;/p&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://algods-cracker.blogspot.com/feeds/7530468713728326855/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://algods-cracker.blogspot.com/2024/10/design-uber.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7496974970329409400/posts/default/7530468713728326855'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7496974970329409400/posts/default/7530468713728326855'/><link rel='alternate' type='text/html' href='http://algods-cracker.blogspot.com/2024/10/design-uber.html' title='Design Uber'/><author><name>Nishant Saxena</name><uri>http://www.blogger.com/profile/17860524009847591950</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjOdjS62BAEI1iMG_zd6lew4qyFGpfJhWHp0AJWQhiJvxQpSGg0AFZ5euJG7tK0D-EGQFno32hF-i1x4E2A49re_8-b9r0QHwXQ-9X_EvlAcekIjUYMaA1v6dWzDqzkBg/s220/2d230a1.jpg'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjs9F-1u6BCGQDEO1TNpO5l28VMfjFHjrJ-as6OutwoTaHv2ui_QFGQj61l8uU452NKoj0fNFfS_lZVv3yyfplhiI6FINmQ7t3ZtiiM9GWbLH1Ps20P8-koCYYCvZFebJUJksNb1xBrBeQDr4CmaidNW4AoaYqRtdUxQ01583ktqKeY5v_iZD25SDGVVUQ/s72-w439-h977-c/UberSeqDiag.png" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7496974970329409400.post-802455555675491406</id><published>2024-10-28T02:22:00.021+05:30</published><updated>2024-10-28T15:24:17.048+05:30</updated><category scheme="http://www.blogger.com/atom/ns#" term="System Design"/><title type='text'>Design Youtube</title><content type='html'>&lt;p&gt;&lt;b&gt;Problem:&lt;/b&gt; Design a highly scalable video on demand (VOD) streaming platform.&lt;/p&gt;&lt;p&gt;&lt;b&gt;Requirements:&lt;/b&gt;&lt;/p&gt;&lt;p&gt;Before we jump into requirements, we should realize we have two different types of users:&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;Content creators&lt;/li&gt;&lt;li&gt;Viewers&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;If we try to observe how they use our platform, we can see the requirements are different both functional as well as nonfunctional requirements.&lt;/p&gt;&lt;p&gt;&lt;b&gt;1. Functional requirements:&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;a. Content creators:&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;ol style=&quot;text-align: left;&quot;&gt;&lt;li&gt;Upload any format/codec video.&lt;/li&gt;&lt;ul&gt;&lt;li&gt;Once the video is uploaded, it can be deleted but not be modified.&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;Each video should have metadata:&lt;/li&gt;&lt;ul&gt;&lt;li&gt;Mandatory: title, author, description.&lt;/li&gt;&lt;li&gt;Optional: List of categories / tags.&lt;/li&gt;&lt;li&gt;Metadata can be updated anytime.&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;Get an email notification when the video is available publically.&lt;/li&gt;&lt;li&gt;Live streaming is not supported.&lt;/li&gt;&lt;/ol&gt;&lt;b&gt;&lt;p&gt;&lt;b&gt;b. Viewers:&lt;/b&gt;&lt;/p&gt;&lt;/b&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;ol style=&quot;text-align: left;&quot;&gt;&lt;li&gt;Only registered users can view the content.&lt;/li&gt;&lt;li&gt;Can search using free text in all of video metadata.&lt;/li&gt;&lt;li&gt;Can watch vidoes on any kind of device (desktop / phone / TV) and network conditions.&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;2. Nonfunctional requirements:&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;a. Content creators:&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;ol style=&quot;text-align: left;&quot;&gt;&lt;li&gt;&lt;b&gt;Scalability:&lt;/b&gt;&lt;/li&gt;&lt;ul&gt;&lt;li&gt;Thousands of content creators.&lt;/li&gt;&lt;li&gt;Upload 1video/week per creator&lt;/li&gt;&lt;li&gt;Average video size ~50 GB (50 TB / week)&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;&lt;b&gt;Consistency:&lt;/b&gt;&lt;/li&gt;&lt;ul&gt;&lt;li&gt;We prefer to have consistency here over availability.&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;&lt;b&gt;Availability:&lt;/b&gt;&lt;/li&gt;&lt;ul&gt;&lt;li&gt;99.9 percentile&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;&lt;b&gt;Performance:&lt;/b&gt;&lt;/li&gt;&lt;ul&gt;&lt;li&gt;Response time of page load &amp;lt; 500 ms at 99 percentile.&lt;/li&gt;&lt;li&gt;Video becomes available to view in hours.&lt;/li&gt;&lt;/ul&gt;&lt;/ol&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;b. Viewers:&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;ol style=&quot;text-align: left;&quot;&gt;&lt;li&gt;&lt;b&gt;Scalability:&lt;/b&gt;&lt;/li&gt;&lt;ul&gt;&lt;li&gt;100K-200K daily active users&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;&lt;b&gt;Availability:&lt;/b&gt;&lt;/li&gt;&lt;ul&gt;&lt;li&gt;99.99 percentile&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;&lt;b&gt;Performance:&lt;/b&gt;&lt;/li&gt;&lt;ul&gt;&lt;li&gt;Search results and page loads &amp;lt; 500 ms at 99 percentile&lt;/li&gt;&lt;li&gt;Zero buffer time for video play&lt;/li&gt;&lt;/ul&gt;&lt;/ol&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;Design:&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;Step 1: API design:&lt;/b&gt;&lt;/p&gt;&lt;p&gt;As usual, for the api design let&#39;s first translate our functional requirements in a sequence diagram which should look like follows:&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/a/AVvXsEj7chLWdWfhSYeAOlMBbhalagfS2pvnMKykuL--ufl4Jth11J5nYRMf-eEh5nA4qpmWjL8Hb21EvRnSOCjDZrxuGDcEw3-IHcmiWBsrdQa7EL96XZBEXoXEIsvdkfrpIKKjdemf4y-UjRhL_qodobR78CrImA5QeViAapmceU76nzzBiTI_nxTNFfuXyrY&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img alt=&quot;&quot; data-original-height=&quot;1069&quot; data-original-width=&quot;517&quot; height=&quot;618&quot; src=&quot;https://blogger.googleusercontent.com/img/a/AVvXsEj7chLWdWfhSYeAOlMBbhalagfS2pvnMKykuL--ufl4Jth11J5nYRMf-eEh5nA4qpmWjL8Hb21EvRnSOCjDZrxuGDcEw3-IHcmiWBsrdQa7EL96XZBEXoXEIsvdkfrpIKKjdemf4y-UjRhL_qodobR78CrImA5QeViAapmceU76nzzBiTI_nxTNFfuXyrY=w299-h618&quot; width=&quot;299&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Now we can easily identify the entities and URIs using above sequence diagram:&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;Users&lt;/li&gt;&lt;ul&gt;&lt;li&gt;/users&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;Videos:&lt;/li&gt;&lt;ul&gt;&lt;li&gt;/videos&lt;/li&gt;&lt;li&gt;/videos/{video_id}&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;Search:&lt;/li&gt;&lt;ul&gt;&lt;li&gt;/search&lt;/li&gt;&lt;/ul&gt;&lt;/ul&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;Now let&#39;s put HTTP method:&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;Users:&lt;/li&gt;&lt;ul&gt;&lt;li&gt;POST /users: Create / register user&lt;/li&gt;&lt;li&gt;POST /users/login: Login a user&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;Videos:&lt;/li&gt;&lt;ul&gt;&lt;li&gt;POST /videos: Start upload a data&lt;/li&gt;&lt;li&gt;PUT /videos/{video_id}/metadata: Create/update metadata of video&lt;/li&gt;&lt;li&gt;GET /videos/{video_id}: Get the video url&lt;/li&gt;&lt;li&gt;POST /videos/{video_id}/play: Send the video content to client&lt;/li&gt;&lt;li&gt;DELETE /videos/{video_id}: Delete a video&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;Search:&lt;/li&gt;&lt;ul&gt;&lt;li&gt;GET /search&lt;/li&gt;&lt;/ul&gt;&lt;/ul&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;Step 2: Mapping functional requirements to architectural diagram:&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;a.1 Content creator can upload any format/codec video:&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;b.3 Viewers can watch video on any device and at different network conditions:&lt;/b&gt;&lt;/p&gt;&lt;p&gt;I am taking both of these requirements together as these are inter related. We need to upload any video in such a manner that it can be supported on any device and adapted to different network conditions to view.&lt;/p&gt;&lt;p&gt;Let&#39;s first understand what is a video file.&amp;nbsp;&lt;/p&gt;&lt;p&gt;The video file is a container which contains:&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;Video stream&lt;/li&gt;&lt;li&gt;Audio stream&lt;/li&gt;&lt;li&gt;Subtitles&lt;/li&gt;&lt;li&gt;Metadata like codec, bitrate, resolution, frame rate&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;The binary representation of these containers like mpg/avi/mp4 can be different based on how these streams are encoded and algos to encode and decode these streams are called codecs like H.264 or AV1 or VP9 etc.&lt;/p&gt;&lt;p&gt;The video captured using a camera is encoded based on lossless compression algorithm which makes it suitable for professional editing but it is too big in size so this kind of codec is not suitable for streaming and storage at scale so the first step is too apply a lossy compression algorirthm. This method of converting a encoded stream to a different encoded stream is called &lt;i&gt;Transcoding&lt;/i&gt;.&lt;/p&gt;&lt;p style=&quot;text-align: center;&quot;&gt;&lt;i&gt;Size of a video = Bit rate (bits/second) * Video length (seconds)&lt;/i&gt;&lt;/p&gt;&lt;p&gt;So this is obvious that we need to reduce the bit rate in order to reduce the size of video but given that we need to support different devices and different network bandwidth. We can&#39;t depend on only one bit rate. We need to support multiple outputs file supporting different bit rates which is directly proportonal to resolutions. The standard resolutions are 360p, 640p, 720p, 1080p and 4K.&lt;/p&gt;&lt;p&gt;This will partially take care of supporting multiple devices but it won&#39;t support varying network conditions like home network getting used by multiple users or the user is travelling. To support this requirement, we will use technique called Adaptive bit rate or &lt;a href=&quot;https://en.wikipedia.org/wiki/Adaptive_bitrate_streaming&quot; target=&quot;_blank&quot;&gt;Adaptive streaming&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;In &lt;i&gt;Adaptive streaming&lt;/i&gt;, we break our stream into multiple small &lt;i&gt;chunks of size say 5 seconds or 10 seconds&lt;/i&gt;. We put references to all of these streams in a text file called &lt;i&gt;manifest&lt;/i&gt;(mpd). When player tries to play the video. It first download this manifest file and then &lt;i&gt;choose a default resolution&amp;nbsp;&lt;/i&gt;(say 720p) and play it&#39;s say first 4-5 chunks to analyze how the network conditions are. If the network conditions are better it switches to better resolution say 1080p or even 4K. It there are download delays then it goes for lesser resolution chunks. &lt;i&gt;Player&lt;/i&gt; &lt;i&gt;keeps analysing the chunks download speed to decide which resolution to go for&lt;/i&gt;.&lt;/p&gt;&lt;p&gt;The next step is to fully support every kind of devices. For this we need to package our video content to support different streaming protocols. Different OS / browser supports different protocols. Here we can also apply &lt;a href=&quot;https://en.wikipedia.org/wiki/Digital_rights_management&quot; target=&quot;_blank&quot;&gt;DRM&lt;/a&gt;(Digital Rights Management) to protect our video in order to support &lt;b&gt;FR# b.1 Only registered users can watch the video&lt;/b&gt;. Using DRM we can also support subscrption when we want to intoduce it.&lt;/p&gt;&lt;p&gt;Now if you see there are steps which we need to take in order to upload the video and making it available for different devices and different locations / network bandwidth. We will use &lt;i&gt;pipes and filter pattern&lt;/i&gt; here to support it.&amp;nbsp;&lt;/p&gt;&lt;p&gt;We will have a &lt;i&gt;Video service &lt;/i&gt;as public interface for this whole activity. This service will have it&#39;s own DB which is NoSql DB in order to support fluid schema. So here is the flow of video upload:&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;ol style=&quot;text-align: left;&quot;&gt;&lt;li&gt;Content creator call Video service to upload video.&lt;/li&gt;&lt;li&gt;Video service will start the upload to object store asynchronously and save the metadata into it&#39;s DB and return the confirmation to user with video id.&lt;/li&gt;&lt;li&gt;Once the video upload is complete to object store, it queues this message to a new service &lt;i&gt;Transcoding service&lt;/i&gt;.&lt;/li&gt;&lt;li&gt;Transcoding service first convert this video to 5-10 seconds chunks and transcode each chunk into multiple resolution and upload it into it&#39;s object store. It also generates manifest file for adaptive streaming.&lt;/li&gt;&lt;li&gt;Transcoding service now queue the message to new service say &lt;i&gt;Packaging service&lt;/i&gt;.&lt;/li&gt;&lt;li&gt;Packaging service package these streams according to streaming protocols and save it into it&#39;s own object store.&lt;/li&gt;&lt;li&gt;Package service now queue the video_id and video_url(which is ultimately manifest download) back to Video service and video service updates it&#39;s DB using the video_id.&amp;nbsp;&amp;nbsp;&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;We can debate over a point on Transcoding service where we can propose a new service to break the uncompressed video in chunks, queue these chunks to let transcoding service just transcode these chunks in parallel. But that&#39;s what we can achieve using multithreading in the transcoding service itself. In that way it will be much easiser to debug issues and also much easier to support the restartabilty as all these chunkings and transcoding will happen in just one service.&lt;/p&gt;&lt;p&gt;We can support &lt;b&gt;FR# a.3 Notify creatore when video is publically available&lt;/b&gt; here only by adding a new service say &lt;i&gt;Notification service&lt;/i&gt;. Video service will queue the video details to this service. Notification service now can send the notification (email) to content creator.&lt;/p&gt;&lt;p&gt;With this knowlege let&#39;s see how our architectural diagram looks like.&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/a/AVvXsEiZcxj9zlt98r9SDWywLGG3i-qEfO6fKxulrjvXieRcjQua71VaTtrGEe_Ho7ikorejO6OZyBO3dcuoPe80KxHXRlYJBZxhcXZ_peZkc7DkbFfMkQl2hJt95R4YnqyfSnj-jXCkpdA9UZNDtm6eBPOFL5W_r_CJ_Y5DjUOBG1AxB0O0_gc5UVAWCR8ul1A&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img alt=&quot;&quot; data-original-height=&quot;1021&quot; data-original-width=&quot;941&quot; height=&quot;467&quot; src=&quot;https://blogger.googleusercontent.com/img/a/AVvXsEiZcxj9zlt98r9SDWywLGG3i-qEfO6fKxulrjvXieRcjQua71VaTtrGEe_Ho7ikorejO6OZyBO3dcuoPe80KxHXRlYJBZxhcXZ_peZkc7DkbFfMkQl2hJt95R4YnqyfSnj-jXCkpdA9UZNDtm6eBPOFL5W_r_CJ_Y5DjUOBG1AxB0O0_gc5UVAWCR8ul1A=w430-h467&quot; width=&quot;430&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;a.2 Update the video metadata:&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;a.1 Delete the video:&lt;/b&gt;&lt;/p&gt;&lt;p&gt;User can simply call the video service to perform these opeations so now here is how the diagram looks like&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/a/AVvXsEj1J9jcvqIzw995CmlJNnMbo7CYn3v48gvAdfBN1or3lRmhkJCyqEFV3L9gOICTIp-BIlDZgFBiXqRkhzcvNrG96Ea16xITvEFep0JZ7cNTKwEWUiWbJr_-aDjIhVUsoTKErheUNtV5yKe1pPlMjiWXQ8fAOylu7LBfmtVmC5_gUVE0dRQzrcCLkZ4EwKo&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img alt=&quot;&quot; data-original-height=&quot;1021&quot; data-original-width=&quot;941&quot; height=&quot;466&quot; src=&quot;https://blogger.googleusercontent.com/img/a/AVvXsEj1J9jcvqIzw995CmlJNnMbo7CYn3v48gvAdfBN1or3lRmhkJCyqEFV3L9gOICTIp-BIlDZgFBiXqRkhzcvNrG96Ea16xITvEFep0JZ7cNTKwEWUiWbJr_-aDjIhVUsoTKErheUNtV5yKe1pPlMjiWXQ8fAOylu7LBfmtVmC5_gUVE0dRQzrcCLkZ4EwKo=w430-h466&quot; width=&quot;430&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;b.2 Viewer can search for the video against the video metadata:&lt;/b&gt;&lt;/p&gt;&lt;p&gt;To support search we need to have a different service say &lt;i&gt;Search service&lt;/i&gt; whose DB is optimized for search like Elastic search. Video service can queue the metadata to this service so you can assume it will also become the part of video upload / update of metdata / deletion of metadata.&amp;nbsp;&lt;/p&gt;&lt;p&gt;We also need to use pagination here.&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/a/AVvXsEg9Q8cX3QXyvdTJCGclvD6X2i2mYqYSIsVM7Iwvk5a5owgcauw6BnsuNlovjxPirQpAwicRylk5SZ1-tAks_84NAzxgIheRTnc6X5zOAsV44S7ISm2DXlopaaweLtd0ZStjC-pCObwO_YiRk7vC_fx4xQY_9pny7UOF22DmJIfLbRIkHcp1yuLW6xWthbI&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img alt=&quot;&quot; data-original-height=&quot;1021&quot; data-original-width=&quot;1036&quot; height=&quot;445&quot; src=&quot;https://blogger.googleusercontent.com/img/a/AVvXsEg9Q8cX3QXyvdTJCGclvD6X2i2mYqYSIsVM7Iwvk5a5owgcauw6BnsuNlovjxPirQpAwicRylk5SZ1-tAks_84NAzxgIheRTnc6X5zOAsV44S7ISm2DXlopaaweLtd0ZStjC-pCObwO_YiRk7vC_fx4xQY_9pny7UOF22DmJIfLbRIkHcp1yuLW6xWthbI=w452-h445&quot; width=&quot;452&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;b.3. Watch video on any device:&lt;/b&gt;&lt;/p&gt;&lt;p&gt;We have already done enough to support this requirement. Client first need to call Video service to get the video_url. Client then downloads the manifest file and then client/player will directly stream the chunks of video from object store as per adaptive streaming which I have already explained.&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/a/AVvXsEiNlF3lKrJD4F4t09D6NvNyHrLIpGM2UcrXqh5fpWFDrZSe-afkE_IagZlNvg0IJsM5nUuNzZtEyY0qlcHzje0gXqT2dYXAkAssLqRt8Sw92S56useuG6OiePFTKVOGpfSufSJvIfzi69gUnzEnaIjXPwn2nS05NLPfvv7VJx8rlv04J5LBJ22uAnoyrko&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img alt=&quot;&quot; data-original-height=&quot;1078&quot; data-original-width=&quot;1036&quot; height=&quot;509&quot; src=&quot;https://blogger.googleusercontent.com/img/a/AVvXsEiNlF3lKrJD4F4t09D6NvNyHrLIpGM2UcrXqh5fpWFDrZSe-afkE_IagZlNvg0IJsM5nUuNzZtEyY0qlcHzje0gXqT2dYXAkAssLqRt8Sw92S56useuG6OiePFTKVOGpfSufSJvIfzi69gUnzEnaIjXPwn2nS05NLPfvv7VJx8rlv04J5LBJ22uAnoyrko=w490-h509&quot; width=&quot;490&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&amp;nbsp;So now we are done with every functional requirement we have.&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;Step 3: Mapping non functional requirements to architectural diagram:&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;a.1 Content creator scalability:&lt;/b&gt;&lt;/p&gt;&lt;p&gt;There is not much to do in terms scalability for the first scalability requirement as the frequency of video upload is not much (1/week/user) That means ~10K video uploads in a week. However it can happen that at a particular time we can get thousands of upload requests. To support those we can have multiple instances of Video service and Web app service.&amp;nbsp;&lt;/p&gt;&lt;p&gt;To tackle the &lt;i&gt;video size we have already created a pipeline to compress the video size&lt;/i&gt; but there is still one problem;&amp;nbsp;&lt;/p&gt;&lt;p&gt;If we take the whole video content to first video service and then upload it to object store, this whole process will consume lot&#39;s of resources and as it can take hours to upload uncompressed video, we might end up scaling video service too much.&amp;nbsp;&lt;/p&gt;&lt;p&gt;To resolve the problem we can use &lt;i&gt;presigned urls&lt;/i&gt; of object store. Presigned urls are the urls with limited permissions and limited time. With presigned urls, the flow of video upload looks like as below:&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;ol style=&quot;text-align: left;&quot;&gt;&lt;li&gt;Client send request for video upload to video service.&lt;/li&gt;&lt;li&gt;Video service requests presigned url from object store with it&#39;s own permissions.&lt;/li&gt;&lt;li&gt;Send the presigned url as response of video upload API to the client.&lt;/li&gt;&lt;li&gt;Client now directly upload the video to object store using presigned url.&amp;nbsp;&lt;/li&gt;&lt;li&gt;Rest of the pipeline remains same.&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;With this flow, we can see Video service doesn&#39;t have to scale and we will save lot&#39;s of resources so now with these changes here is how architecture diagram looks like:&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/a/AVvXsEgLliBZjuUcBc6VaDZ1q96_zTFDJhMXZ7yjIiXd4MegFOt07mOUfXEI0xLU7yKksySUlvk2jynJ40XIjja2DDUQgdhUFw1LNMdkNlglI4W22su9VRsmT5zG25GorBBfimUfchhSLPU6yTgUsBfo1bnBdBwExSopEKSQQMvvlZfkiMXVTbPSqXtSnOIKUAU&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img alt=&quot;&quot; data-original-height=&quot;1078&quot; data-original-width=&quot;1036&quot; height=&quot;553&quot; src=&quot;https://blogger.googleusercontent.com/img/a/AVvXsEgLliBZjuUcBc6VaDZ1q96_zTFDJhMXZ7yjIiXd4MegFOt07mOUfXEI0xLU7yKksySUlvk2jynJ40XIjja2DDUQgdhUFw1LNMdkNlglI4W22su9VRsmT5zG25GorBBfimUfchhSLPU6yTgUsBfo1bnBdBwExSopEKSQQMvvlZfkiMXVTbPSqXtSnOIKUAU=w532-h553&quot; width=&quot;532&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;a.2 Content creator availability:&lt;/b&gt;&lt;/p&gt;&lt;p&gt;We have already take care of the availabity using the multiple instances of web app and video services. We can use the cloud native services for video transcoding and packaging like &lt;a href=&quot;https://aws.amazon.com/mediaconvert/&quot; target=&quot;_blank&quot;&gt;AWS Elemental MediaConvert&lt;/a&gt; and &lt;a href=&quot;https://aws.amazon.com/mediapackage/&quot; target=&quot;_blank&quot;&gt;AWS Elemental MediaPackage&lt;/a&gt; to support the availability.&lt;/p&gt;&lt;p&gt;We can replicate the Video service DB to support the availability.&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/a/AVvXsEgYM1cJyucPdXi4v1j9MIRoyaaeYg4hG0LMM7jla4VIPon3Wa3I6yKhji3yCkRavtWYKmgwkW17tbUhMPS-NKeb5EIKdz2Vi8OVaFKhk8c6QLxyQD6JU6gZpNhuEBqlqG14kvJW2Clgw4CIVbZA4rEbOXeaqxurAt_Jykl8Q0a0mSvLGwYFOE4DfSr7mtk&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img alt=&quot;&quot; data-original-height=&quot;1078&quot; data-original-width=&quot;1094&quot; height=&quot;544&quot; src=&quot;https://blogger.googleusercontent.com/img/a/AVvXsEgYM1cJyucPdXi4v1j9MIRoyaaeYg4hG0LMM7jla4VIPon3Wa3I6yKhji3yCkRavtWYKmgwkW17tbUhMPS-NKeb5EIKdz2Vi8OVaFKhk8c6QLxyQD6JU6gZpNhuEBqlqG14kvJW2Clgw4CIVbZA4rEbOXeaqxurAt_Jykl8Q0a0mSvLGwYFOE4DfSr7mtk=w553-h544&quot; width=&quot;553&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;a.3 Content Creator Performance:&lt;/b&gt;&lt;/p&gt;&lt;p&gt;We have already taken care of the performance as there is not much to do. However the only problem is when all/many content creators try to upload videos at the same time. In such scenario, we might not able to complete the video upload pipeline in hours.&amp;nbsp;&lt;/p&gt;&lt;p&gt;We need to parallelize this process. That means we need to have multiple instances of Transcoding service and Packaging service.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/a/AVvXsEi7gGQbi0qwnQMOGncAKPCyIpBg6ejHAXU3aHk5Kej2EC5i1pNGLwvR5sYdX8liHJO0P7MFu9n0URjDJ-F-rbp6376Zo6woEdXCcRaU2B_vwKJrIPH_PlGZWVNJqU86KvnBXIDHFWUWpZvlrBIQ07u26uHpQW0VXbRu0kCjkbsodJ3R-shzbz0FsqbyVKk&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img alt=&quot;&quot; data-original-height=&quot;1078&quot; data-original-width=&quot;1094&quot; height=&quot;535&quot; src=&quot;https://blogger.googleusercontent.com/img/a/AVvXsEi7gGQbi0qwnQMOGncAKPCyIpBg6ejHAXU3aHk5Kej2EC5i1pNGLwvR5sYdX8liHJO0P7MFu9n0URjDJ-F-rbp6376Zo6woEdXCcRaU2B_vwKJrIPH_PlGZWVNJqU86KvnBXIDHFWUWpZvlrBIQ07u26uHpQW0VXbRu0kCjkbsodJ3R-shzbz0FsqbyVKk=w543-h535&quot; width=&quot;543&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;a.4 Content Creator CP over AP:&lt;/b&gt;&lt;/p&gt;&lt;p&gt;To achieve this we just need to choose the right Video service DB or DB&#39;s configuration which supports consistency over availability. That&#39;s all!&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;b.1 Viewers Scalability:&lt;/b&gt;&lt;/p&gt;&lt;p&gt;To support this 100K - 200K user visits we have already scale our web app service and video service but to scale the search functionality, we need to have multiple instances of search service. This will take care of the scalabilty of service.&amp;nbsp;&lt;/p&gt;&lt;p&gt;As elastic search is not cloud native, we can use AWS opensearch / Elastic cloud on AWS which autoscale itself.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/a/AVvXsEipsBTG2Umv9Fl0zQDDmZnklAYazJ4YK6XW-9E9aMXwyz5puUTLU8omuH5ZixzM_o2GOPxMUEEcj71C5GJ40hXExOC86eENdfA-PFO2KyjSxqOrfE7SJlVvKCgZPtUIbwHnKYo06S2BuGYq_vwO3_UtRM3pu-Xmmi3KxtJ5eQKQIuKMTqTSyUVoL-h09n0&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img alt=&quot;&quot; data-original-height=&quot;1078&quot; data-original-width=&quot;1094&quot; height=&quot;559&quot; src=&quot;https://blogger.googleusercontent.com/img/a/AVvXsEipsBTG2Umv9Fl0zQDDmZnklAYazJ4YK6XW-9E9aMXwyz5puUTLU8omuH5ZixzM_o2GOPxMUEEcj71C5GJ40hXExOC86eENdfA-PFO2KyjSxqOrfE7SJlVvKCgZPtUIbwHnKYo06S2BuGYq_vwO3_UtRM3pu-Xmmi3KxtJ5eQKQIuKMTqTSyUVoL-h09n0=w568-h559&quot; width=&quot;568&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;b.2 Viewers Availability:&amp;nbsp;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;We have done mostly everything for the availability but as here our availability requirement is high. We can use &lt;i&gt;muti region deployment&lt;/i&gt; and a &lt;i&gt;global load balancer&lt;/i&gt; too. This will also help with the &lt;i&gt;performance&lt;/i&gt;.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;b.3. Viewers Performance:&lt;/b&gt;&lt;/p&gt;&lt;p&gt;We are using adaptive bitrate streaming for the zero buffer time but as you see still we need to download intial chunks, we need to go to object store which might be expensive so we can use &lt;i&gt;CDN&lt;/i&gt;&amp;nbsp;to provide it. We can have initial chunks in the CDN to increase the performance of download and then the client can use adaptive streaming to go for the right chunks.&lt;/p&gt;&lt;p&gt;Please note that we can put the whole video too on the CDN which will definitely improve the performance and the quality of the video but it can be very expensive so I am still opting for initial chunks of videos.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/a/AVvXsEj2F-qVgrSHo0P0S1Wq4MQgNcZ7uMfgU4qpMPDrFclbLn0qUR_TZVB5TnAzv-S5KbZt-TIcM4IdmN7CYPItetDrKqXZkAGY4NHp1s-Xe6Da7-xk8AX522y0Yql8V9Gcoju_a2NzKRsANWywIe6ry9xgorRX613SDblHlxf0A7t_ups-IuKUO9LTdb2jhWY&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img alt=&quot;&quot; data-original-height=&quot;1218&quot; data-original-width=&quot;1095&quot; height=&quot;657&quot; src=&quot;https://blogger.googleusercontent.com/img/a/AVvXsEj2F-qVgrSHo0P0S1Wq4MQgNcZ7uMfgU4qpMPDrFclbLn0qUR_TZVB5TnAzv-S5KbZt-TIcM4IdmN7CYPItetDrKqXZkAGY4NHp1s-Xe6Da7-xk8AX522y0Yql8V9Gcoju_a2NzKRsANWywIe6ry9xgorRX613SDblHlxf0A7t_ups-IuKUO9LTdb2jhWY=w592-h657&quot; width=&quot;592&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&amp;nbsp;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;b.4. Viewer AP over CP:&lt;/b&gt;&lt;/p&gt;&lt;p&gt;We are already using lot&#39;s of async operations / message broker which guarantees availability but eventual consistency. For search we are already receiving metadata updates using queue and also Elastic search provides AP over CP so this requirement is already satisfied.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;With this we are done with every functional and non functional requirements and here is how our final architectural diagram looks like:&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/a/AVvXsEizrsS2m9cTcg4NiGIxc1yoBZEBfAUvt8UNqV1k4DFCZqVy3JDU38ZM8QmT_JfFlbQbcStLjD3Fy107fMnSLkmvHj7f1-DeuL8w2ICaBumolBPp8uq09FjL3NZsiPQRl878lBfmqREQmV9MyvdCLXCdkXHy9z7DNN9FDy0h-oR37mFqhFtmk9V4_31ZvQE&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img alt=&quot;&quot; data-original-height=&quot;1218&quot; data-original-width=&quot;1095&quot; height=&quot;675&quot; src=&quot;https://blogger.googleusercontent.com/img/a/AVvXsEizrsS2m9cTcg4NiGIxc1yoBZEBfAUvt8UNqV1k4DFCZqVy3JDU38ZM8QmT_JfFlbQbcStLjD3Fy107fMnSLkmvHj7f1-DeuL8w2ICaBumolBPp8uq09FjL3NZsiPQRl878lBfmqREQmV9MyvdCLXCdkXHy9z7DNN9FDy0h-oR37mFqhFtmk9V4_31ZvQE=w607-h675&quot; width=&quot;607&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;p&gt;That&#39;s all!&lt;/p&gt;&lt;p&gt;* Please note that here we should have a &lt;i&gt;User service&lt;/i&gt; to support user login and registration but that&#39;s very obvious so I have not discussed it here. Given the user&#39;s volume is in hundreds of thousand, we don&#39;t need to do many things.&lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='http://algods-cracker.blogspot.com/feeds/802455555675491406/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://algods-cracker.blogspot.com/2024/10/design-youtube.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7496974970329409400/posts/default/802455555675491406'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7496974970329409400/posts/default/802455555675491406'/><link rel='alternate' type='text/html' href='http://algods-cracker.blogspot.com/2024/10/design-youtube.html' title='Design Youtube'/><author><name>Nishant Saxena</name><uri>http://www.blogger.com/profile/17860524009847591950</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjOdjS62BAEI1iMG_zd6lew4qyFGpfJhWHp0AJWQhiJvxQpSGg0AFZ5euJG7tK0D-EGQFno32hF-i1x4E2A49re_8-b9r0QHwXQ-9X_EvlAcekIjUYMaA1v6dWzDqzkBg/s220/2d230a1.jpg'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/a/AVvXsEj7chLWdWfhSYeAOlMBbhalagfS2pvnMKykuL--ufl4Jth11J5nYRMf-eEh5nA4qpmWjL8Hb21EvRnSOCjDZrxuGDcEw3-IHcmiWBsrdQa7EL96XZBEXoXEIsvdkfrpIKKjdemf4y-UjRhL_qodobR78CrImA5QeViAapmceU76nzzBiTI_nxTNFfuXyrY=s72-w299-h618-c" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7496974970329409400.post-1160289488736251855</id><published>2024-10-18T19:52:00.008+05:30</published><updated>2024-10-27T14:42:42.079+05:30</updated><category scheme="http://www.blogger.com/atom/ns#" term="System Design"/><title type='text'>Design Instagram</title><content type='html'>&lt;p&gt;&lt;b&gt;Problem:&lt;/b&gt; Design highly scalabale image sharing social media platform like instagram.&lt;/p&gt;&lt;p&gt;&lt;b&gt;Requirements:&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;1. Functional Requirements:&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;ol style=&quot;text-align: left;&quot;&gt;&lt;li&gt;Only registered user can access the platform. They need to provide following info while registering:&lt;/li&gt;&lt;ul&gt;&lt;li&gt;Mandatory: first name, last name, email, phone number, profile image, password&lt;/li&gt;&lt;li&gt;Optional: age, sex, location, interests etc.&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;User can share/post only images&lt;/li&gt;&lt;ul&gt;&lt;li&gt;We need to design it in a way to extend it to videos or text.&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;Search a user using different attibutes&lt;/li&gt;&lt;li&gt;Unidirectional relationship: User A follows User B does not mean User B also follows User A.&lt;/li&gt;&lt;li&gt;Load a timeline of latest images posted by people they follow sorted by recency in descending order&lt;/li&gt;&lt;/ol&gt;&amp;nbsp;&lt;br /&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;2. Non-functional Requirements:&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;ol style=&quot;text-align: left;&quot;&gt;&lt;li&gt;Scalability:&lt;/li&gt;&lt;ul&gt;&lt;li&gt;~1-2 billion active users&lt;/li&gt;&lt;li&gt;100-500 million visits / day&lt;/li&gt;&lt;li&gt;Each user uploads ~1 image / day&lt;/li&gt;&lt;li&gt;Each image size ~2 MB.&lt;/li&gt;&lt;li&gt;Data processing volume: ~1 PB / day&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;Availability: Prioritize availability over consistency as it is okay even if user does not see the latest data. We are targetting 99.99% here.&lt;/li&gt;&lt;li&gt;&amp;nbsp;Performance:&amp;nbsp;&lt;/li&gt;&lt;ul&gt;&lt;li&gt;Response time &amp;lt; 500 ms at 99 percentile.&lt;/li&gt;&lt;li&gt;Timeline load time &amp;lt;1000 ms at 99 percentile.&lt;/li&gt;&lt;/ul&gt;&lt;/ol&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;Design:&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;Step 1: API design:&lt;/b&gt;&lt;/p&gt;&lt;p&gt;For the api design, let&#39;s first translate our functional requirements in a sequence diagram which should look like follows:&lt;/p&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjmY-wlVvaeSELPeWVlsACDol3f4QdRsxZFd8_7GuzfPRY2VewjiQbwDAe6j5zbJ0D4JVx1nqctiQh5D7mCqKdJ8177vbHfYww6LEqXZ6h1Mw_-Pdh_77dB5FH10p_r7nBJd9Uk9X1F5Wzz9zhgifrFD9q80SLbna52hZ7EysTSQVTVq2A2reyzfT5u3Zw/s868/InstaSeqDiagram.png&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;868&quot; data-original-width=&quot;490&quot; height=&quot;657&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjmY-wlVvaeSELPeWVlsACDol3f4QdRsxZFd8_7GuzfPRY2VewjiQbwDAe6j5zbJ0D4JVx1nqctiQh5D7mCqKdJ8177vbHfYww6LEqXZ6h1Mw_-Pdh_77dB5FH10p_r7nBJd9Uk9X1F5Wzz9zhgifrFD9q80SLbna52hZ7EysTSQVTVq2A2reyzfT5u3Zw/w372-h657/InstaSeqDiagram.png&quot; width=&quot;372&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;p&gt;Now if you see above, we can easily identify the entities and URIs:&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;Users&lt;/li&gt;&lt;ul&gt;&lt;li&gt;/users&lt;/li&gt;&lt;li&gt;/users/{user-id}&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;Images&lt;/li&gt;&lt;ul&gt;&lt;li&gt;/images&lt;/li&gt;&lt;li&gt;/images/{image-id}&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;Search&lt;/li&gt;&lt;ul&gt;&lt;li&gt;/search&lt;/li&gt;&lt;/ul&gt;&lt;/ul&gt;Now let&#39;s put HTTP methods:&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;Users&amp;nbsp;&lt;/li&gt;&lt;ul&gt;&lt;li&gt;POST /users - Create user / register user&lt;/li&gt;&lt;li&gt;POST /users/login - Login a user&lt;/li&gt;&lt;li&gt;POST /users/{user-id}/follow - Follow a user&lt;/li&gt;&lt;li&gt;DELETE /users/{user-id}/follow - Unfollow a user&lt;/li&gt;&lt;li&gt;GET /users/{user-id}/timeline - Get user time line. This requires pagination.&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;Images&lt;/li&gt;&lt;ul&gt;&lt;li&gt;POST /images - Post an image&lt;/li&gt;&lt;li&gt;GET /images/{image-id} - Get an image&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;Search&lt;/li&gt;&lt;ul&gt;&lt;li&gt;Get /search - Search a user&lt;/li&gt;&lt;/ul&gt;&lt;/ul&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;Step 2: Mapping functional requirements to architectural diagram:&lt;/b&gt;&lt;/p&gt;&lt;p&gt;Before we move to our main functional requirements, I want to add a service say &quot;Web app service&quot; to serve the html pages since we have support on desktop web browser too.&lt;/p&gt;&lt;p&gt;&lt;b&gt;1. Registering user to our platform:&lt;/b&gt;&lt;/p&gt;&lt;p&gt;We will have a &lt;i&gt;User service&lt;/i&gt; with it&#39;s own DB which will help with login and registration of users. User service database will have following fields as per FR#1:&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;user_id&lt;/li&gt;&lt;li&gt;user_name&lt;/li&gt;&lt;li&gt;first_name&lt;/li&gt;&lt;li&gt;last_name&lt;/li&gt;&lt;li&gt;email&lt;/li&gt;&lt;li&gt;password&lt;/li&gt;&lt;li&gt;phone_number&lt;/li&gt;&lt;li&gt;profie_image_url&lt;/li&gt;&lt;li&gt;and some optional fields like age, sex, interests, location etc.&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;If you see we have so many optional fields which can change with time like some optional fields can be removed and some can be added. That means our schema is fluid and that&#39;s why we are going with &lt;i&gt;NoSql Document DB&lt;/i&gt;. Given we have around ~1-2 billions users, these schma changes become an considerable overhead.&lt;/div&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;In the schema we are storing the profile image url instead of profile image because DBs are not optimized for blob storage so what we will do is we will store the profile image into a blob store or &lt;i&gt;object store&lt;/i&gt; and then save the image url in our DB.&lt;/p&gt;&lt;p&gt;Once the registration is completed, client will get user id and auth token which will help client with further operations.&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/a/AVvXsEiaeRQDNqgy73TY6U0c40dq94CWi0mKd-k9LMGpHpUbNJjoQuzgDVywfP8-PFxrLEpNp9v78FdjU_M2y2tFbI7rZKhARNIKkm-eAK2G-KLK4SdtBrZvceJ5dOqe4OJSdYW7-2PdjLz0MqNrY8hTjmh4INr4UZ6fedV7SI5oXQDjW-YUr8fDuijr97NYHCU&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img alt=&quot;&quot; data-original-height=&quot;491&quot; data-original-width=&quot;831&quot; height=&quot;283&quot; src=&quot;https://blogger.googleusercontent.com/img/a/AVvXsEiaeRQDNqgy73TY6U0c40dq94CWi0mKd-k9LMGpHpUbNJjoQuzgDVywfP8-PFxrLEpNp9v78FdjU_M2y2tFbI7rZKhARNIKkm-eAK2G-KLK4SdtBrZvceJ5dOqe4OJSdYW7-2PdjLz0MqNrY8hTjmh4INr4UZ6fedV7SI5oXQDjW-YUr8fDuijr97NYHCU=w479-h283&quot; width=&quot;479&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;2. Post an image:&lt;/b&gt;&lt;/p&gt;&lt;p&gt;Let&#39;s have a post service for this service, we are not calling it as image service so that we can extend it to any type of post. This service will have it&#39;s own DB which contains the following fields:&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;post_id&lt;/li&gt;&lt;li&gt;user_id&lt;/li&gt;&lt;li&gt;post_url&lt;/li&gt;&lt;li&gt;timestamp&lt;/li&gt;&lt;li&gt;post_type - This will be by default image but can be extended to video etc.&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;Since this is a fixed schema, I am going to use SQL DB for storing this info. Here is the flow of image upload:&lt;/div&gt;&lt;div&gt;&lt;ol style=&quot;text-align: left;&quot;&gt;&lt;li&gt;User send the request to Post service to share an image&lt;/li&gt;&lt;li&gt;Post service send the image to object store&lt;/li&gt;&lt;li&gt;Object store return the url of uploaded image&lt;/li&gt;&lt;li&gt;Save the image metdata and url in the DB&lt;/li&gt;&lt;li&gt;Return confirmation to user.&lt;/li&gt;&lt;/ol&gt;&lt;div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/a/AVvXsEgvqrNzUIPHviSXAgE5r-XoubGHUbWkWd1XhzuP4-9F5CrkUAMnzTlVLkGeTL0ZrBZF5lcDozz5SEOr0-WqBeyqTVCM0pb2BKz64M9laraoqdIcosY7-I9bOBbTs3ACJnTyfa_8JLguA5wRJcOKeTavsRvPYralCNW-1L9J6cF6bFUmDnW493othP-je3E&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img alt=&quot;&quot; data-original-height=&quot;491&quot; data-original-width=&quot;831&quot; height=&quot;282&quot; src=&quot;https://blogger.googleusercontent.com/img/a/AVvXsEgvqrNzUIPHviSXAgE5r-XoubGHUbWkWd1XhzuP4-9F5CrkUAMnzTlVLkGeTL0ZrBZF5lcDozz5SEOr0-WqBeyqTVCM0pb2BKz64M9laraoqdIcosY7-I9bOBbTs3ACJnTyfa_8JLguA5wRJcOKeTavsRvPYralCNW-1L9J6cF6bFUmDnW493othP-je3E=w477-h282&quot; width=&quot;477&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;3. Search users using different attributes:&lt;/b&gt;&lt;/p&gt;&lt;p&gt;We can use the same user service to search the users but if you see this DB is not optimized for search As we don&#39;t know in advance what all the attributes are searchable or what kind of search we are going to support, it&#39;s better if we use a different service say &lt;i&gt;Search service&lt;/i&gt; with DB which is optimized for search scenario like &lt;i&gt;elastic search&lt;/i&gt; or other &lt;i&gt;lucene&lt;/i&gt; based DB.&lt;/p&gt;&lt;p&gt;So now whenever there is a new user added or there is an update in user&#39;s record we can &lt;i&gt;queue&lt;/i&gt; it to the search service. Search service will updates it&#39;s DB.&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/a/AVvXsEj1U3nXXcKQozqUO99MzNimaU-sdRpA8bOLG0PGnXFgkopgmxFoa3hsAC4su2ofqNYzVolCkTQatwW7agn_DSv6o3bXjfoTvmfyJEgYypxdWttIusgWgkA48QEUB6juAjUI0mbzOR5nC0FkCW7q6cbC1aezHHkMSPNSlmz5GI8WhiQRClWebXwpcMOcYSY&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img alt=&quot;&quot; data-original-height=&quot;576&quot; data-original-width=&quot;841&quot; height=&quot;317&quot; src=&quot;https://blogger.googleusercontent.com/img/a/AVvXsEj1U3nXXcKQozqUO99MzNimaU-sdRpA8bOLG0PGnXFgkopgmxFoa3hsAC4su2ofqNYzVolCkTQatwW7agn_DSv6o3bXjfoTvmfyJEgYypxdWttIusgWgkA48QEUB6juAjUI0mbzOR5nC0FkCW7q6cbC1aezHHkMSPNSlmz5GI8WhiQRClWebXwpcMOcYSY=w463-h317&quot; width=&quot;463&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;4.: Follow/Unfollow user:&lt;/b&gt;&lt;/p&gt;&lt;p&gt;We can create another service to handle follow/unfollow activity but for me it&#39;s not that much useful and is unnecessary. We can use existing &lt;i&gt;User service&lt;/i&gt; only, we just need to create another collection with following fields:&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;ol style=&quot;text-align: left;&quot;&gt;&lt;li&gt;follower_user_id&lt;/li&gt;&lt;li&gt;target_user_id&amp;nbsp;&lt;/li&gt;&lt;li&gt;target_user_name&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/a/AVvXsEi2PEQ4QuaadCy1CEC9IFiG6DOAWvHHzS_z6-THlT5mJajRo9U4QeGVzNX5UZKFzEEVEYgFHn6HeeJHpFJI2D2IeRetxCXj57nCjtKeofkoDTwrtnoJfZq3Cx0CS6rxr7_5Mc25lKoynPYbnjpTZtJ_fRlckgMURh6zUdWA-jjOMFcyfkIWohV6spVyPjo&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img alt=&quot;&quot; data-original-height=&quot;576&quot; data-original-width=&quot;841&quot; height=&quot;314&quot; src=&quot;https://blogger.googleusercontent.com/img/a/AVvXsEi2PEQ4QuaadCy1CEC9IFiG6DOAWvHHzS_z6-THlT5mJajRo9U4QeGVzNX5UZKFzEEVEYgFHn6HeeJHpFJI2D2IeRetxCXj57nCjtKeofkoDTwrtnoJfZq3Cx0CS6rxr7_5Mc25lKoynPYbnjpTZtJ_fRlckgMURh6zUdWA-jjOMFcyfkIWohV6spVyPjo=w457-h314&quot; width=&quot;457&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;5. Loading the timeline of the user:&lt;/b&gt;&lt;/p&gt;&lt;p&gt;That&#39;s the most complex problem. Within the current design here is how we can achieve it.&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;Client send the request to User service&lt;/li&gt;&lt;li&gt;User service gets all the users who the user is following.&lt;/li&gt;&lt;li&gt;It will then query the posts of all the users sorted by timestamps with pagesize of 20-50 using the Post service.&lt;/li&gt;&lt;li&gt;Send page size number of posts sorted based on timestamp to the client.&lt;/li&gt;&lt;li&gt;Client can then dowload the images using the post_urls from object store.&lt;/li&gt;&lt;/ul&gt;This will definitely solve the problem but it is very inefficient. I know we are not solving the non-functional requirements now but we should think about the performance.&lt;p&gt;&lt;/p&gt;&lt;p&gt;To make it efficient, we will use &lt;i&gt;CQRS&lt;/i&gt; pattern. We will have a new service called &lt;i&gt;Timeline service&lt;/i&gt;. This will have an efficient &lt;i&gt;key value pair DB&lt;/i&gt; where &lt;i&gt;key is the user_id&lt;/i&gt; and &lt;i&gt;value is the list of post records&lt;/i&gt;&amp;nbsp;of all the users followed by the user with user_id(key). Every post record will have &lt;i&gt;{post_url, user_id, timestamp}&lt;/i&gt;&lt;/p&gt;&lt;p&gt;Now here is what we do with this new service:&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;POST service will queue the new posts containing post_url, user_id, timestamp to Timeline service.&lt;/li&gt;&lt;li&gt;Timeline service will take the user_id and get it&#39;s followers from User service.&lt;/li&gt;&lt;li&gt;It then add this post to the front of all the followers&#39; list of post records. It can remove the posts if the list is have more records than what we need to show in the timeline.&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;With this new service, our flow of showing timeline will become straight forward:&lt;/div&gt;&lt;div&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;Client requests Timeline service for the timeline.&lt;/li&gt;&lt;li&gt;Timeline service returns the list of post records from it&#39;s key value db with key as requested user&#39;s user_id.&lt;/li&gt;&lt;li&gt;Now client can download the images from object store using post_url.&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;This will be eventual consistent but that&#39;s okay as per our non functional requirements. This will be much efficient than the older design.&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/a/AVvXsEhu5KquTIZ1K1In63envW8WOTdDHjMcn_UVOxNZEWAzxLf1VxLkSokbYqJKvsCPdydTLf5fgDcGMJgLy9e6VnADoCzxRxZjJFWo6J9tjEHbdFfoDtiiHwZvDfX6zq0qbQvZc2QOccZr1ne1m4ArxjbOhErVvZOgzP9BZYjU6e9X9f6ORu5j9rtlbmghSCw&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img alt=&quot;&quot; data-original-height=&quot;631&quot; data-original-width=&quot;848&quot; height=&quot;363&quot; src=&quot;https://blogger.googleusercontent.com/img/a/AVvXsEhu5KquTIZ1K1In63envW8WOTdDHjMcn_UVOxNZEWAzxLf1VxLkSokbYqJKvsCPdydTLf5fgDcGMJgLy9e6VnADoCzxRxZjJFWo6J9tjEHbdFfoDtiiHwZvDfX6zq0qbQvZc2QOccZr1ne1m4ArxjbOhErVvZOgzP9BZYjU6e9X9f6ORu5j9rtlbmghSCw=w488-h363&quot; width=&quot;488&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;Step 3: Mapping nonfunctional requirements to architectural diagram:&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;1. Scalability:&amp;nbsp;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;If you see we have following scalability requirements here:&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;Number of users: We have 1-2 billion users data which will be huge so we can&#39;t rely on just one DB instance so we have to shard the &lt;i&gt;User service DB&lt;/i&gt;. We can shard using hashing technique:&lt;/li&gt;&lt;ul&gt;&lt;li&gt;User DB: Shard on the basis of &lt;i&gt;user_id&lt;/i&gt;.&lt;/li&gt;&lt;li&gt;Follower DB: Shard based on &lt;i&gt;target_user_id&lt;/i&gt; as our main case is to get the followers which is a call from Timeline service.&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;For search we are already using&amp;nbsp;&lt;i&gt;elastic search and we can shard &lt;/i&gt;it too.&lt;/li&gt;&lt;li&gt;Number of visists: To support these number of visits, we have to run multiple instances of different services behind load balancer.&lt;/li&gt;&lt;li&gt;Number of posts: This has two parts:&lt;/li&gt;&lt;ol&gt;&lt;li&gt;Data in the DB: This will be huge also so we have to &lt;i&gt;shard&lt;/i&gt; Post DB as well as Timeline DB. Post DB can be sharded using &lt;i&gt;post_id&lt;/i&gt; and Timeline DB using &lt;i&gt;user_id&lt;/i&gt;.&lt;/li&gt;&lt;li&gt;Image Data: As per requirement we need to save petabytes of data because we are getting uncompressed image. Not only these images will take lots of space but also these are not optimized for viewing on Mobile device or browser. We can introduce an &lt;i&gt;async image processing pipeline&lt;/i&gt; like &lt;i&gt;AWS severless image handler&lt;/i&gt; to compress these images which will convert this petabytes of data into TBs or even GBs.&lt;/li&gt;&lt;/ol&gt;&lt;/ul&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/a/AVvXsEiSze6qDEDMCkXglVMs-szTyGPNv3NUVzjMvhKrTSa0JOvoeIDkHvC-MG3297dsyCA87yiHbsW5R1ZclbU0E3ELauFl5rwX5JbERDG-5A0UwLpFsfm1ShPxhCRTRAkW0ZheOJ1eCM1f44qUdj2tY26EAuxi3hgV1XIDSEciOpfGhN7rQF3AMhABGdpg-pY&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img alt=&quot;&quot; data-original-height=&quot;931&quot; data-original-width=&quot;992&quot; height=&quot;429&quot; src=&quot;https://blogger.googleusercontent.com/img/a/AVvXsEiSze6qDEDMCkXglVMs-szTyGPNv3NUVzjMvhKrTSa0JOvoeIDkHvC-MG3297dsyCA87yiHbsW5R1ZclbU0E3ELauFl5rwX5JbERDG-5A0UwLpFsfm1ShPxhCRTRAkW0ZheOJ1eCM1f44qUdj2tY26EAuxi3hgV1XIDSEciOpfGhN7rQF3AMhABGdpg-pY=w458-h429&quot; width=&quot;458&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;2. Availability:&lt;/b&gt;&lt;/p&gt;&lt;p&gt;By using &lt;i&gt;multiple instances of our services&lt;/i&gt; behind load balancer, we have almost achieved the availability. We can have &lt;i&gt;replicas of our DBs&lt;/i&gt; to achieve the availability requirements. Additionally we can do &lt;i&gt;multi region deployement&lt;/i&gt; and have a &lt;i&gt;global load balancer&lt;/i&gt; in case one region is down. It will also increase the performance.&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/a/AVvXsEiE-bV7DNUKxCf1Hji1E7iE2NpIWNa8gAdChSdZbYqKLevSFGjAA-3zzO0L4iu6vwW8GYtWVVbDE8K2gAXzttg3dHY_jPzIIUfzDGYncxwsTJneR7UCVxhhdDCOBb8I3-FyP-c9jb8ZL3WzRIfpYo9H_3osbMAldtVTeksdkHm_GoAiaQjz--DeLdDF8t8&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img alt=&quot;&quot; data-original-height=&quot;931&quot; data-original-width=&quot;1110&quot; height=&quot;381&quot; src=&quot;https://blogger.googleusercontent.com/img/a/AVvXsEiE-bV7DNUKxCf1Hji1E7iE2NpIWNa8gAdChSdZbYqKLevSFGjAA-3zzO0L4iu6vwW8GYtWVVbDE8K2gAXzttg3dHY_jPzIIUfzDGYncxwsTJneR7UCVxhhdDCOBb8I3-FyP-c9jb8ZL3WzRIfpYo9H_3osbMAldtVTeksdkHm_GoAiaQjz--DeLdDF8t8=w455-h381&quot; width=&quot;455&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;p&gt;&lt;b&gt;3. Performance:&lt;/b&gt;&lt;/p&gt;&lt;p&gt;We have two performance benchmarks:&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;500 ms for every page load: To achieve it we can use CDNs to store html pages, CSS and post images.&lt;/li&gt;&lt;li&gt;1 second for timeline page load: We have already made a decision to use CQRS pattern and made Timeline service to serve the timeline page. This will take care of the performance part but it will create a different problem. There are few thousands of users whom we call &lt;i&gt;celebrity / influencers&lt;/i&gt; and millions of users follow them. In case if a &lt;i&gt;celebrity user makes a post, millions of entries of Timeline service DB will be updated&lt;/i&gt; which might slow down the DB and hence the performance. To tackle this situation we can make following steps:&lt;/li&gt;&lt;ol&gt;&lt;li&gt;Define which user is celebrity; Say a celebrity has 1 M followers.&lt;/li&gt;&lt;li&gt;Make a column in &lt;i&gt;User DB&lt;/i&gt; - &lt;i&gt;IsCelebrity &lt;/i&gt;which will tell if the user is a celebrity or not.&lt;/li&gt;&lt;li&gt;When celebrity post an image and Timeline serivec calls User service to get the followers list. Instead of returning followers list, User service will return IsCelebrity = true.&lt;/li&gt;&lt;li&gt;Another Key-Value pair say &lt;i&gt;Celebrity POST DB&amp;nbsp;&lt;/i&gt;will be added to Timeline service DB which where key is &lt;i&gt;celebrity_user_id&lt;/i&gt; and value is &lt;i&gt;sorted list of post records&lt;/i&gt;.&lt;/li&gt;&lt;li&gt;When Timeline service receive IsCelebrity as true. It just add the post into Celebrity POST DB.&lt;/li&gt;&lt;li&gt;While loading the Timeline, Time line service get the list of celebrities from User service which the user is following using new REST endpoint on User service say GET /users/{user-id}/celebrity.&lt;/li&gt;&lt;li&gt;Timeline service then merge the sorted results it gets from celebrity key value pair and user key value pair and returns it to user.&lt;/li&gt;&lt;/ol&gt;&lt;/ul&gt;&lt;div&gt;And that&#39;s all about the performance. Now that we have addresses every requirement functional or non functional, here is our final architecture diagram:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/a/AVvXsEgfNX6_Z6X-2T8yZWsFxpmAD5_g_8T_I3VXaMFVsmGePXKl_O6rc2CLWrUmRRwe-k8xkCMaqUb1CwowDkM1mCRKpTTfxIlBe44lYENWGo8_s-99jchqwf2CPRuHHuSwN_GmWia7sC2AyEoFXjaXsDqHPgQtydDqedv8CiA7PP9t57MPFHkHIHKLw8GzSXg&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img alt=&quot;&quot; data-original-height=&quot;931&quot; data-original-width=&quot;1110&quot; height=&quot;421&quot; src=&quot;https://blogger.googleusercontent.com/img/a/AVvXsEgfNX6_Z6X-2T8yZWsFxpmAD5_g_8T_I3VXaMFVsmGePXKl_O6rc2CLWrUmRRwe-k8xkCMaqUb1CwowDkM1mCRKpTTfxIlBe44lYENWGo8_s-99jchqwf2CPRuHHuSwN_GmWia7sC2AyEoFXjaXsDqHPgQtydDqedv8CiA7PP9t57MPFHkHIHKLw8GzSXg=w501-h421&quot; width=&quot;501&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;Have fun!&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='http://algods-cracker.blogspot.com/feeds/1160289488736251855/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://algods-cracker.blogspot.com/2024/10/design-instagram.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7496974970329409400/posts/default/1160289488736251855'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7496974970329409400/posts/default/1160289488736251855'/><link rel='alternate' type='text/html' href='http://algods-cracker.blogspot.com/2024/10/design-instagram.html' title='Design Instagram'/><author><name>Nishant Saxena</name><uri>http://www.blogger.com/profile/17860524009847591950</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjOdjS62BAEI1iMG_zd6lew4qyFGpfJhWHp0AJWQhiJvxQpSGg0AFZ5euJG7tK0D-EGQFno32hF-i1x4E2A49re_8-b9r0QHwXQ-9X_EvlAcekIjUYMaA1v6dWzDqzkBg/s220/2d230a1.jpg'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjmY-wlVvaeSELPeWVlsACDol3f4QdRsxZFd8_7GuzfPRY2VewjiQbwDAe6j5zbJ0D4JVx1nqctiQh5D7mCqKdJ8177vbHfYww6LEqXZ6h1Mw_-Pdh_77dB5FH10p_r7nBJd9Uk9X1F5Wzz9zhgifrFD9q80SLbna52hZ7EysTSQVTVq2A2reyzfT5u3Zw/s72-w372-h657-c/InstaSeqDiagram.png" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7496974970329409400.post-6158664395872740128</id><published>2024-10-04T01:43:00.004+05:30</published><updated>2024-10-04T01:43:20.429+05:30</updated><category scheme="http://www.blogger.com/atom/ns#" term="Binary Search"/><category scheme="http://www.blogger.com/atom/ns#" term="LeetCode"/><title type='text'>[LeetCode] Snapshot Array</title><content type='html'>&lt;p&gt;&lt;b&gt;Problem:&lt;/b&gt; Implement a SnapshotArray that supports the following interface:&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;SnapshotArray(int length) initializes an array-like data structure with the given length. Initially, each element equals 0.&lt;/li&gt;&lt;li&gt;void set(index, val) sets the element at the given index to be equal to val.&lt;/li&gt;&lt;li&gt;int snap() takes a snapshot of the array and returns the snap_id: the total number of times we called snap() minus 1.&lt;/li&gt;&lt;li&gt;int get(index, snap_id) returns the value at the given index, at the time we took the snapshot with the given snap_id&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;Example:&lt;/p&gt;&lt;pre style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-translate-x: 0; --tw-translate-y: 0; background-color: #f0f0f0; border-color: var(--border-tertiary); border-image: initial; border-style: solid; border-width: 0px 0px 0px 2px; box-sizing: border-box; color: var(--text-secondary); font-family: Menlo, sans-serif; font-size: 14px; line-height: 1.25rem; margin-bottom: 1rem; margin-top: 1rem; overflow-wrap: break-word; overflow: visible; padding-left: 1rem; text-wrap: wrap;&quot;&gt;&lt;span style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-text-opacity: 1; --tw-translate-x: 0; --tw-translate-y: 0; border-color: hsl(var(--sd-border)); border-image: initial; border-style: solid; border-width: 0px; box-sizing: border-box; color: rgb(38 38 38/var(--tw-text-opacity)); font-weight: 700; overflow-wrap: break-word;&quot;&gt;Input:&lt;/span&gt; [&quot;SnapshotArray&quot;,&quot;set&quot;,&quot;snap&quot;,&quot;set&quot;,&quot;get&quot;]
[[3],[0,5],[],[0,6],[0,0]]
&lt;span style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-text-opacity: 1; --tw-translate-x: 0; --tw-translate-y: 0; border-color: hsl(var(--sd-border)); border-image: initial; border-style: solid; border-width: 0px; box-sizing: border-box; color: rgb(38 38 38/var(--tw-text-opacity)); font-weight: 700; overflow-wrap: break-word;&quot;&gt;Output:&lt;/span&gt; [null,null,0,null,5]
&lt;span style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-text-opacity: 1; --tw-translate-x: 0; --tw-translate-y: 0; border-color: hsl(var(--sd-border)); border-image: initial; border-style: solid; border-width: 0px; box-sizing: border-box; color: rgb(38 38 38/var(--tw-text-opacity)); font-weight: 700; overflow-wrap: break-word;&quot;&gt;Explanation: &lt;/span&gt;
SnapshotArray snapshotArr = new SnapshotArray(3); // set the length to be 3
snapshotArr.set(0,5);  // Set array[0] = 5
snapshotArr.snap();  // Take a snapshot, return snap_id = 0
snapshotArr.set(0,6);
snapshotArr.get(0,0);  // Get the value of array[0] with snap_id = 0, return 5&lt;/pre&gt;&lt;p&gt;Constraints:&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;1 &amp;lt;= length &amp;lt;= 5 * 10^4&lt;/li&gt;&lt;li&gt;0 &amp;lt;= index &amp;lt; length&lt;/li&gt;&lt;li&gt;0 &amp;lt;= val &amp;lt;= 10^9&lt;/li&gt;&lt;li&gt;0 &amp;lt;= snap_id &amp;lt; (the total number of times we call snap())&lt;/li&gt;&lt;li&gt;At most 5 * 10^4 calls will be made to set, snap, and get.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;Approach:&lt;/b&gt; First thing in the problem we can notice that we can&#39;t save full array, every time we take the snapshot as the length of the array could be 5 * 10 ^ 4 and snap can be called 5 * 10 ^ 4 times.&lt;/p&gt;&lt;p&gt;What we can do is we only store the updates which happened in the current snapshot. In this way for every index we will have a list of snapshot id and the value updates so now when we try to get the value given the snapshot we can do following:&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;If no modification i.e. list of updates at the input index will be&amp;nbsp; null or if no snapshot is taken i.e. current snapshot id is still 0 then we can simply return 0.&lt;/li&gt;&lt;li&gt;Else we find the upper bound of snap_id using binary search and return the stored value.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;That&#39;s all!&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;Implementation in C#:&lt;/b&gt;&lt;/p&gt;&lt;div style=&quot;background-color: white; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 13px; line-height: 18px; white-space: pre;&quot;&gt;&lt;div&gt;&lt;span style=&quot;color: blue;&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color: blue;&quot;&gt;class&lt;/span&gt; &lt;span style=&quot;color: #267f99;&quot;&gt;SnapshotArray&lt;/span&gt;&lt;/div&gt;&lt;div&gt;{&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: blue;&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color: #795e26;&quot;&gt;SnapshotArray&lt;/span&gt;(&lt;span style=&quot;color: blue;&quot;&gt;int&lt;/span&gt; &lt;span style=&quot;color: #001080;&quot;&gt;length&lt;/span&gt;)&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; {&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: blue;&quot;&gt;this&lt;/span&gt;.&lt;span style=&quot;color: #001080;&quot;&gt;snapshots&lt;/span&gt; = &lt;span style=&quot;color: blue;&quot;&gt;new&lt;/span&gt; &lt;span style=&quot;color: #267f99;&quot;&gt;List&lt;/span&gt;&amp;lt;&lt;span style=&quot;color: #267f99;&quot;&gt;Tuple&lt;/span&gt;&amp;lt;&lt;span style=&quot;color: blue;&quot;&gt;int&lt;/span&gt;, &lt;span style=&quot;color: blue;&quot;&gt;int&lt;/span&gt;&amp;gt;&amp;gt;[&lt;span style=&quot;color: #001080;&quot;&gt;length&lt;/span&gt;];&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: blue;&quot;&gt;this&lt;/span&gt;.&lt;span style=&quot;color: #001080;&quot;&gt;currSnapId&lt;/span&gt; = &lt;span style=&quot;color: #098658;&quot;&gt;0&lt;/span&gt;;&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; }&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: blue;&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color: blue;&quot;&gt;void&lt;/span&gt; &lt;span style=&quot;color: #795e26;&quot;&gt;Set&lt;/span&gt;(&lt;span style=&quot;color: blue;&quot;&gt;int&lt;/span&gt; &lt;span style=&quot;color: #001080;&quot;&gt;index&lt;/span&gt;, &lt;span style=&quot;color: blue;&quot;&gt;int&lt;/span&gt; &lt;span style=&quot;color: #001080;&quot;&gt;val&lt;/span&gt;)&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; {&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #af00db;&quot;&gt;if&lt;/span&gt; (&lt;span style=&quot;color: blue;&quot;&gt;this&lt;/span&gt;.&lt;span style=&quot;color: #001080;&quot;&gt;snapshots&lt;/span&gt;[&lt;span style=&quot;color: #001080;&quot;&gt;index&lt;/span&gt;] == &lt;span style=&quot;color: blue;&quot;&gt;null&lt;/span&gt;)&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; {&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: blue;&quot;&gt;this&lt;/span&gt;.&lt;span style=&quot;color: #001080;&quot;&gt;snapshots&lt;/span&gt;[&lt;span style=&quot;color: #001080;&quot;&gt;index&lt;/span&gt;] = &lt;span style=&quot;color: blue;&quot;&gt;new&lt;/span&gt; &lt;span style=&quot;color: #267f99;&quot;&gt;List&lt;/span&gt;&amp;lt;&lt;span style=&quot;color: #267f99;&quot;&gt;Tuple&lt;/span&gt;&amp;lt;&lt;span style=&quot;color: blue;&quot;&gt;int&lt;/span&gt;, &lt;span style=&quot;color: blue;&quot;&gt;int&lt;/span&gt;&amp;gt;&amp;gt;();&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: blue;&quot;&gt;int&lt;/span&gt; &lt;span style=&quot;color: #001080;&quot;&gt;length&lt;/span&gt; = &lt;span style=&quot;color: blue;&quot;&gt;this&lt;/span&gt;.&lt;span style=&quot;color: #001080;&quot;&gt;snapshots&lt;/span&gt;[&lt;span style=&quot;color: #001080;&quot;&gt;index&lt;/span&gt;].&lt;span style=&quot;color: #001080;&quot;&gt;Count&lt;/span&gt;;&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #af00db;&quot;&gt;if&lt;/span&gt; (&lt;span style=&quot;color: #001080;&quot;&gt;length&lt;/span&gt; &amp;gt; &lt;span style=&quot;color: #098658;&quot;&gt;0&lt;/span&gt; &amp;amp;&amp;amp;&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: blue;&quot;&gt;this&lt;/span&gt;.&lt;span style=&quot;color: #001080;&quot;&gt;snapshots&lt;/span&gt;[&lt;span style=&quot;color: #001080;&quot;&gt;index&lt;/span&gt;][&lt;span style=&quot;color: #001080;&quot;&gt;length&lt;/span&gt; - &lt;span style=&quot;color: #098658;&quot;&gt;1&lt;/span&gt;].&lt;span style=&quot;color: #001080;&quot;&gt;Item1&lt;/span&gt; == &lt;span style=&quot;color: blue;&quot;&gt;this&lt;/span&gt;.&lt;span style=&quot;color: #001080;&quot;&gt;currSnapId&lt;/span&gt;)&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; {&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: blue;&quot;&gt;this&lt;/span&gt;.&lt;span style=&quot;color: #001080;&quot;&gt;snapshots&lt;/span&gt;[&lt;span style=&quot;color: #001080;&quot;&gt;index&lt;/span&gt;].&lt;span style=&quot;color: #795e26;&quot;&gt;RemoveAt&lt;/span&gt;(&lt;span style=&quot;color: #001080;&quot;&gt;length&lt;/span&gt; - &lt;span style=&quot;color: #098658;&quot;&gt;1&lt;/span&gt;);&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: blue;&quot;&gt;this&lt;/span&gt;.&lt;span style=&quot;color: #001080;&quot;&gt;snapshots&lt;/span&gt;[&lt;span style=&quot;color: #001080;&quot;&gt;index&lt;/span&gt;].&lt;span style=&quot;color: #795e26;&quot;&gt;Add&lt;/span&gt;(&lt;span style=&quot;color: blue;&quot;&gt;new&lt;/span&gt; &lt;span style=&quot;color: #267f99;&quot;&gt;Tuple&lt;/span&gt;&amp;lt;&lt;span style=&quot;color: blue;&quot;&gt;int&lt;/span&gt;, &lt;span style=&quot;color: blue;&quot;&gt;int&lt;/span&gt;&amp;gt;(&lt;span style=&quot;color: blue;&quot;&gt;this&lt;/span&gt;.&lt;span style=&quot;color: #001080;&quot;&gt;currSnapId&lt;/span&gt;,&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #001080;&quot;&gt;val&lt;/span&gt;));&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; }&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: blue;&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color: blue;&quot;&gt;int&lt;/span&gt; &lt;span style=&quot;color: #795e26;&quot;&gt;Snap&lt;/span&gt;()&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; {&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ++&lt;span style=&quot;color: blue;&quot;&gt;this&lt;/span&gt;.&lt;span style=&quot;color: #001080;&quot;&gt;currSnapId&lt;/span&gt;;&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #af00db;&quot;&gt;return&lt;/span&gt; &lt;span style=&quot;color: blue;&quot;&gt;this&lt;/span&gt;.&lt;span style=&quot;color: #001080;&quot;&gt;currSnapId&lt;/span&gt; - &lt;span style=&quot;color: #098658;&quot;&gt;1&lt;/span&gt;;&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; }&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: blue;&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color: blue;&quot;&gt;int&lt;/span&gt; &lt;span style=&quot;color: #795e26;&quot;&gt;Get&lt;/span&gt;(&lt;span style=&quot;color: blue;&quot;&gt;int&lt;/span&gt; &lt;span style=&quot;color: #001080;&quot;&gt;index&lt;/span&gt;, &lt;span style=&quot;color: blue;&quot;&gt;int&lt;/span&gt; &lt;span style=&quot;color: #001080;&quot;&gt;snap_id&lt;/span&gt;)&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; {&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: green;&quot;&gt;// No modification or no snapshot taken&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #af00db;&quot;&gt;if&lt;/span&gt; (&lt;span style=&quot;color: blue;&quot;&gt;this&lt;/span&gt;.&lt;span style=&quot;color: #001080;&quot;&gt;snapshots&lt;/span&gt;[&lt;span style=&quot;color: #001080;&quot;&gt;index&lt;/span&gt;] == &lt;span style=&quot;color: blue;&quot;&gt;null&lt;/span&gt; || &lt;span style=&quot;color: blue;&quot;&gt;this&lt;/span&gt;.&lt;span style=&quot;color: #001080;&quot;&gt;currSnapId&lt;/span&gt; == &lt;span style=&quot;color: #098658;&quot;&gt;0&lt;/span&gt;)&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; {&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #af00db;&quot;&gt;return&lt;/span&gt; &lt;span style=&quot;color: #098658;&quot;&gt;0&lt;/span&gt;;&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: blue;&quot;&gt;int&lt;/span&gt; &lt;span style=&quot;color: #001080;&quot;&gt;snapIndex&lt;/span&gt; = &lt;span style=&quot;color: blue;&quot;&gt;this&lt;/span&gt;.&lt;span style=&quot;color: #795e26;&quot;&gt;FindSnapIndex&lt;/span&gt;(&lt;span style=&quot;color: blue;&quot;&gt;this&lt;/span&gt;.&lt;span style=&quot;color: #001080;&quot;&gt;snapshots&lt;/span&gt;[&lt;span style=&quot;color: #001080;&quot;&gt;index&lt;/span&gt;], &lt;span style=&quot;color: #001080;&quot;&gt;snap_id&lt;/span&gt;);&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #af00db;&quot;&gt;return&lt;/span&gt; &lt;span style=&quot;color: #001080;&quot;&gt;snapIndex&lt;/span&gt; == -&lt;span style=&quot;color: #098658;&quot;&gt;1&lt;/span&gt; ? &lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;span style=&quot;color: #098658;&quot;&gt;0&lt;/span&gt; : &lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;span style=&quot;color: blue;&quot;&gt;this&lt;/span&gt;.&lt;span style=&quot;color: #001080;&quot;&gt;snapshots&lt;/span&gt;[&lt;span style=&quot;color: #001080;&quot;&gt;index&lt;/span&gt;][&lt;span style=&quot;color: #001080;&quot;&gt;snapIndex&lt;/span&gt;].&lt;span style=&quot;color: #001080;&quot;&gt;Item2&lt;/span&gt;;&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; }&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: blue;&quot;&gt;private&lt;/span&gt; &lt;span style=&quot;color: blue;&quot;&gt;int&lt;/span&gt; &lt;span style=&quot;color: #795e26;&quot;&gt;FindSnapIndex&lt;/span&gt;(&lt;span style=&quot;color: #267f99;&quot;&gt;List&lt;/span&gt;&amp;lt;&lt;span style=&quot;color: #267f99;&quot;&gt;Tuple&lt;/span&gt;&amp;lt;&lt;span style=&quot;color: blue;&quot;&gt;int&lt;/span&gt;, &lt;span style=&quot;color: blue;&quot;&gt;int&lt;/span&gt;&amp;gt;&amp;gt; &lt;span style=&quot;color: #001080;&quot;&gt;snapIds&lt;/span&gt;, &lt;span style=&quot;color: blue;&quot;&gt;int&lt;/span&gt; &lt;span style=&quot;color: #001080;&quot;&gt;snapId&lt;/span&gt;)&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; {&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: blue;&quot;&gt;int&lt;/span&gt; &lt;span style=&quot;color: #001080;&quot;&gt;start&lt;/span&gt; = &lt;span style=&quot;color: #098658;&quot;&gt;0&lt;/span&gt;, &lt;span style=&quot;color: #001080;&quot;&gt;end&lt;/span&gt; = &lt;span style=&quot;color: #001080;&quot;&gt;snapIds&lt;/span&gt;.&lt;span style=&quot;color: #001080;&quot;&gt;Count&lt;/span&gt; - &lt;span style=&quot;color: #098658;&quot;&gt;1&lt;/span&gt;;&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #af00db;&quot;&gt;if&lt;/span&gt; (&lt;span style=&quot;color: #001080;&quot;&gt;snapId&lt;/span&gt; &amp;gt;= &lt;span style=&quot;color: #001080;&quot;&gt;snapIds&lt;/span&gt;[&lt;span style=&quot;color: #001080;&quot;&gt;end&lt;/span&gt;].&lt;span style=&quot;color: #001080;&quot;&gt;Item1&lt;/span&gt;)&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; {&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #af00db;&quot;&gt;return&lt;/span&gt; &lt;span style=&quot;color: #001080;&quot;&gt;end&lt;/span&gt;;&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #af00db;&quot;&gt;while&lt;/span&gt; (&lt;span style=&quot;color: #001080;&quot;&gt;start&lt;/span&gt; &amp;lt;= &lt;span style=&quot;color: #001080;&quot;&gt;end&lt;/span&gt;)&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; {&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: blue;&quot;&gt;int&lt;/span&gt; &lt;span style=&quot;color: #001080;&quot;&gt;mid&lt;/span&gt; = &lt;span style=&quot;color: #001080;&quot;&gt;start&lt;/span&gt; + (&lt;span style=&quot;color: #001080;&quot;&gt;end&lt;/span&gt; - &lt;span style=&quot;color: #001080;&quot;&gt;start&lt;/span&gt;) / &lt;span style=&quot;color: #098658;&quot;&gt;2&lt;/span&gt;;&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: blue;&quot;&gt;int&lt;/span&gt; &lt;span style=&quot;color: #001080;&quot;&gt;currSnap&lt;/span&gt; = &lt;span style=&quot;color: #001080;&quot;&gt;snapIds&lt;/span&gt;[&lt;span style=&quot;color: #001080;&quot;&gt;mid&lt;/span&gt;].&lt;span style=&quot;color: #001080;&quot;&gt;Item1&lt;/span&gt;;&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #af00db;&quot;&gt;if&lt;/span&gt; (&lt;span style=&quot;color: #001080;&quot;&gt;currSnap&lt;/span&gt; == &lt;span style=&quot;color: #001080;&quot;&gt;snapId&lt;/span&gt;)&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; {&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #af00db;&quot;&gt;return&lt;/span&gt; &lt;span style=&quot;color: #001080;&quot;&gt;mid&lt;/span&gt;;&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #af00db;&quot;&gt;else&lt;/span&gt; &lt;span style=&quot;color: #af00db;&quot;&gt;if&lt;/span&gt; (&lt;span style=&quot;color: #001080;&quot;&gt;currSnap&lt;/span&gt; &amp;lt; &lt;span style=&quot;color: #001080;&quot;&gt;snapId&lt;/span&gt;)&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; {&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #001080;&quot;&gt;start&lt;/span&gt; = &lt;span style=&quot;color: #001080;&quot;&gt;mid&lt;/span&gt; + &lt;span style=&quot;color: #098658;&quot;&gt;1&lt;/span&gt;;&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #af00db;&quot;&gt;else&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; {&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #001080;&quot;&gt;end&lt;/span&gt; = &lt;span style=&quot;color: #001080;&quot;&gt;mid&lt;/span&gt; - &lt;span style=&quot;color: #098658;&quot;&gt;1&lt;/span&gt;;&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #af00db;&quot;&gt;return&lt;/span&gt; &lt;span style=&quot;color: #001080;&quot;&gt;end&lt;/span&gt;;&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; }&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: blue;&quot;&gt;private&lt;/span&gt; &lt;span style=&quot;color: #267f99;&quot;&gt;List&lt;/span&gt;&amp;lt;&lt;span style=&quot;color: #267f99;&quot;&gt;Tuple&lt;/span&gt;&amp;lt;&lt;span style=&quot;color: blue;&quot;&gt;int&lt;/span&gt;, &lt;span style=&quot;color: blue;&quot;&gt;int&lt;/span&gt;&amp;gt;&amp;gt;[] &lt;span style=&quot;color: #001080;&quot;&gt;snapshots&lt;/span&gt;;&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: blue;&quot;&gt;private&lt;/span&gt; &lt;span style=&quot;color: blue;&quot;&gt;int&lt;/span&gt; &lt;span style=&quot;color: #001080;&quot;&gt;currSnapId&lt;/span&gt;; &lt;/div&gt;&lt;div&gt;}&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&lt;b&gt;Complexity: SnapshotArray: &lt;/b&gt;O(1)&lt;b&gt;, Set: &lt;/b&gt;O(1)&lt;b&gt;, Snap: &lt;/b&gt;O(1)&lt;b&gt;, Get: &lt;/b&gt;O(logn)&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='http://algods-cracker.blogspot.com/feeds/6158664395872740128/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://algods-cracker.blogspot.com/2024/10/leetcode-snapshot-array.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7496974970329409400/posts/default/6158664395872740128'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7496974970329409400/posts/default/6158664395872740128'/><link rel='alternate' type='text/html' href='http://algods-cracker.blogspot.com/2024/10/leetcode-snapshot-array.html' title='[LeetCode] Snapshot Array'/><author><name>Nishant Saxena</name><uri>http://www.blogger.com/profile/17860524009847591950</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjOdjS62BAEI1iMG_zd6lew4qyFGpfJhWHp0AJWQhiJvxQpSGg0AFZ5euJG7tK0D-EGQFno32hF-i1x4E2A49re_8-b9r0QHwXQ-9X_EvlAcekIjUYMaA1v6dWzDqzkBg/s220/2d230a1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7496974970329409400.post-9157850225888033376</id><published>2024-10-04T00:37:00.005+05:30</published><updated>2024-10-04T00:37:30.196+05:30</updated><category scheme="http://www.blogger.com/atom/ns#" term="Binary Search"/><category scheme="http://www.blogger.com/atom/ns#" term="LeetCode"/><title type='text'>[LeetCode] Time Based Key-Value Store</title><content type='html'>&lt;p&gt;&lt;b&gt;Problem:&lt;/b&gt; Design a time-based key-value data structure that can store multiple values for the same key at different time stamps and retrieve the key&#39;s value at a certain timestamp.&lt;/p&gt;&lt;p&gt;Implement the TimeMap class:&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;TimeMap() Initializes the object of the data structure.&lt;/li&gt;&lt;li&gt;void set(String key, String value, int timestamp) Stores the key key with the value value at the given time timestamp.&lt;/li&gt;&lt;li&gt;String get(String key, int timestamp) Returns a value such that set was called previously, with timestamp_prev &amp;lt;= timestamp. If there are multiple such values, it returns the value associated with the largest timestamp_prev. If there are no values, it returns &quot;&quot;.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;Example:&lt;/p&gt;&lt;pre style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-translate-x: 0; --tw-translate-y: 0; background-color: #f0f0f0; border-color: var(--border-tertiary); border-image: initial; border-style: solid; border-width: 0px 0px 0px 2px; box-sizing: border-box; color: var(--text-secondary); font-family: Menlo, sans-serif; font-size: 14px; line-height: 1.25rem; margin-bottom: 1rem; margin-top: 1rem; overflow-wrap: break-word; overflow: visible; padding-left: 1rem; text-wrap: wrap;&quot;&gt;&lt;span style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-text-opacity: 1; --tw-translate-x: 0; --tw-translate-y: 0; border-color: hsl(var(--sd-border)); border-image: initial; border-style: solid; border-width: 0px; box-sizing: border-box; color: rgb(38 38 38/var(--tw-text-opacity)); font-weight: 700; overflow-wrap: break-word;&quot;&gt;Input&lt;/span&gt;
[&quot;TimeMap&quot;, &quot;set&quot;, &quot;get&quot;, &quot;get&quot;, &quot;set&quot;, &quot;get&quot;, &quot;get&quot;]
[[], [&quot;foo&quot;, &quot;bar&quot;, 1], [&quot;foo&quot;, 1], [&quot;foo&quot;, 3], [&quot;foo&quot;, &quot;bar2&quot;, 4], [&quot;foo&quot;, 4], [&quot;foo&quot;, 5]]
&lt;span style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-text-opacity: 1; --tw-translate-x: 0; --tw-translate-y: 0; border-color: hsl(var(--sd-border)); border-image: initial; border-style: solid; border-width: 0px; box-sizing: border-box; color: rgb(38 38 38/var(--tw-text-opacity)); font-weight: 700; overflow-wrap: break-word;&quot;&gt;Output&lt;/span&gt;
[null, null, &quot;bar&quot;, &quot;bar&quot;, null, &quot;bar2&quot;, &quot;bar2&quot;]

&lt;span style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-text-opacity: 1; --tw-translate-x: 0; --tw-translate-y: 0; border-color: hsl(var(--sd-border)); border-image: initial; border-style: solid; border-width: 0px; box-sizing: border-box; color: rgb(38 38 38/var(--tw-text-opacity)); font-weight: 700; overflow-wrap: break-word;&quot;&gt;Explanation&lt;/span&gt;
TimeMap timeMap = new TimeMap();
timeMap.set(&quot;foo&quot;, &quot;bar&quot;, 1);  // store the key &quot;foo&quot; and value &quot;bar&quot; along with timestamp = 1.
timeMap.get(&quot;foo&quot;, 1);         // return &quot;bar&quot;
timeMap.get(&quot;foo&quot;, 3);         // return &quot;bar&quot;, since there is no value corresponding to foo at timestamp 3 and timestamp 2, then the only value is at timestamp 1 is &quot;bar&quot;.
timeMap.set(&quot;foo&quot;, &quot;bar2&quot;, 4); // store the key &quot;foo&quot; and value &quot;bar2&quot; along with timestamp = 4.
timeMap.get(&quot;foo&quot;, 4);         // return &quot;bar2&quot;
timeMap.get(&quot;foo&quot;, 5);         // return &quot;bar2&quot;&lt;/pre&gt;&lt;p&gt;Constraints:&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;1 &amp;lt;= key.length, value.length &amp;lt;= 100&lt;/li&gt;&lt;li&gt;key and value consist of lowercase English letters and digits.&lt;/li&gt;&lt;li&gt;1 &amp;lt;= timestamp &amp;lt;= 10^7&lt;/li&gt;&lt;li&gt;All the timestamps timestamp of set are strictly increasing.&lt;/li&gt;&lt;li&gt;At most 2 * 10^5 calls will be made to set and get.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;/p&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;p&gt;&lt;b&gt;Approach:&lt;/b&gt; This is a binary search problem where we need to find the timestamp which is equal to or just smaller than the given timestamp.&amp;nbsp;&lt;/p&gt;&lt;p&gt;Given the constraint that timestamps are coming in strictly increasing order, we don&#39;t have to sort or maintain a sorted data structure. We can simply use a list.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;Implementation in C#:&lt;/b&gt;&lt;/p&gt;&lt;div style=&quot;background-color: white; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 13px; line-height: 18px; white-space: pre;&quot;&gt;&lt;div&gt;&lt;span style=&quot;color: blue;&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color: blue;&quot;&gt;class&lt;/span&gt; &lt;span style=&quot;color: #267f99;&quot;&gt;TimeMap&lt;/span&gt; &lt;/div&gt;&lt;div&gt;{&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: blue;&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color: #795e26;&quot;&gt;TimeMap&lt;/span&gt;()&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; {&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: blue;&quot;&gt;this&lt;/span&gt;.&lt;span style=&quot;color: #001080;&quot;&gt;kvMap&lt;/span&gt; = &lt;span style=&quot;color: blue;&quot;&gt;new&lt;/span&gt; &lt;span style=&quot;color: #267f99;&quot;&gt;Dictionary&lt;/span&gt;&amp;lt;&lt;span style=&quot;color: blue;&quot;&gt;string&lt;/span&gt;, &lt;span style=&quot;color: #267f99;&quot;&gt;List&lt;/span&gt;&amp;lt;&lt;span style=&quot;color: #267f99;&quot;&gt;Tuple&lt;/span&gt;&amp;lt;&lt;span style=&quot;color: blue;&quot;&gt;int&lt;/span&gt;, &lt;span style=&quot;color: blue;&quot;&gt;string&lt;/span&gt;&amp;gt;&amp;gt;&amp;gt;();&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; }&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: blue;&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color: blue;&quot;&gt;void&lt;/span&gt; &lt;span style=&quot;color: #795e26;&quot;&gt;Set&lt;/span&gt;(&lt;span style=&quot;color: blue;&quot;&gt;string&lt;/span&gt; &lt;span style=&quot;color: #001080;&quot;&gt;key&lt;/span&gt;, &lt;span style=&quot;color: blue;&quot;&gt;string&lt;/span&gt; &lt;span style=&quot;color: #001080;&quot;&gt;value&lt;/span&gt;, &lt;span style=&quot;color: blue;&quot;&gt;int&lt;/span&gt; &lt;span style=&quot;color: #001080;&quot;&gt;timestamp&lt;/span&gt;) {&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #af00db;&quot;&gt;if&lt;/span&gt; (!&lt;span style=&quot;color: blue;&quot;&gt;this&lt;/span&gt;.&lt;span style=&quot;color: #001080;&quot;&gt;kvMap&lt;/span&gt;.&lt;span style=&quot;color: #795e26;&quot;&gt;ContainsKey&lt;/span&gt;(&lt;span style=&quot;color: #001080;&quot;&gt;key&lt;/span&gt;))&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; {&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: blue;&quot;&gt;this&lt;/span&gt;.&lt;span style=&quot;color: #001080;&quot;&gt;kvMap&lt;/span&gt;[&lt;span style=&quot;color: #001080;&quot;&gt;key&lt;/span&gt;] = &lt;span style=&quot;color: blue;&quot;&gt;new&lt;/span&gt; &lt;span style=&quot;color: #267f99;&quot;&gt;List&lt;/span&gt;&amp;lt;&lt;span style=&quot;color: #267f99;&quot;&gt;Tuple&lt;/span&gt;&amp;lt;&lt;span style=&quot;color: blue;&quot;&gt;int&lt;/span&gt;, &lt;span style=&quot;color: blue;&quot;&gt;string&lt;/span&gt;&amp;gt;&amp;gt;();&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: blue;&quot;&gt;this&lt;/span&gt;.&lt;span style=&quot;color: #001080;&quot;&gt;kvMap&lt;/span&gt;[&lt;span style=&quot;color: #001080;&quot;&gt;key&lt;/span&gt;].&lt;span style=&quot;color: #795e26;&quot;&gt;Add&lt;/span&gt;(&lt;span style=&quot;color: blue;&quot;&gt;new&lt;/span&gt; &lt;span style=&quot;color: #267f99;&quot;&gt;Tuple&lt;/span&gt;&amp;lt;&lt;span style=&quot;color: blue;&quot;&gt;int&lt;/span&gt;, &lt;span style=&quot;color: blue;&quot;&gt;string&lt;/span&gt;&amp;gt;(&lt;span style=&quot;color: #001080;&quot;&gt;timestamp&lt;/span&gt;, &lt;span style=&quot;color: #001080;&quot;&gt;value&lt;/span&gt;));&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; }&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: blue;&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color: blue;&quot;&gt;string&lt;/span&gt; &lt;span style=&quot;color: #795e26;&quot;&gt;Get&lt;/span&gt;(&lt;span style=&quot;color: blue;&quot;&gt;string&lt;/span&gt; &lt;span style=&quot;color: #001080;&quot;&gt;key&lt;/span&gt;, &lt;span style=&quot;color: blue;&quot;&gt;int&lt;/span&gt; &lt;span style=&quot;color: #001080;&quot;&gt;timestamp&lt;/span&gt;)&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; {&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #af00db;&quot;&gt;if&lt;/span&gt; (!&lt;span style=&quot;color: #001080;&quot;&gt;kvMap&lt;/span&gt;.&lt;span style=&quot;color: #795e26;&quot;&gt;ContainsKey&lt;/span&gt;(&lt;span style=&quot;color: #001080;&quot;&gt;key&lt;/span&gt;))&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; {&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #af00db;&quot;&gt;return&lt;/span&gt; &lt;span style=&quot;color: #a31515;&quot;&gt;&quot;&quot;&lt;/span&gt;;&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: blue;&quot;&gt;int&lt;/span&gt; &lt;span style=&quot;color: #001080;&quot;&gt;index&lt;/span&gt; = &lt;span style=&quot;color: blue;&quot;&gt;this&lt;/span&gt;.&lt;span style=&quot;color: #795e26;&quot;&gt;GetIndex&lt;/span&gt;(&lt;span style=&quot;color: #001080;&quot;&gt;kvMap&lt;/span&gt;[&lt;span style=&quot;color: #001080;&quot;&gt;key&lt;/span&gt;], &lt;span style=&quot;color: #001080;&quot;&gt;timestamp&lt;/span&gt;);&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #af00db;&quot;&gt;return&lt;/span&gt; &lt;span style=&quot;color: #001080;&quot;&gt;index&lt;/span&gt; == -&lt;span style=&quot;color: #098658;&quot;&gt;1&lt;/span&gt; ? &lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;span style=&quot;color: #a31515;&quot;&gt;&quot;&quot;&lt;/span&gt; : &lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;span style=&quot;color: #001080;&quot;&gt;kvMap&lt;/span&gt;[&lt;span style=&quot;color: #001080;&quot;&gt;key&lt;/span&gt;][&lt;span style=&quot;color: #001080;&quot;&gt;index&lt;/span&gt;].&lt;span style=&quot;color: #001080;&quot;&gt;Item2&lt;/span&gt;;&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; }&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: blue;&quot;&gt;private&lt;/span&gt; &lt;span style=&quot;color: blue;&quot;&gt;int&lt;/span&gt; &lt;span style=&quot;color: #795e26;&quot;&gt;GetIndex&lt;/span&gt;(&lt;span style=&quot;color: #267f99;&quot;&gt;List&lt;/span&gt;&amp;lt;&lt;span style=&quot;color: #267f99;&quot;&gt;Tuple&lt;/span&gt;&amp;lt;&lt;span style=&quot;color: blue;&quot;&gt;int&lt;/span&gt;, &lt;span style=&quot;color: blue;&quot;&gt;string&lt;/span&gt;&amp;gt;&amp;gt; &lt;span style=&quot;color: #001080;&quot;&gt;sortedTimestamps&lt;/span&gt;,&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;span style=&quot;color: blue;&quot;&gt;int&lt;/span&gt; &lt;span style=&quot;color: #001080;&quot;&gt;timestamp&lt;/span&gt;)&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; {&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: blue;&quot;&gt;int&lt;/span&gt; &lt;span style=&quot;color: #001080;&quot;&gt;start&lt;/span&gt; = &lt;span style=&quot;color: #098658;&quot;&gt;0&lt;/span&gt;, &lt;span style=&quot;color: #001080;&quot;&gt;end&lt;/span&gt; = &lt;span style=&quot;color: #001080;&quot;&gt;sortedTimestamps&lt;/span&gt;.&lt;span style=&quot;color: #001080;&quot;&gt;Count&lt;/span&gt; - &lt;span style=&quot;color: #098658;&quot;&gt;1&lt;/span&gt;;&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #af00db;&quot;&gt;if&lt;/span&gt; (&lt;span style=&quot;color: #001080;&quot;&gt;start&lt;/span&gt; &amp;gt; &lt;span style=&quot;color: #001080;&quot;&gt;end&lt;/span&gt; || &lt;span style=&quot;color: #001080;&quot;&gt;timestamp&lt;/span&gt; &amp;lt; &lt;span style=&quot;color: #001080;&quot;&gt;sortedTimestamps&lt;/span&gt;[&lt;span style=&quot;color: #098658;&quot;&gt;0&lt;/span&gt;].&lt;span style=&quot;color: #001080;&quot;&gt;Item1&lt;/span&gt;)&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; {&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #af00db;&quot;&gt;return&lt;/span&gt; -&lt;span style=&quot;color: #098658;&quot;&gt;1&lt;/span&gt;;&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #af00db;&quot;&gt;while&lt;/span&gt; (&lt;span style=&quot;color: #001080;&quot;&gt;start&lt;/span&gt; &amp;lt;= &lt;span style=&quot;color: #001080;&quot;&gt;end&lt;/span&gt;)&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; {&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: blue;&quot;&gt;int&lt;/span&gt; &lt;span style=&quot;color: #001080;&quot;&gt;mid&lt;/span&gt; = &lt;span style=&quot;color: #001080;&quot;&gt;start&lt;/span&gt; + (&lt;span style=&quot;color: #001080;&quot;&gt;end&lt;/span&gt; - &lt;span style=&quot;color: #001080;&quot;&gt;start&lt;/span&gt;) / &lt;span style=&quot;color: #098658;&quot;&gt;2&lt;/span&gt;;&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: blue;&quot;&gt;int&lt;/span&gt; &lt;span style=&quot;color: #001080;&quot;&gt;currTimestamp&lt;/span&gt; = &lt;span style=&quot;color: #001080;&quot;&gt;sortedTimestamps&lt;/span&gt;[&lt;span style=&quot;color: #001080;&quot;&gt;mid&lt;/span&gt;].&lt;span style=&quot;color: #001080;&quot;&gt;Item1&lt;/span&gt;;&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #af00db;&quot;&gt;if&lt;/span&gt; (&lt;span style=&quot;color: #001080;&quot;&gt;currTimestamp&lt;/span&gt; == &lt;span style=&quot;color: #001080;&quot;&gt;timestamp&lt;/span&gt;)&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; {&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #af00db;&quot;&gt;return&lt;/span&gt; &lt;span style=&quot;color: #001080;&quot;&gt;mid&lt;/span&gt;;&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #af00db;&quot;&gt;if&lt;/span&gt; (&lt;span style=&quot;color: #001080;&quot;&gt;currTimestamp&lt;/span&gt; &amp;lt; &lt;span style=&quot;color: #001080;&quot;&gt;timestamp&lt;/span&gt;)&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; {&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #001080;&quot;&gt;start&lt;/span&gt; = &lt;span style=&quot;color: #001080;&quot;&gt;mid&lt;/span&gt; + &lt;span style=&quot;color: #098658;&quot;&gt;1&lt;/span&gt;;&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #af00db;&quot;&gt;else&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; {&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #001080;&quot;&gt;end&lt;/span&gt; = &lt;span style=&quot;color: #001080;&quot;&gt;mid&lt;/span&gt; - &lt;span style=&quot;color: #098658;&quot;&gt;1&lt;/span&gt;;&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #af00db;&quot;&gt;return&lt;/span&gt; &lt;span style=&quot;color: #001080;&quot;&gt;end&lt;/span&gt;;&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; }&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: blue;&quot;&gt;private&lt;/span&gt; &lt;span style=&quot;color: #267f99;&quot;&gt;Dictionary&lt;/span&gt;&amp;lt;&lt;span style=&quot;color: blue;&quot;&gt;string&lt;/span&gt;, &lt;span style=&quot;color: #267f99;&quot;&gt;List&lt;/span&gt;&amp;lt;&lt;span style=&quot;color: #267f99;&quot;&gt;Tuple&lt;/span&gt;&amp;lt;&lt;span style=&quot;color: blue;&quot;&gt;int&lt;/span&gt;, &lt;span style=&quot;color: blue;&quot;&gt;string&lt;/span&gt;&amp;gt;&amp;gt;&amp;gt; &lt;span style=&quot;color: #001080;&quot;&gt;kvMap&lt;/span&gt;;&lt;/div&gt;&lt;div&gt;}&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&lt;b&gt;Complexity:&lt;/b&gt; &lt;b&gt;Set&lt;/b&gt; - O(1), &lt;b&gt;Get&lt;/b&gt; - O(logn)&lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='http://algods-cracker.blogspot.com/feeds/9157850225888033376/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://algods-cracker.blogspot.com/2024/10/leetcode-time-based-key-value-store.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7496974970329409400/posts/default/9157850225888033376'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7496974970329409400/posts/default/9157850225888033376'/><link rel='alternate' type='text/html' href='http://algods-cracker.blogspot.com/2024/10/leetcode-time-based-key-value-store.html' title='[LeetCode] Time Based Key-Value Store'/><author><name>Nishant Saxena</name><uri>http://www.blogger.com/profile/17860524009847591950</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjOdjS62BAEI1iMG_zd6lew4qyFGpfJhWHp0AJWQhiJvxQpSGg0AFZ5euJG7tK0D-EGQFno32hF-i1x4E2A49re_8-b9r0QHwXQ-9X_EvlAcekIjUYMaA1v6dWzDqzkBg/s220/2d230a1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7496974970329409400.post-1269533311315540614</id><published>2024-10-03T21:06:00.006+05:30</published><updated>2024-10-03T21:06:28.197+05:30</updated><category scheme="http://www.blogger.com/atom/ns#" term="LeetCode"/><title type='text'>[LeetCode] Count Negative Numbers in a Sorted Matrix</title><content type='html'>&lt;p&gt;&lt;b&gt;Problem:&lt;/b&gt; Given a m x n matrix grid which is sorted in non-increasing order both row-wise and column-wise, return the number of &lt;i&gt;negative&lt;/i&gt; numbers in grid.&lt;/p&gt;&lt;p&gt;Example:&lt;/p&gt;&lt;pre style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-translate-x: 0; --tw-translate-y: 0; background-color: #f0f0f0; border-color: var(--border-tertiary); border-image: initial; border-style: solid; border-width: 0px 0px 0px 2px; box-sizing: border-box; color: var(--text-secondary); font-family: Menlo, sans-serif; font-size: 14px; line-height: 1.25rem; margin-bottom: 1rem; margin-top: 1rem; overflow-wrap: break-word; overflow: visible; padding-left: 1rem; text-wrap: wrap;&quot;&gt;&lt;span style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-text-opacity: 1; --tw-translate-x: 0; --tw-translate-y: 0; border-color: hsl(var(--sd-border)); border-image: initial; border-style: solid; border-width: 0px; box-sizing: border-box; color: rgb(38 38 38/var(--tw-text-opacity)); font-weight: 700; overflow-wrap: break-word;&quot;&gt;Input:&lt;/span&gt; grid = [[4,3,2,-1],[3,2,1,-1],[1,1,-1,-2],[-1,-1,-2,-3]]
&lt;span style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-text-opacity: 1; --tw-translate-x: 0; --tw-translate-y: 0; border-color: hsl(var(--sd-border)); border-image: initial; border-style: solid; border-width: 0px; box-sizing: border-box; color: rgb(38 38 38/var(--tw-text-opacity)); font-weight: 700; overflow-wrap: break-word;&quot;&gt;Output:&lt;/span&gt; 8
&lt;span style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-text-opacity: 1; --tw-translate-x: 0; --tw-translate-y: 0; border-color: hsl(var(--sd-border)); border-image: initial; border-style: solid; border-width: 0px; box-sizing: border-box; color: rgb(38 38 38/var(--tw-text-opacity)); font-weight: 700; overflow-wrap: break-word;&quot;&gt;Explanation:&lt;/span&gt; There are 8 negatives number in the matrix.
&lt;/pre&gt;&lt;div&gt;&lt;pre style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-translate-x: 0; --tw-translate-y: 0; background-color: #f0f0f0; border-color: var(--border-tertiary); border-image: initial; border-style: solid; border-width: 0px 0px 0px 2px; box-sizing: border-box; color: var(--text-secondary); font-family: Menlo, sans-serif; font-size: 14px; line-height: 1.25rem; margin-bottom: 1rem; margin-top: 1rem; overflow-wrap: break-word; overflow: visible; padding-left: 1rem; text-wrap: wrap;&quot;&gt;&lt;span style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-text-opacity: 1; --tw-translate-x: 0; --tw-translate-y: 0; border-color: hsl(var(--sd-border)); border-image: initial; border-style: solid; border-width: 0px; box-sizing: border-box; color: rgb(38 38 38/var(--tw-text-opacity)); font-weight: 700; overflow-wrap: break-word;&quot;&gt;Input:&lt;/span&gt; grid = [[3,2],[1,0]]
&lt;span style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-text-opacity: 1; --tw-translate-x: 0; --tw-translate-y: 0; border-color: hsl(var(--sd-border)); border-image: initial; border-style: solid; border-width: 0px; box-sizing: border-box; color: rgb(38 38 38/var(--tw-text-opacity)); font-weight: 700; overflow-wrap: break-word;&quot;&gt;Output:&lt;/span&gt; 0
&lt;/pre&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;p&gt;&lt;b&gt;Approach:&lt;/b&gt; Given we have a matrix which is sorted row wise and column wise, we can use the approach which we have used in the problem of &lt;a href=&quot;https://algods-cracker.blogspot.com/2020/10/search-element-in-row-wise-and-column.html&quot; target=&quot;_blank&quot;&gt;searching an element in row wise and column wise sorted matrix&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;Here, I am going to start from bottom left corner as the matrix is sorted in descending order but we can solve this problem starting from top right corner too.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;Implementation in C#:&lt;/b&gt;&lt;/p&gt;&lt;div style=&quot;background-color: white; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 13px; line-height: 18px; white-space: pre;&quot;&gt;&lt;div&gt;&lt;span style=&quot;color: blue;&quot;&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;/span&gt;public&lt;/span&gt; &lt;span style=&quot;color: blue;&quot;&gt;int&lt;/span&gt; &lt;span style=&quot;color: #795e26;&quot;&gt;CountNegatives&lt;/span&gt;(&lt;span style=&quot;color: blue;&quot;&gt;int&lt;/span&gt;[][] &lt;span style=&quot;color: #001080;&quot;&gt;grid&lt;/span&gt;)&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; {&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: blue;&quot;&gt;int&lt;/span&gt; &lt;span style=&quot;color: #001080;&quot;&gt;rows&lt;/span&gt; = &lt;span style=&quot;color: #001080;&quot;&gt;grid&lt;/span&gt;?.&lt;span style=&quot;color: #001080;&quot;&gt;Length&lt;/span&gt; ?? &lt;span style=&quot;color: #098658;&quot;&gt;0&lt;/span&gt;;&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #af00db;&quot;&gt;if&lt;/span&gt; (&lt;span style=&quot;color: #001080;&quot;&gt;rows&lt;/span&gt; == &lt;span style=&quot;color: #098658;&quot;&gt;0&lt;/span&gt;)&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; {&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #af00db;&quot;&gt;return&lt;/span&gt; &lt;span style=&quot;color: #098658;&quot;&gt;0&lt;/span&gt;;&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: blue;&quot;&gt;int&lt;/span&gt; &lt;span style=&quot;color: #001080;&quot;&gt;cols&lt;/span&gt; = &lt;span style=&quot;color: #001080;&quot;&gt;grid&lt;/span&gt;[&lt;span style=&quot;color: #098658;&quot;&gt;0&lt;/span&gt;].&lt;span style=&quot;color: #001080;&quot;&gt;Length&lt;/span&gt;;&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: blue;&quot;&gt;int&lt;/span&gt; &lt;span style=&quot;color: #001080;&quot;&gt;row&lt;/span&gt; = &lt;span style=&quot;color: #001080;&quot;&gt;rows&lt;/span&gt; - &lt;span style=&quot;color: #098658;&quot;&gt;1&lt;/span&gt;, &lt;span style=&quot;color: #001080;&quot;&gt;col&lt;/span&gt; = &lt;span style=&quot;color: #098658;&quot;&gt;0&lt;/span&gt;;&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: blue;&quot;&gt;int&lt;/span&gt; &lt;span style=&quot;color: #001080;&quot;&gt;totalNegNums&lt;/span&gt; = &lt;span style=&quot;color: #098658;&quot;&gt;0&lt;/span&gt;;&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #af00db;&quot;&gt;while&lt;/span&gt; (&lt;span style=&quot;color: #001080;&quot;&gt;row&lt;/span&gt; &amp;gt;= &lt;span style=&quot;color: #098658;&quot;&gt;0&lt;/span&gt; &amp;amp;&amp;amp; &lt;span style=&quot;color: #001080;&quot;&gt;col&lt;/span&gt; &amp;lt; &lt;span style=&quot;color: #001080;&quot;&gt;cols&lt;/span&gt;)&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; {&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #af00db;&quot;&gt;if&lt;/span&gt; (&lt;span style=&quot;color: #001080;&quot;&gt;grid&lt;/span&gt;[&lt;span style=&quot;color: #001080;&quot;&gt;row&lt;/span&gt;][&lt;span style=&quot;color: #001080;&quot;&gt;col&lt;/span&gt;] &amp;lt; &lt;span style=&quot;color: #098658;&quot;&gt;0&lt;/span&gt;)&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; {&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #001080;&quot;&gt;totalNegNums&lt;/span&gt; += (&lt;span style=&quot;color: #001080;&quot;&gt;cols&lt;/span&gt; - &lt;span style=&quot;color: #001080;&quot;&gt;col&lt;/span&gt;);&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; --&lt;span style=&quot;color: #001080;&quot;&gt;row&lt;/span&gt;;&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #af00db;&quot;&gt;else&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; {&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ++&lt;span style=&quot;color: #001080;&quot;&gt;col&lt;/span&gt;;&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #af00db;&quot;&gt;return&lt;/span&gt; &lt;span style=&quot;color: #001080;&quot;&gt;totalNegNums&lt;/span&gt;;&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; }&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;Complexity:&lt;/b&gt; O(m + n)&lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='http://algods-cracker.blogspot.com/feeds/1269533311315540614/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://algods-cracker.blogspot.com/2024/10/leetcode-count-negative-numbers-in.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7496974970329409400/posts/default/1269533311315540614'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7496974970329409400/posts/default/1269533311315540614'/><link rel='alternate' type='text/html' href='http://algods-cracker.blogspot.com/2024/10/leetcode-count-negative-numbers-in.html' title='[LeetCode] Count Negative Numbers in a Sorted Matrix'/><author><name>Nishant Saxena</name><uri>http://www.blogger.com/profile/17860524009847591950</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjOdjS62BAEI1iMG_zd6lew4qyFGpfJhWHp0AJWQhiJvxQpSGg0AFZ5euJG7tK0D-EGQFno32hF-i1x4E2A49re_8-b9r0QHwXQ-9X_EvlAcekIjUYMaA1v6dWzDqzkBg/s220/2d230a1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7496974970329409400.post-8886538001518028079</id><published>2024-10-03T20:44:00.006+05:30</published><updated>2024-10-03T20:44:34.060+05:30</updated><category scheme="http://www.blogger.com/atom/ns#" term="Binary Search"/><category scheme="http://www.blogger.com/atom/ns#" term="LeetCode"/><title type='text'>[LeetCode] Search Insert Position</title><content type='html'>&lt;p&gt;&lt;b&gt;Problem:&lt;/b&gt; Given a sorted array of distinct integers and a target value, return the index if the target is found. If not, return the index where it would be if it were inserted in order.&lt;/p&gt;&lt;p&gt;Example:&lt;/p&gt;&lt;pre style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-translate-x: 0; --tw-translate-y: 0; background-color: #f0f0f0; border-color: var(--border-tertiary); border-image: initial; border-style: solid; border-width: 0px 0px 0px 2px; box-sizing: border-box; color: var(--text-secondary); font-family: Menlo, sans-serif; font-size: 14px; line-height: 1.25rem; margin-bottom: 1rem; margin-top: 1rem; overflow-wrap: break-word; overflow: visible; padding-left: 1rem; text-wrap: wrap;&quot;&gt;&lt;span style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-text-opacity: 1; --tw-translate-x: 0; --tw-translate-y: 0; border-color: hsl(var(--sd-border)); border-image: initial; border-style: solid; border-width: 0px; box-sizing: border-box; color: rgb(38 38 38/var(--tw-text-opacity)); font-weight: 700; overflow-wrap: break-word;&quot;&gt;Input:&lt;/span&gt; nums = [1,3,5,6], target = 5
&lt;span style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-text-opacity: 1; --tw-translate-x: 0; --tw-translate-y: 0; border-color: hsl(var(--sd-border)); border-image: initial; border-style: solid; border-width: 0px; box-sizing: border-box; color: rgb(38 38 38/var(--tw-text-opacity)); font-weight: 700; overflow-wrap: break-word;&quot;&gt;Output:&lt;/span&gt; 2
&lt;/pre&gt;&lt;div&gt;&lt;pre style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-translate-x: 0; --tw-translate-y: 0; background-color: #f0f0f0; border-color: var(--border-tertiary); border-image: initial; border-style: solid; border-width: 0px 0px 0px 2px; box-sizing: border-box; color: var(--text-secondary); font-family: Menlo, sans-serif; font-size: 14px; line-height: 1.25rem; margin-bottom: 1rem; margin-top: 1rem; overflow-wrap: break-word; overflow: visible; padding-left: 1rem; text-wrap: wrap;&quot;&gt;&lt;span style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-text-opacity: 1; --tw-translate-x: 0; --tw-translate-y: 0; border-color: hsl(var(--sd-border)); border-image: initial; border-style: solid; border-width: 0px; box-sizing: border-box; color: rgb(38 38 38/var(--tw-text-opacity)); font-weight: 700; overflow-wrap: break-word;&quot;&gt;Input:&lt;/span&gt; nums = [1,3,5,6], target = 2
&lt;span style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-text-opacity: 1; --tw-translate-x: 0; --tw-translate-y: 0; border-color: hsl(var(--sd-border)); border-image: initial; border-style: solid; border-width: 0px; box-sizing: border-box; color: rgb(38 38 38/var(--tw-text-opacity)); font-weight: 700; overflow-wrap: break-word;&quot;&gt;Output:&lt;/span&gt; 1
&lt;/pre&gt;&lt;/div&gt;&lt;div&gt;&lt;pre style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-translate-x: 0; --tw-translate-y: 0; background-color: #f0f0f0; border-color: var(--border-tertiary); border-image: initial; border-style: solid; border-width: 0px 0px 0px 2px; box-sizing: border-box; color: var(--text-secondary); font-family: Menlo, sans-serif; font-size: 14px; line-height: 1.25rem; margin-bottom: 1rem; margin-top: 1rem; overflow-wrap: break-word; overflow: visible; padding-left: 1rem; text-wrap: wrap;&quot;&gt;&lt;span style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-text-opacity: 1; --tw-translate-x: 0; --tw-translate-y: 0; border-color: hsl(var(--sd-border)); border-image: initial; border-style: solid; border-width: 0px; box-sizing: border-box; color: rgb(38 38 38/var(--tw-text-opacity)); font-weight: 700; overflow-wrap: break-word;&quot;&gt;Input:&lt;/span&gt; nums = [1,3,5,6], target = 7
&lt;span style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-text-opacity: 1; --tw-translate-x: 0; --tw-translate-y: 0; border-color: hsl(var(--sd-border)); border-image: initial; border-style: solid; border-width: 0px; box-sizing: border-box; color: rgb(38 38 38/var(--tw-text-opacity)); font-weight: 700; overflow-wrap: break-word;&quot;&gt;Output:&lt;/span&gt; 4&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Constraints:&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;1 &amp;lt;= nums.length &amp;lt;= 10^4&lt;/li&gt;&lt;li&gt;-10^4 &amp;lt;= nums[i] &amp;lt;= 10^4&lt;/li&gt;&lt;li&gt;nums contains distinct values sorted in ascending order.&lt;/li&gt;&lt;li&gt;-10^4 &amp;lt;= target &amp;lt;= 10^4&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;/p&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;p&gt;&lt;b&gt;Approach:&lt;/b&gt; The problem here is just to find the target itself or just greater element in the array so if you see this is a &lt;i&gt;binary search&lt;/i&gt; problem with following changes:&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;ol style=&quot;text-align: left;&quot;&gt;&lt;li&gt;If nums[mid] &amp;lt; target then obviously we need to go to the right side i.e. start = mid + 1&lt;/li&gt;&lt;li&gt;Else end = mid&lt;/li&gt;&lt;li&gt;Return end.&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;Implementation in C#:&lt;/b&gt;&lt;/p&gt;&lt;div style=&quot;background-color: white; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 13px; line-height: 18px; white-space: pre;&quot;&gt;&lt;div&gt;&lt;span style=&quot;color: blue;&quot;&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;/span&gt;public&lt;/span&gt; &lt;span style=&quot;color: blue;&quot;&gt;int&lt;/span&gt; &lt;span style=&quot;color: #795e26;&quot;&gt;SearchInsert&lt;/span&gt;(&lt;span style=&quot;color: blue;&quot;&gt;int&lt;/span&gt;[] &lt;span style=&quot;color: #001080;&quot;&gt;nums&lt;/span&gt;, &lt;span style=&quot;color: blue;&quot;&gt;int&lt;/span&gt; &lt;span style=&quot;color: #001080;&quot;&gt;target&lt;/span&gt;) &lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; {&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: blue;&quot;&gt;int&lt;/span&gt; &lt;span style=&quot;color: #001080;&quot;&gt;start&lt;/span&gt; = &lt;span style=&quot;color: #098658;&quot;&gt;0&lt;/span&gt;, &lt;span style=&quot;color: #001080;&quot;&gt;end&lt;/span&gt; = &lt;span style=&quot;color: #001080;&quot;&gt;nums&lt;/span&gt;.&lt;span style=&quot;color: #001080;&quot;&gt;Length&lt;/span&gt; - &lt;span style=&quot;color: #098658;&quot;&gt;1&lt;/span&gt; ;&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #af00db;&quot;&gt;if&lt;/span&gt; (&lt;span style=&quot;color: #001080;&quot;&gt;target&lt;/span&gt; &amp;lt; &lt;span style=&quot;color: #001080;&quot;&gt;nums&lt;/span&gt;[&lt;span style=&quot;color: #001080;&quot;&gt;start&lt;/span&gt;])&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; {&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #af00db;&quot;&gt;return&lt;/span&gt; &lt;span style=&quot;color: #001080;&quot;&gt;start&lt;/span&gt;;&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #af00db;&quot;&gt;if&lt;/span&gt; (&lt;span style=&quot;color: #001080;&quot;&gt;target&lt;/span&gt; &amp;gt; &lt;span style=&quot;color: #001080;&quot;&gt;nums&lt;/span&gt;[&lt;span style=&quot;color: #001080;&quot;&gt;end&lt;/span&gt;])&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; {&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #af00db;&quot;&gt;return&lt;/span&gt; &lt;span style=&quot;color: #001080;&quot;&gt;end&lt;/span&gt; + &lt;span style=&quot;color: #098658;&quot;&gt;1&lt;/span&gt;;&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #af00db;&quot;&gt;while&lt;/span&gt; (&lt;span style=&quot;color: #001080;&quot;&gt;start&lt;/span&gt; &amp;lt; &lt;span style=&quot;color: #001080;&quot;&gt;end&lt;/span&gt;)&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; {&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: blue;&quot;&gt;int&lt;/span&gt; &lt;span style=&quot;color: #001080;&quot;&gt;mid&lt;/span&gt; = &lt;span style=&quot;color: #001080;&quot;&gt;start&lt;/span&gt; + (&lt;span style=&quot;color: #001080;&quot;&gt;end&lt;/span&gt; - &lt;span style=&quot;color: #001080;&quot;&gt;start&lt;/span&gt;) / &lt;span style=&quot;color: #098658;&quot;&gt;2&lt;/span&gt;;&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #af00db;&quot;&gt;if&lt;/span&gt; (&lt;span style=&quot;color: #001080;&quot;&gt;nums&lt;/span&gt;[&lt;span style=&quot;color: #001080;&quot;&gt;mid&lt;/span&gt;] &amp;lt; &lt;span style=&quot;color: #001080;&quot;&gt;target&lt;/span&gt;)&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; {&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #001080;&quot;&gt;start&lt;/span&gt; = &lt;span style=&quot;color: #001080;&quot;&gt;mid&lt;/span&gt; + &lt;span style=&quot;color: #098658;&quot;&gt;1&lt;/span&gt;;&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #af00db;&quot;&gt;else&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; {&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #001080;&quot;&gt;end&lt;/span&gt; = &lt;span style=&quot;color: #001080;&quot;&gt;mid&lt;/span&gt;;&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; } &amp;nbsp; &amp;nbsp;&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #af00db;&quot;&gt;return&lt;/span&gt; &lt;span style=&quot;color: #001080;&quot;&gt;end&lt;/span&gt;;&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; }&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;Complexity:&lt;/b&gt; O(log(n))&lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='http://algods-cracker.blogspot.com/feeds/8886538001518028079/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://algods-cracker.blogspot.com/2024/10/leetcode-search-insert-position.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7496974970329409400/posts/default/8886538001518028079'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7496974970329409400/posts/default/8886538001518028079'/><link rel='alternate' type='text/html' href='http://algods-cracker.blogspot.com/2024/10/leetcode-search-insert-position.html' title='[LeetCode] Search Insert Position'/><author><name>Nishant Saxena</name><uri>http://www.blogger.com/profile/17860524009847591950</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjOdjS62BAEI1iMG_zd6lew4qyFGpfJhWHp0AJWQhiJvxQpSGg0AFZ5euJG7tK0D-EGQFno32hF-i1x4E2A49re_8-b9r0QHwXQ-9X_EvlAcekIjUYMaA1v6dWzDqzkBg/s220/2d230a1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7496974970329409400.post-4166676003597798957</id><published>2024-10-03T20:24:00.008+05:30</published><updated>2024-10-03T20:44:56.307+05:30</updated><category scheme="http://www.blogger.com/atom/ns#" term="Binary Search"/><category scheme="http://www.blogger.com/atom/ns#" term="LeetCode"/><title type='text'>[LeetCode] Find Smallest Letter Greater Than Target</title><content type='html'>&lt;p&gt;&lt;b&gt;Problem:&lt;/b&gt; You are given an array of characters letters that is sorted in &lt;i&gt;non-decreasing order&lt;/i&gt;, and a character target. There are &lt;i&gt;at least two different characters&lt;/i&gt; in letters.&lt;/p&gt;&lt;p&gt;Return the smallest character in letters that is &lt;i&gt;lexicographically greater&lt;/i&gt; than target. If such a character does not exist, return the first character in letters&lt;/p&gt;&lt;p&gt;Example:&lt;/p&gt;&lt;pre style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-translate-x: 0; --tw-translate-y: 0; background-color: #f0f0f0; border-color: var(--border-tertiary); border-image: initial; border-style: solid; border-width: 0px 0px 0px 2px; box-sizing: border-box; color: var(--text-secondary); font-family: Menlo, sans-serif; font-size: 14px; line-height: 1.25rem; margin-bottom: 1rem; margin-top: 1rem; overflow-wrap: break-word; overflow: visible; padding-left: 1rem; text-wrap: wrap;&quot;&gt;&lt;span color=&quot;rgb(38 38 38/var(--tw-text-opacity))&quot; style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-text-opacity: 1; --tw-translate-x: 0; --tw-translate-y: 0; border-color: hsl(var(--sd-border)); border-image: initial; border-style: solid; border-width: 0px; box-sizing: border-box; font-weight: 700; overflow-wrap: break-word;&quot;&gt;Input:&lt;/span&gt; letters = [&quot;c&quot;,&quot;f&quot;,&quot;j&quot;], target = &quot;a&quot;
&lt;span color=&quot;rgb(38 38 38/var(--tw-text-opacity))&quot; style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-text-opacity: 1; --tw-translate-x: 0; --tw-translate-y: 0; border-color: hsl(var(--sd-border)); border-image: initial; border-style: solid; border-width: 0px; box-sizing: border-box; font-weight: 700; overflow-wrap: break-word;&quot;&gt;Output:&lt;/span&gt; &quot;c&quot;
&lt;span color=&quot;rgb(38 38 38/var(--tw-text-opacity))&quot; style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-text-opacity: 1; --tw-translate-x: 0; --tw-translate-y: 0; border-color: hsl(var(--sd-border)); border-image: initial; border-style: solid; border-width: 0px; box-sizing: border-box; font-weight: 700; overflow-wrap: break-word;&quot;&gt;Explanation:&lt;/span&gt; The smallest character that is lexicographically greater than &#39;a&#39; in letters is &#39;c&#39;&lt;/pre&gt;&lt;pre style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-translate-x: 0; --tw-translate-y: 0; background-color: #f0f0f0; border-color: var(--border-tertiary); border-image: initial; border-style: solid; border-width: 0px 0px 0px 2px; box-sizing: border-box; color: var(--text-secondary); font-family: Menlo, sans-serif; font-size: 14px; line-height: 1.25rem; margin-bottom: 1rem; margin-top: 1rem; overflow-wrap: break-word; overflow: visible; padding-left: 1rem; text-wrap: wrap;&quot;&gt;&lt;span color=&quot;rgb(38 38 38/var(--tw-text-opacity))&quot; style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-text-opacity: 1; --tw-translate-x: 0; --tw-translate-y: 0; border-color: hsl(var(--sd-border)); border-image: initial; border-style: solid; border-width: 0px; box-sizing: border-box; font-weight: 700; overflow-wrap: break-word;&quot;&gt;Input:&lt;/span&gt; letters = [&quot;c&quot;,&quot;f&quot;,&quot;j&quot;], target = &quot;c&quot;
&lt;span color=&quot;rgb(38 38 38/var(--tw-text-opacity))&quot; style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-text-opacity: 1; --tw-translate-x: 0; --tw-translate-y: 0; border-color: hsl(var(--sd-border)); border-image: initial; border-style: solid; border-width: 0px; box-sizing: border-box; font-weight: 700; overflow-wrap: break-word;&quot;&gt;Output:&lt;/span&gt; &quot;f&quot;
&lt;span color=&quot;rgb(38 38 38/var(--tw-text-opacity))&quot; style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-text-opacity: 1; --tw-translate-x: 0; --tw-translate-y: 0; border-color: hsl(var(--sd-border)); border-image: initial; border-style: solid; border-width: 0px; box-sizing: border-box; font-weight: 700; overflow-wrap: break-word;&quot;&gt;Explanation:&lt;/span&gt; The smallest character that is lexicographically greater than &#39;c&#39; in letters is &#39;f&#39;.&lt;/pre&gt;&lt;pre style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-translate-x: 0; --tw-translate-y: 0; background-color: #f0f0f0; border-color: var(--border-tertiary); border-image: initial; border-style: solid; border-width: 0px 0px 0px 2px; box-sizing: border-box; color: var(--text-secondary); font-family: Menlo, sans-serif; font-size: 14px; line-height: 1.25rem; margin-bottom: 1rem; margin-top: 1rem; overflow-wrap: break-word; overflow: visible; padding-left: 1rem; text-wrap: wrap;&quot;&gt;&lt;span color=&quot;rgb(38 38 38/var(--tw-text-opacity))&quot; style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-text-opacity: 1; --tw-translate-x: 0; --tw-translate-y: 0; border-color: hsl(var(--sd-border)); border-image: initial; border-style: solid; border-width: 0px; box-sizing: border-box; font-weight: 700; overflow-wrap: break-word;&quot;&gt;Input:&lt;/span&gt; letters = [&quot;x&quot;,&quot;x&quot;,&quot;y&quot;,&quot;y&quot;], target = &quot;z&quot;
&lt;span color=&quot;rgb(38 38 38/var(--tw-text-opacity))&quot; style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-text-opacity: 1; --tw-translate-x: 0; --tw-translate-y: 0; border-color: hsl(var(--sd-border)); border-image: initial; border-style: solid; border-width: 0px; box-sizing: border-box; font-weight: 700; overflow-wrap: break-word;&quot;&gt;Output:&lt;/span&gt; &quot;x&quot;
&lt;span color=&quot;rgb(38 38 38/var(--tw-text-opacity))&quot; style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-text-opacity: 1; --tw-translate-x: 0; --tw-translate-y: 0; border-color: hsl(var(--sd-border)); border-image: initial; border-style: solid; border-width: 0px; box-sizing: border-box; font-weight: 700; overflow-wrap: break-word;&quot;&gt;Explanation:&lt;/span&gt; There are no characters in letters that is lexicographically greater than &#39;z&#39; so we return letters[0].&lt;/pre&gt;&lt;p&gt;Constraints:&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;2 &amp;lt;= letters.length &amp;lt;= 10^4&lt;/li&gt;&lt;li&gt;letters[i] is a lowercase English letter.&lt;/li&gt;&lt;li&gt;letters is sorted in non-decreasing order.&lt;/li&gt;&lt;li&gt;letters contains at least two different characters.&lt;/li&gt;&lt;li&gt;target is a lowercase English letter.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;Approach:&lt;/b&gt; This is a simple binary search problem with following changes:&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;ol style=&quot;text-align: left;&quot;&gt;&lt;li&gt;If letters[mid] &amp;lt;= target then obviously we will search on the right side so start becomes mid + 1.&lt;/li&gt;&lt;li&gt;Else we go to the left to see there is a smaller letter which is greater than target so end becomes mid.&lt;/li&gt;&lt;li&gt;In the end we return letters[end]&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;Implementation in C#:&lt;/b&gt;&lt;/p&gt;&lt;div style=&quot;background-color: white; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 13px; line-height: 18px; white-space: pre;&quot;&gt;&lt;div&gt;&lt;span style=&quot;color: blue;&quot;&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;/span&gt;public&lt;/span&gt; &lt;span style=&quot;color: blue;&quot;&gt;char&lt;/span&gt; &lt;span style=&quot;color: #795e26;&quot;&gt;NextGreatestLetter&lt;/span&gt;(&lt;span style=&quot;color: blue;&quot;&gt;char&lt;/span&gt;[] &lt;span style=&quot;color: #001080;&quot;&gt;letters&lt;/span&gt;, &lt;span style=&quot;color: blue;&quot;&gt;char&lt;/span&gt; &lt;span style=&quot;color: #001080;&quot;&gt;target&lt;/span&gt;)&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; {&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: blue;&quot;&gt;int&lt;/span&gt; &lt;span style=&quot;color: #001080;&quot;&gt;start&lt;/span&gt; = &lt;span style=&quot;color: #098658;&quot;&gt;0&lt;/span&gt;, &lt;span style=&quot;color: #001080;&quot;&gt;end&lt;/span&gt; = &lt;span style=&quot;color: #001080;&quot;&gt;letters&lt;/span&gt;.&lt;span style=&quot;color: #001080;&quot;&gt;Length&lt;/span&gt; - &lt;span style=&quot;color: #098658;&quot;&gt;1&lt;/span&gt;;&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #af00db;&quot;&gt;if&lt;/span&gt; (&lt;span style=&quot;color: #001080;&quot;&gt;target&lt;/span&gt; &amp;lt; &lt;span style=&quot;color: #001080;&quot;&gt;letters&lt;/span&gt;[&lt;span style=&quot;color: #001080;&quot;&gt;start&lt;/span&gt;] || &lt;span style=&quot;color: #001080;&quot;&gt;target&lt;/span&gt; &amp;gt;= &lt;span style=&quot;color: #001080;&quot;&gt;letters&lt;/span&gt;[&lt;span style=&quot;color: #001080;&quot;&gt;end&lt;/span&gt;])&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; {&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #af00db;&quot;&gt;return&lt;/span&gt; &lt;span style=&quot;color: #001080;&quot;&gt;letters&lt;/span&gt;[&lt;span style=&quot;color: #001080;&quot;&gt;start&lt;/span&gt;];&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #af00db;&quot;&gt;while&lt;/span&gt; (&lt;span style=&quot;color: #001080;&quot;&gt;start&lt;/span&gt; &amp;lt; &lt;span style=&quot;color: #001080;&quot;&gt;end&lt;/span&gt;)&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; {&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: blue;&quot;&gt;int&lt;/span&gt; &lt;span style=&quot;color: #001080;&quot;&gt;mid&lt;/span&gt; = &lt;span style=&quot;color: #001080;&quot;&gt;start&lt;/span&gt; + (&lt;span style=&quot;color: #001080;&quot;&gt;end&lt;/span&gt; - &lt;span style=&quot;color: #001080;&quot;&gt;start&lt;/span&gt;) / &lt;span style=&quot;color: #098658;&quot;&gt;2&lt;/span&gt;;&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #af00db;&quot;&gt;if&lt;/span&gt; (&lt;span style=&quot;color: #001080;&quot;&gt;letters&lt;/span&gt;[&lt;span style=&quot;color: #001080;&quot;&gt;mid&lt;/span&gt;] &amp;lt;= &lt;span style=&quot;color: #001080;&quot;&gt;target&lt;/span&gt;)&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; {&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #001080;&quot;&gt;start&lt;/span&gt; = &lt;span style=&quot;color: #001080;&quot;&gt;mid&lt;/span&gt; + &lt;span style=&quot;color: #098658;&quot;&gt;1&lt;/span&gt;;&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #af00db;&quot;&gt;else&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; {&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #001080;&quot;&gt;end&lt;/span&gt; = &lt;span style=&quot;color: #001080;&quot;&gt;mid&lt;/span&gt;;&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #af00db;&quot;&gt;return&lt;/span&gt; &lt;span style=&quot;color: #001080;&quot;&gt;letters&lt;/span&gt;[&lt;span style=&quot;color: #001080;&quot;&gt;end&lt;/span&gt;];&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; }&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;Complexity:&lt;/b&gt; O(log(n))&lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='http://algods-cracker.blogspot.com/feeds/4166676003597798957/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://algods-cracker.blogspot.com/2024/10/leetcode-find-smallest-letter-greater.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7496974970329409400/posts/default/4166676003597798957'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7496974970329409400/posts/default/4166676003597798957'/><link rel='alternate' type='text/html' href='http://algods-cracker.blogspot.com/2024/10/leetcode-find-smallest-letter-greater.html' title='[LeetCode] Find Smallest Letter Greater Than Target'/><author><name>Nishant Saxena</name><uri>http://www.blogger.com/profile/17860524009847591950</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjOdjS62BAEI1iMG_zd6lew4qyFGpfJhWHp0AJWQhiJvxQpSGg0AFZ5euJG7tK0D-EGQFno32hF-i1x4E2A49re_8-b9r0QHwXQ-9X_EvlAcekIjUYMaA1v6dWzDqzkBg/s220/2d230a1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7496974970329409400.post-5588530542943403556</id><published>2024-08-19T18:18:00.006+05:30</published><updated>2024-08-19T18:18:40.297+05:30</updated><category scheme="http://www.blogger.com/atom/ns#" term="DP"/><category scheme="http://www.blogger.com/atom/ns#" term="LeetCode"/><title type='text'>[LeetCode] 2 Keys Keyboard</title><content type='html'>&lt;p&gt;&lt;b&gt;Problem:&lt;/b&gt; There is only one character &#39;A&#39; on the screen of a notepad. You can perform one of two operations on this notepad for each step:&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;Copy All: You can copy all the characters present on the screen (a partial copy is not allowed).&lt;/li&gt;&lt;li&gt;Paste: You can paste the characters which are copied last time.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;Given an integer n, return the minimum number of operations to get the character &#39;A&#39; exactly n times on the screen.&lt;/p&gt;&lt;p&gt;Example:&lt;/p&gt;&lt;pre style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-translate-x: 0; --tw-translate-y: 0; background-color: #f0f0f0; border-color: var(--border-tertiary); border-image: initial; border-style: solid; border-width: 0px 0px 0px 2px; box-sizing: border-box; color: var(--text-secondary); font-family: Menlo, sans-serif; font-size: 14px; line-height: 1.25rem; margin-bottom: 1rem; margin-top: 1rem; overflow-wrap: break-word; overflow: visible; padding-left: 1rem; text-wrap: wrap;&quot;&gt;&lt;span style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-text-opacity: 1; --tw-translate-x: 0; --tw-translate-y: 0; border-color: hsl(var(--sd-border)); border-image: initial; border-style: solid; border-width: 0px; box-sizing: border-box; color: rgb(38 38 38/var(--tw-text-opacity)); font-weight: 700; overflow-wrap: break-word;&quot;&gt;Input:&lt;/span&gt; n = 3
&lt;span style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-text-opacity: 1; --tw-translate-x: 0; --tw-translate-y: 0; border-color: hsl(var(--sd-border)); border-image: initial; border-style: solid; border-width: 0px; box-sizing: border-box; color: rgb(38 38 38/var(--tw-text-opacity)); font-weight: 700; overflow-wrap: break-word;&quot;&gt;Output:&lt;/span&gt; 3
&lt;span style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-text-opacity: 1; --tw-translate-x: 0; --tw-translate-y: 0; border-color: hsl(var(--sd-border)); border-image: initial; border-style: solid; border-width: 0px; box-sizing: border-box; color: rgb(38 38 38/var(--tw-text-opacity)); font-weight: 700; overflow-wrap: break-word;&quot;&gt;Explanation:&lt;/span&gt; Initially, we have one character &#39;A&#39;.
In step 1, we use Copy All operation.
In step 2, we use Paste operation to get &#39;AA&#39;.
In step 3, we use Paste operation to get &#39;AAA&#39;.&lt;/pre&gt;&lt;pre style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-translate-x: 0; --tw-translate-y: 0; background-color: #f0f0f0; border-color: var(--border-tertiary); border-image: initial; border-style: solid; border-width: 0px 0px 0px 2px; box-sizing: border-box; color: var(--text-secondary); font-family: Menlo, sans-serif; font-size: 14px; line-height: 1.25rem; margin-bottom: 1rem; margin-top: 1rem; overflow-wrap: break-word; overflow: visible; padding-left: 1rem; text-wrap: wrap;&quot;&gt;&lt;span style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-text-opacity: 1; --tw-translate-x: 0; --tw-translate-y: 0; border-color: hsl(var(--sd-border)); border-image: initial; border-style: solid; border-width: 0px; box-sizing: border-box; color: rgb(38 38 38/var(--tw-text-opacity)); font-weight: 700; overflow-wrap: break-word;&quot;&gt;Input:&lt;/span&gt; n = 1
&lt;span style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-text-opacity: 1; --tw-translate-x: 0; --tw-translate-y: 0; border-color: hsl(var(--sd-border)); border-image: initial; border-style: solid; border-width: 0px; box-sizing: border-box; color: rgb(38 38 38/var(--tw-text-opacity)); font-weight: 700; overflow-wrap: break-word;&quot;&gt;Output:&lt;/span&gt; 0&lt;/pre&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;Approach:&lt;/b&gt; We are going to use bottom-up &lt;i&gt;DP&lt;/i&gt; here. We can define a 1D array where table[i] tells the minimum number of steps required to display i A&#39;s. Obviously table[n] will be our answer.&lt;/p&gt;&lt;p&gt;Now the main logic here is to get the relations between table[i] and table[i-1]...table[1], right?&amp;nbsp; Let&#39;s understand it; let&#39;s say we had j A&#39;s on the screen where 1 &amp;lt;= j &amp;lt; i. Now we can say we can copy these j A&#39;s and paste it exactly (i - j) / j times to display i A&#39;s so total number of operations will be:&lt;/p&gt;&lt;p&gt;&lt;i&gt;f(i) = f(j) + 1 + (i - j) / j&lt;/i&gt;&lt;/p&gt;&lt;p&gt;Why? Let&#39;s see:&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;f(j) - Number of steps to display j A&#39;s&lt;/li&gt;&lt;li&gt;1 - Copy All&lt;/li&gt;&lt;li&gt;(i - j) / j - Number of pastes.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;Now let&#39;s simplify this equation:&lt;/p&gt;&lt;p&gt;f(i) = f(j) + 1 + (i - j) / j&lt;/p&gt;&lt;p&gt;=&amp;gt; f(i) = f(j) + 1 + (i/j) - (j/j)&lt;/p&gt;&lt;p&gt;=&amp;gt; f(i) = f(j) + 1 + (i/j) - 1&lt;/p&gt;&lt;p&gt;=&amp;gt; f(i) = f(j) + i / j&lt;/p&gt;&lt;p&gt;So here is our final relation:&lt;/p&gt;&lt;p style=&quot;text-align: center;&quot;&gt;&lt;i&gt;f(i) = f(j) + i / j&lt;/i&gt;&lt;/p&gt;&lt;p&gt;We also need to make sure that i should be divisible by j as it&#39;s kind of repeated pastes. Now we just need to get the minimum of all such j&#39;s where 1 &amp;lt;= j &amp;lt; i and i is divisible by j.&lt;/p&gt;&lt;p&gt;That&#39;s all!&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;Implementation in C#:&lt;/b&gt;&lt;/p&gt;&lt;div style=&quot;background-color: white; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 13px; line-height: 18px; white-space: pre;&quot;&gt;&lt;div&gt;&lt;span style=&quot;color: blue;&quot;&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;/span&gt;public&lt;/span&gt; &lt;span style=&quot;color: blue;&quot;&gt;int&lt;/span&gt; &lt;span style=&quot;color: #795e26;&quot;&gt;MinSteps&lt;/span&gt;(&lt;span style=&quot;color: blue;&quot;&gt;int&lt;/span&gt; &lt;span style=&quot;color: #001080;&quot;&gt;n&lt;/span&gt;)&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; {&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #af00db;&quot;&gt;if&lt;/span&gt; (&lt;span style=&quot;color: #001080;&quot;&gt;n&lt;/span&gt; &amp;lt;= &lt;span style=&quot;color: #098658;&quot;&gt;1&lt;/span&gt;)&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; {&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #af00db;&quot;&gt;return&lt;/span&gt; &lt;span style=&quot;color: #098658;&quot;&gt;0&lt;/span&gt;;&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: blue;&quot;&gt;int&lt;/span&gt;[] &lt;span style=&quot;color: #001080;&quot;&gt;table&lt;/span&gt; = &lt;span style=&quot;color: blue;&quot;&gt;new&lt;/span&gt; &lt;span style=&quot;color: blue;&quot;&gt;int&lt;/span&gt;[&lt;span style=&quot;color: #001080;&quot;&gt;n&lt;/span&gt; + &lt;span style=&quot;color: #098658;&quot;&gt;1&lt;/span&gt;];&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #af00db;&quot;&gt;for&lt;/span&gt; (&lt;span style=&quot;color: blue;&quot;&gt;int&lt;/span&gt; &lt;span style=&quot;color: #001080;&quot;&gt;i&lt;/span&gt; = &lt;span style=&quot;color: #098658;&quot;&gt;2&lt;/span&gt;; &lt;span style=&quot;color: #001080;&quot;&gt;i&lt;/span&gt; &amp;lt;= &lt;span style=&quot;color: #001080;&quot;&gt;n&lt;/span&gt;; ++&lt;span style=&quot;color: #001080;&quot;&gt;i&lt;/span&gt;)&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; {&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #001080;&quot;&gt;table&lt;/span&gt;[&lt;span style=&quot;color: #001080;&quot;&gt;i&lt;/span&gt;] = &lt;span style=&quot;color: #001080;&quot;&gt;int&lt;/span&gt;.&lt;span style=&quot;color: #001080;&quot;&gt;MaxValue&lt;/span&gt;;&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #af00db;&quot;&gt;for&lt;/span&gt; (&lt;span style=&quot;color: blue;&quot;&gt;int&lt;/span&gt; &lt;span style=&quot;color: #001080;&quot;&gt;j&lt;/span&gt; = &lt;span style=&quot;color: #098658;&quot;&gt;1&lt;/span&gt;; &lt;span style=&quot;color: #001080;&quot;&gt;j&lt;/span&gt; &amp;lt;= &lt;span style=&quot;color: #001080;&quot;&gt;i&lt;/span&gt; / &lt;span style=&quot;color: #098658;&quot;&gt;2&lt;/span&gt;; ++&lt;span style=&quot;color: #001080;&quot;&gt;j&lt;/span&gt;)&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; {&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #af00db;&quot;&gt;if&lt;/span&gt; (&lt;span style=&quot;color: #001080;&quot;&gt;i&lt;/span&gt; % &lt;span style=&quot;color: #001080;&quot;&gt;j&lt;/span&gt; != &lt;span style=&quot;color: #098658;&quot;&gt;0&lt;/span&gt;)&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; {&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #af00db;&quot;&gt;continue&lt;/span&gt;;&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #001080;&quot;&gt;table&lt;/span&gt;[&lt;span style=&quot;color: #001080;&quot;&gt;i&lt;/span&gt;] = &lt;span style=&quot;color: #001080;&quot;&gt;Math&lt;/span&gt;.&lt;span style=&quot;color: #795e26;&quot;&gt;Min&lt;/span&gt;(&lt;span style=&quot;color: #001080;&quot;&gt;table&lt;/span&gt;[&lt;span style=&quot;color: #001080;&quot;&gt;i&lt;/span&gt;], &lt;span style=&quot;color: #001080;&quot;&gt;table&lt;/span&gt;[&lt;span style=&quot;color: #001080;&quot;&gt;j&lt;/span&gt;] + &lt;span style=&quot;color: #001080;&quot;&gt;i&lt;/span&gt; / &lt;span style=&quot;color: #001080;&quot;&gt;j&lt;/span&gt;);&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #af00db;&quot;&gt;return&lt;/span&gt; &lt;span style=&quot;color: #001080;&quot;&gt;table&lt;/span&gt;[&lt;span style=&quot;color: #001080;&quot;&gt;n&lt;/span&gt;];&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; }&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;Complexity:&lt;/b&gt; O(n^2)&lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='http://algods-cracker.blogspot.com/feeds/5588530542943403556/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://algods-cracker.blogspot.com/2024/08/leetcode-2-keys-keyboard.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7496974970329409400/posts/default/5588530542943403556'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7496974970329409400/posts/default/5588530542943403556'/><link rel='alternate' type='text/html' href='http://algods-cracker.blogspot.com/2024/08/leetcode-2-keys-keyboard.html' title='[LeetCode] 2 Keys Keyboard'/><author><name>Nishant Saxena</name><uri>http://www.blogger.com/profile/17860524009847591950</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjOdjS62BAEI1iMG_zd6lew4qyFGpfJhWHp0AJWQhiJvxQpSGg0AFZ5euJG7tK0D-EGQFno32hF-i1x4E2A49re_8-b9r0QHwXQ-9X_EvlAcekIjUYMaA1v6dWzDqzkBg/s220/2d230a1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7496974970329409400.post-1985433497369941513</id><published>2024-08-15T02:43:00.010+05:30</published><updated>2024-10-27T14:59:44.782+05:30</updated><category scheme="http://www.blogger.com/atom/ns#" term="System Design"/><title type='text'>Design Stack overflow</title><content type='html'>&lt;p&gt;&lt;b&gt;Problem:&lt;/b&gt; Design a highly scalable public discussion forum like reddit, quora or Stack Overflow. Here are the features that needs to be supported:&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;Post questions / news to public&lt;/li&gt;&lt;li&gt;Comments on existing posts&lt;/li&gt;&lt;li&gt;Upvote/downvote posts or comments&lt;/li&gt;&lt;li&gt;Feed of most popular posts.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;Requirements:&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;Functional requirements:&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;ol style=&quot;text-align: left;&quot;&gt;&lt;li&gt;This is browser only application.&lt;/li&gt;&lt;li&gt;A &lt;i&gt;logged in&lt;/i&gt; user only can post, comment and vote.&lt;/li&gt;&lt;li&gt;A post contains following:&lt;/li&gt;&lt;ul&gt;&lt;li&gt;Title&lt;/li&gt;&lt;li&gt;Tags&lt;/li&gt;&lt;li&gt;Body containing text and image&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;Any user (logged in) can comment on any post.&lt;/li&gt;&lt;li&gt;Comments are shown as list in descending order by time.&lt;/li&gt;&lt;li&gt;Use can delete his/her own comments or posts.&lt;/li&gt;&lt;li&gt;Any user can vote any post or comment.&lt;/li&gt;&lt;li&gt;A user&#39;s home page contains the top popular posts in the last 24 hours where:&lt;/li&gt;&lt;ul&gt;&lt;li&gt;&lt;i&gt;Popularity = Upvotes - Downvotes&lt;/i&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/ol&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;Non functional requirements:&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;ol style=&quot;text-align: left;&quot;&gt;&lt;li&gt;Scalabilty: Millions of daily users.&lt;/li&gt;&lt;li&gt;Performance: 500 ms response time 99 percentile.&lt;/li&gt;&lt;li&gt;Availability: Priority to availability over consistency as it is ok if the user won&#39;t see the latest data.&lt;/li&gt;&lt;li&gt;Durability: Have posts and comments till the user doesn&#39;t delete it.&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;Design:&lt;/b&gt; Now that the requirements are clear. We will start with our design.&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;b&gt;Step 1:&amp;nbsp; API design:&lt;/b&gt;&lt;/p&gt;&lt;p&gt;We will first try to come up with the &lt;i&gt;Rest&lt;/i&gt; APIs as per our functional requirements. For this we need to first identify what are the &lt;i&gt;entities&lt;/i&gt; in our system and try to map those to &lt;i&gt;URIs&lt;/i&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;Users:&amp;nbsp;&lt;/li&gt;&lt;ul&gt;&lt;li&gt;/users&lt;/li&gt;&lt;li&gt;/users/{user-id}&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;Posts:&lt;/li&gt;&lt;ul&gt;&lt;li&gt;/posts&lt;/li&gt;&lt;li&gt;/posts/{post-id}&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;Images&lt;/li&gt;&lt;ul&gt;&lt;li&gt;/posts/{post-id}/images&lt;/li&gt;&lt;li&gt;/posts/{post-id}/images/{image-id}&lt;/li&gt;&lt;li&gt;/posts/{post-id}/comments/{comment-id}/images&lt;/li&gt;&lt;li&gt;/posts/{post-id}/comments/{comment-id}/images/{image-id}&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;Comments&lt;/li&gt;&lt;ul&gt;&lt;li&gt;/posts/{post-id}/comments&lt;/li&gt;&lt;li&gt;/posts/{post-id}/images/{comment-id}&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;Votes&lt;/li&gt;&lt;ul&gt;&lt;li&gt;/posts/{post-id}/vote&lt;/li&gt;&lt;li&gt;/posts/{post-id}/comments/{comment-id}/vote&lt;/li&gt;&lt;/ul&gt;&lt;/ul&gt;&lt;div&gt;Let&#39;s see how the post looks like: (response of GET)&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;background-color: #eeeeee;&quot;&gt;{&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;background-color: #eeeeee;&quot;&gt;&lt;span&gt;&amp;nbsp; &amp;nbsp; post_id: string&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;background-color: #eeeeee;&quot;&gt;&lt;span&gt;&amp;nbsp; &amp;nbsp; title: string&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span style=&quot;background-color: #eeeeee;&quot;&gt;&lt;span&gt;&amp;nbsp; &amp;nbsp; tags: List of strings&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;&lt;span style=&quot;background-color: #eeeeee;&quot;&gt;&lt;span&gt;&amp;nbsp; &amp;nbsp; user_id: string&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span style=&quot;background-color: #eeeeee;&quot;&gt;&lt;span&gt;&amp;nbsp; &amp;nbsp; upvotes: int&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span style=&quot;background-color: #eeeeee;&quot;&gt;&lt;span&gt;&amp;nbsp; &amp;nbsp; downvotes: int&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span style=&quot;background-color: #eeeeee;&quot;&gt;&lt;span&gt;&amp;nbsp; &amp;nbsp; body: json&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;background-color: #eeeeee;&quot;&gt;}&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Let&#39;s see how the comment looks like: (response of GET):&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;background-color: #eeeeee;&quot;&gt;{&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;background-color: #eeeeee;&quot;&gt;&lt;span&gt;&amp;nbsp; &amp;nbsp; post_id: string&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;background-color: #eeeeee;&quot;&gt;&lt;span&gt;&amp;nbsp; &amp;nbsp; comment_id: string&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;background-color: #eeeeee;&quot;&gt;&lt;span&gt;&amp;nbsp; &amp;nbsp; body: json&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;background-color: #eeeeee;&quot;&gt;&lt;span&gt;&amp;nbsp; &amp;nbsp; user_id:&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span style=&quot;background-color: #eeeeee;&quot;&gt;&lt;span&gt;&amp;nbsp; &amp;nbsp; upvotes: int&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;&lt;span style=&quot;background-color: #eeeeee;&quot;&gt;&lt;span&gt;&amp;nbsp; &amp;nbsp; downvotes: int&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;background-color: #eeeeee;&quot;&gt;}&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Now that we know the entities and URIs, its time to assign the HTTP method which wll ultimately results ino our final APIs:&lt;/div&gt;&lt;div&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;&lt;b&gt;Users:&lt;/b&gt;&lt;/li&gt;&lt;ul&gt;&lt;li&gt;POST /users/ - Create/signup a new user&lt;/li&gt;&lt;li&gt;POST /users/login - Login a user&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;&lt;b&gt;Posts:&lt;/b&gt;&lt;/li&gt;&lt;ul&gt;&lt;li&gt;POST /posts - Create a new post&amp;nbsp;&lt;/li&gt;&lt;li&gt;GET /posts - View posts. Response of this requires pagination as it can contain even 1 million posts so the parameters can be:&lt;/li&gt;&lt;ul&gt;&lt;li&gt;limit&lt;/li&gt;&lt;li&gt;offset&lt;/li&gt;&lt;li&gt;user_id (optional)&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;GET /posts/post-id - View a post&lt;/li&gt;&lt;li&gt;DELETE /posts/post-id - Delete a post&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;&lt;b&gt;Comments:&lt;/b&gt;&lt;/li&gt;&lt;ul&gt;&lt;li&gt;POST /posts/{post-id}/comments - Create new comment&lt;/li&gt;&lt;li&gt;GET /posts/{post-id}/comments - View post&#39;s list of comments&lt;/li&gt;&lt;li&gt;GET /posts/{post-id}/comment/{comment-id} - View a comment&lt;/li&gt;&lt;li&gt;DELETE /posts/{post-id}/comment/{comment-id} - Delete a comment&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;&lt;b&gt;Votes:&lt;/b&gt;&lt;/li&gt;&lt;ul&gt;&lt;li&gt;POST /posts/{post-id}/vote - Upvote/downvote a post&lt;/li&gt;&lt;li&gt;POST /posts/{post-id}/comments/{comment-id}/vote - Upvote/downvote a comment&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;&lt;b&gt;Images:&lt;/b&gt;&lt;/li&gt;&lt;ul&gt;&lt;li&gt;POST /posts/{post-id}/images - Upload a image to a post body&lt;/li&gt;&lt;li&gt;GET /posts/{post-id}/images/{image-id} - Get an image of post&lt;/li&gt;&lt;li&gt;POST /posts/{post-id}/comments/{comment-id}/images - Upload a image to a comment body&lt;/li&gt;&lt;li&gt;GET /posts/{post-id}/comments/{comment-id}/images/{image-id} - Get an image of a comment&lt;/li&gt;&lt;/ul&gt;&lt;/ul&gt;&lt;div&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;Step 2: Mapping functional requirements to architectural diagram:&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;1. Browser only application:&lt;/b&gt; For this we will have &lt;i&gt;web app service&lt;/i&gt; which will serve static web pages.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/a/AVvXsEjvKFa3iWZ5yB3raX948wnITi4jr675lwQ2bmr9lef1sQNmQ46_JMSiyq0IYlfPkVel8jx50G3sDs9OO8uSH51mAGH9tF5BsGYsTAdBjf6zsrAC_j4eDTD-ZChxvh4jU8pAVTUafuMQ0Jkj1lPBR93LC4ynHR_pWAl3j6ekmPONRIJBrK1pFl5ZuJcGe9Q&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img alt=&quot;&quot; data-original-height=&quot;422&quot; data-original-width=&quot;261&quot; height=&quot;313&quot; src=&quot;https://blogger.googleusercontent.com/img/a/AVvXsEjvKFa3iWZ5yB3raX948wnITi4jr675lwQ2bmr9lef1sQNmQ46_JMSiyq0IYlfPkVel8jx50G3sDs9OO8uSH51mAGH9tF5BsGYsTAdBjf6zsrAC_j4eDTD-ZChxvh4jU8pAVTUafuMQ0Jkj1lPBR93LC4ynHR_pWAl3j6ekmPONRIJBrK1pFl5ZuJcGe9Q=w193-h313&quot; width=&quot;193&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;b&gt;2. User Sign up / login:&lt;/b&gt; We will have a user service and this service have its own DB to store user info which we can choose as SQL DB as it&#39;s going to be structured data and also its not going to be huge.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/a/AVvXsEhlx1yx5JGQ4F1fssrXbrEXQu5U91BQPr8s6-LYmrxmzThlYu8IrAijLj-JMQNfbc3mFyVmE7mTbiUJp80_CsKB4za1xk96l_qHyxSh6hhttbx4OGxQX34TcZB1O0Vq3k8SPcBkgknMXlSL38hfPk51jKOBecHyqEK4iVCPpCR4W7mNVoihrjS0zpUqqqQ&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img alt=&quot;&quot; data-original-height=&quot;422&quot; data-original-width=&quot;621&quot; height=&quot;250&quot; src=&quot;https://blogger.googleusercontent.com/img/a/AVvXsEhlx1yx5JGQ4F1fssrXbrEXQu5U91BQPr8s6-LYmrxmzThlYu8IrAijLj-JMQNfbc3mFyVmE7mTbiUJp80_CsKB4za1xk96l_qHyxSh6hhttbx4OGxQX34TcZB1O0Vq3k8SPcBkgknMXlSL38hfPk51jKOBecHyqEK4iVCPpCR4W7mNVoihrjS0zpUqqqQ=w369-h250&quot; width=&quot;369&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;3.&amp;nbsp; Create/Delete a post:&lt;/b&gt; Again for this we will have another microservice say post service which will have it&#39;s own DB. As these number of posts are going to be huge and also post schema, we may want to vary time to time, I am going to use Nosql DB for this.&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Given we can upload an image in the post, we can use any blob store to save the imges so if the post contains the image, a request will go to web app service which will upload the image to blob store and then take the image-id and put it in the post body and send a request posts service to save the post&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;While viewing the post, first we will get the post content using the posts service and then when the browser sees the image url, it can directly fetch from the blob store using the url.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/a/AVvXsEiNHInMT3T3HfMOVZzqL5E3b6fFqi7033LH7YrE2kkKhdfs-1HHMO2_DLf74q4Q3F9pd7O2wJR1-r5sl9CX7unZEufMsOn-PLPZPbl6oKFinYxVIaoefRvGD8Qy5hJBzKcrCymygdT-HeZXO37LSVlnSe18ppLPDaJhGNEKD_kTUcbuLGbosDDK-qvRPcY&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img alt=&quot;&quot; data-original-height=&quot;422&quot; data-original-width=&quot;621&quot; height=&quot;303&quot; src=&quot;https://blogger.googleusercontent.com/img/a/AVvXsEiNHInMT3T3HfMOVZzqL5E3b6fFqi7033LH7YrE2kkKhdfs-1HHMO2_DLf74q4Q3F9pd7O2wJR1-r5sl9CX7unZEufMsOn-PLPZPbl6oKFinYxVIaoefRvGD8Qy5hJBzKcrCymygdT-HeZXO37LSVlnSe18ppLPDaJhGNEKD_kTUcbuLGbosDDK-qvRPcY=w446-h303&quot; width=&quot;446&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;4. Posting comments / Deleting comments:&amp;nbsp;&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;5. Comments are shown in list in descending order of posting time:&lt;/b&gt;&lt;/div&gt;&lt;div&gt;We can use a different microservice Comments with it&#39;s own DB but we can merge it with Post service and use the same DB. As you see comments are tightly attached to post and also their schema is almost same except comments will have a post id attached to it. We also need to add a timestamp fields as we need to show comments in sorted order.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;We can opt for any approach but I am choosing to have one micro service for posts and comments and calling it Post and Comment service.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;If you see we are also satisfying &lt;i style=&quot;font-weight: bold;&quot;&gt;FR 6: Deleting posts and comments &lt;/i&gt;here&lt;i&gt;.&lt;/i&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/a/AVvXsEh4prHmkyjPtsGf8yWnbEHlKoECy52JqN2q7Azm977vPutBJ5KyJiqbzuQwhVvEe7yZegiifnXlmbYAxbXiTXnKevyxEeskGRbQTX5DZ4Af4FujCaQTX4hAyqnUuFoSjx43T7qFwJpbT4vO7F65t9aB7T_qBMbRMdXqA94CRzFjwzfV-Ecsjhpi747q9gA&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img alt=&quot;&quot; data-original-height=&quot;422&quot; data-original-width=&quot;621&quot; height=&quot;294&quot; src=&quot;https://blogger.googleusercontent.com/img/a/AVvXsEh4prHmkyjPtsGf8yWnbEHlKoECy52JqN2q7Azm977vPutBJ5KyJiqbzuQwhVvEe7yZegiifnXlmbYAxbXiTXnKevyxEeskGRbQTX5DZ4Af4FujCaQTX4hAyqnUuFoSjx43T7qFwJpbT4vO7F65t9aB7T_qBMbRMdXqA94CRzFjwzfV-Ecsjhpi747q9gA=w434-h294&quot; width=&quot;434&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;b&gt;7. Upvote or downvote a post or comment:&lt;/b&gt; For this functionality, we will have a different service say Votes service with its on DB. Now we have a choice here:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;We can just maintain a schema like folllows:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;table aria-rowcount=&quot;2&quot; border=&quot;1&quot; class=&quot;Table Ltr TableWordWrap SCXW31144044 BCX0&quot; data-tablelook=&quot;1696&quot; data-tablestyle=&quot;MsoTableGrid&quot; style=&quot;-webkit-tap-highlight-color: transparent; -webkit-user-drag: none; background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; background-position: initial; background-repeat: initial; background-size: initial; border-collapse: collapse; border-spacing: 0px; color: black; empty-cells: show; font-family: &amp;quot;Segoe UI&amp;quot;, &amp;quot;Segoe UI Web&amp;quot;, Arial, Verdana, sans-serif; font-size: 12px; margin: 0px; overflow: visible; padding: 0px; position: relative; table-layout: fixed; user-select: text; width: 0px;&quot;&gt;&lt;tbody class=&quot;SCXW31144044 BCX0&quot; style=&quot;-webkit-tap-highlight-color: transparent; -webkit-user-drag: none; margin: 0px; padding: 0px; user-select: text;&quot;&gt;&lt;tr aria-rowindex=&quot;1&quot; class=&quot;TableRow SCXW31144044 BCX0&quot; role=&quot;row&quot; style=&quot;-webkit-tap-highlight-color: transparent; -webkit-user-drag: none; height: 20px; margin: 0px; overflow: visible; padding: 0px; user-select: text;&quot;&gt;&lt;td class=&quot;FirstRow FirstCol SCXW31144044 BCX0&quot; data-celllook=&quot;0&quot; role=&quot;rowheader&quot; style=&quot;-webkit-tap-highlight-color: transparent; -webkit-user-drag: none; background-clip: padding-box; border: 1px solid; margin: 0px; overflow: visible; padding: 0px; position: relative; user-select: text; vertical-align: top; width: 312px;&quot;&gt;&lt;div class=&quot;TableCellContent SCXW31144044 BCX0&quot; style=&quot;-webkit-tap-highlight-color: transparent; -webkit-user-drag: none; margin: 0px; overflow: visible; padding: 0px 7px; user-select: text;&quot;&gt;&lt;div class=&quot;OutlineElement Ltr SCXW31144044 BCX0&quot; style=&quot;-webkit-tap-highlight-color: transparent; -webkit-user-drag: none; clear: both; cursor: text; direction: ltr; margin: 0px; overflow: visible; padding: 0px; position: relative; user-select: text;&quot;&gt;&lt;p class=&quot;Paragraph SCXW31144044 BCX0&quot; lang=&quot;EN-US&quot; paraeid=&quot;{7a221504-deaf-4a12-beaa-1ae27e891a10}{21}&quot; paraid=&quot;813882011&quot; style=&quot;-webkit-tap-highlight-color: transparent; -webkit-user-drag: none; color: windowtext; font-kerning: none; margin: 0px; overflow-wrap: break-word; padding: 0px; user-select: text; vertical-align: baseline; white-space-collapse: preserve;&quot; xml:lang=&quot;EN-US&quot;&gt;&lt;span class=&quot;TextRun SCXW31144044 BCX0&quot; data-contrast=&quot;auto&quot; face=&quot;Aptos, Aptos_EmbeddedFont, Aptos_MSFontService, sans-serif&quot; lang=&quot;EN-US&quot; style=&quot;-webkit-tap-highlight-color: transparent; -webkit-user-drag: none; font-size: 12pt; font-variant-ligatures: none; line-height: 20.925px; margin: 0px; padding: 0px; user-select: text;&quot; xml:lang=&quot;EN-US&quot;&gt;Post Id&lt;/span&gt;&lt;span class=&quot;EOP SCXW31144044 BCX0&quot; data-ccp-props=&quot;{&amp;quot;201341983&amp;quot;:0,&amp;quot;335559740&amp;quot;:279}&quot; face=&quot;Aptos, Aptos_EmbeddedFont, Aptos_MSFontService, sans-serif&quot; style=&quot;-webkit-tap-highlight-color: transparent; -webkit-user-drag: none; font-size: 12pt; line-height: 20.925px; margin: 0px; padding: 0px; user-select: text;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;FirstRow LastCol SCXW31144044 BCX0&quot; data-celllook=&quot;0&quot; role=&quot;columnheader&quot; style=&quot;-webkit-tap-highlight-color: transparent; -webkit-user-drag: none; background-clip: padding-box; border: 1px solid; margin: 0px; overflow: visible; padding: 0px; position: relative; user-select: text; vertical-align: top; width: 312px;&quot;&gt;&lt;div class=&quot;TableCellContent SCXW31144044 BCX0&quot; style=&quot;-webkit-tap-highlight-color: transparent; -webkit-user-drag: none; margin: 0px; overflow: visible; padding: 0px 7px; user-select: text;&quot;&gt;&lt;div class=&quot;OutlineElement Ltr SCXW31144044 BCX0&quot; style=&quot;-webkit-tap-highlight-color: transparent; -webkit-user-drag: none; clear: both; cursor: text; direction: ltr; margin: 0px; overflow: visible; padding: 0px; position: relative; user-select: text;&quot;&gt;&lt;p class=&quot;Paragraph SCXW31144044 BCX0&quot; lang=&quot;EN-US&quot; paraeid=&quot;{7a221504-deaf-4a12-beaa-1ae27e891a10}{27}&quot; paraid=&quot;1628512909&quot; style=&quot;-webkit-tap-highlight-color: transparent; -webkit-user-drag: none; color: windowtext; font-kerning: none; margin: 0px; overflow-wrap: break-word; padding: 0px; user-select: text; vertical-align: baseline; white-space-collapse: preserve;&quot; xml:lang=&quot;EN-US&quot;&gt;&lt;span class=&quot;TextRun SCXW31144044 BCX0&quot; data-contrast=&quot;auto&quot; face=&quot;Aptos, Aptos_EmbeddedFont, Aptos_MSFontService, sans-serif&quot; lang=&quot;EN-US&quot; style=&quot;-webkit-tap-highlight-color: transparent; -webkit-user-drag: none; font-size: 12pt; font-variant-ligatures: none; line-height: 20.925px; margin: 0px; padding: 0px; user-select: text;&quot; xml:lang=&quot;EN-US&quot;&gt;count&lt;/span&gt;&lt;span class=&quot;EOP SCXW31144044 BCX0&quot; data-ccp-props=&quot;{&amp;quot;201341983&amp;quot;:0,&amp;quot;335559740&amp;quot;:279}&quot; face=&quot;Aptos, Aptos_EmbeddedFont, Aptos_MSFontService, sans-serif&quot; style=&quot;-webkit-tap-highlight-color: transparent; -webkit-user-drag: none; font-size: 12pt; line-height: 20.925px; margin: 0px; padding: 0px; user-select: text;&quot;&gt;&lt;/span&gt;&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr aria-rowindex=&quot;2&quot; class=&quot;TableRow SCXW31144044 BCX0&quot; role=&quot;row&quot; style=&quot;-webkit-tap-highlight-color: transparent; -webkit-user-drag: none; height: 20px; margin: 0px; overflow: visible; padding: 0px; user-select: text;&quot;&gt;&lt;td class=&quot;FirstCol LastRow SCXW31144044 BCX0&quot; data-celllook=&quot;0&quot; role=&quot;rowheader&quot; style=&quot;-webkit-tap-highlight-color: transparent; -webkit-user-drag: none; background-clip: padding-box; border: 1px solid; margin: 0px; overflow: visible; padding: 0px; position: relative; user-select: text; vertical-align: top; width: 312px;&quot;&gt;&lt;div class=&quot;TableCellContent SCXW31144044 BCX0&quot; style=&quot;-webkit-tap-highlight-color: transparent; -webkit-user-drag: none; margin: 0px; overflow: visible; padding: 0px 7px; user-select: text;&quot;&gt;&lt;div class=&quot;OutlineElement Ltr SCXW31144044 BCX0&quot; style=&quot;-webkit-tap-highlight-color: transparent; -webkit-user-drag: none; clear: both; cursor: text; direction: ltr; margin: 0px; overflow: visible; padding: 0px; position: relative; user-select: text;&quot;&gt;&lt;p class=&quot;Paragraph SCXW31144044 BCX0&quot; lang=&quot;EN-US&quot; paraeid=&quot;{7a221504-deaf-4a12-beaa-1ae27e891a10}{33}&quot; paraid=&quot;1216480242&quot; style=&quot;-webkit-tap-highlight-color: transparent; -webkit-user-drag: none; color: windowtext; font-kerning: none; margin: 0px; overflow-wrap: break-word; padding: 0px; user-select: text; vertical-align: baseline; white-space-collapse: preserve;&quot; xml:lang=&quot;EN-US&quot;&gt;&lt;span class=&quot;TextRun SCXW31144044 BCX0&quot; data-contrast=&quot;auto&quot; face=&quot;Aptos, Aptos_EmbeddedFont, Aptos_MSFontService, sans-serif&quot; lang=&quot;EN-US&quot; style=&quot;-webkit-tap-highlight-color: transparent; -webkit-user-drag: none; font-size: 12pt; font-variant-ligatures: none; line-height: 20.925px; margin: 0px; padding: 0px; user-select: text;&quot; xml:lang=&quot;EN-US&quot;&gt;Comment Id&lt;/span&gt;&lt;span class=&quot;EOP SCXW31144044 BCX0&quot; data-ccp-props=&quot;{&amp;quot;201341983&amp;quot;:0,&amp;quot;335559740&amp;quot;:279}&quot; face=&quot;Aptos, Aptos_EmbeddedFont, Aptos_MSFontService, sans-serif&quot; style=&quot;-webkit-tap-highlight-color: transparent; -webkit-user-drag: none; font-size: 12pt; line-height: 20.925px; margin: 0px; padding: 0px; user-select: text;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;LastCol LastRow SCXW31144044 BCX0&quot; data-celllook=&quot;0&quot; style=&quot;-webkit-tap-highlight-color: transparent; -webkit-user-drag: none; background-clip: padding-box; border: 1px solid; margin: 0px; overflow: visible; padding: 0px; position: relative; user-select: text; vertical-align: top; width: 312px;&quot;&gt;&lt;div class=&quot;TableCellContent SCXW31144044 BCX0&quot; style=&quot;-webkit-tap-highlight-color: transparent; -webkit-user-drag: none; margin: 0px; overflow: visible; padding: 0px 7px; user-select: text;&quot;&gt;&lt;div class=&quot;OutlineElement Ltr SCXW31144044 BCX0&quot; style=&quot;-webkit-tap-highlight-color: transparent; -webkit-user-drag: none; clear: both; cursor: text; direction: ltr; margin: 0px; overflow: visible; padding: 0px; position: relative; user-select: text;&quot;&gt;&lt;p class=&quot;Paragraph SCXW31144044 BCX0&quot; lang=&quot;EN-US&quot; paraeid=&quot;{7a221504-deaf-4a12-beaa-1ae27e891a10}{37}&quot; paraid=&quot;754514062&quot; style=&quot;-webkit-tap-highlight-color: transparent; -webkit-user-drag: none; color: windowtext; font-kerning: none; margin: 0px; overflow-wrap: break-word; padding: 0px; user-select: text; vertical-align: baseline; white-space-collapse: preserve;&quot; xml:lang=&quot;EN-US&quot;&gt;&lt;span class=&quot;TextRun SCXW31144044 BCX0&quot; data-contrast=&quot;auto&quot; face=&quot;Aptos, Aptos_EmbeddedFont, Aptos_MSFontService, sans-serif&quot; lang=&quot;EN-US&quot; style=&quot;-webkit-tap-highlight-color: transparent; -webkit-user-drag: none; font-size: 12pt; font-variant-ligatures: none; line-height: 20.925px; margin: 0px; padding: 0px; user-select: text;&quot; xml:lang=&quot;EN-US&quot;&gt;count&lt;/span&gt;&lt;span class=&quot;EOP SCXW31144044 BCX0&quot; data-ccp-props=&quot;{&amp;quot;201341983&amp;quot;:0,&amp;quot;335559740&amp;quot;:279}&quot; face=&quot;Aptos, Aptos_EmbeddedFont, Aptos_MSFontService, sans-serif&quot; style=&quot;-webkit-tap-highlight-color: transparent; -webkit-user-drag: none; font-size: 12pt; line-height: 20.925px; margin: 0px; padding: 0px; user-select: text;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;But the problem with the above schema is&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;We can&#39;t restrict user to just vote once for a single post/comment.&lt;/li&gt;&lt;li&gt;FR 7: Can&#39;t get popular posts of last 24 hours.&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;That means we can&#39;t go wth the above schema. Hence here is the schema which I am proposing:&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div class=&quot;OutlineElement Ltr SCXW105878675 BCX0&quot; style=&quot;-webkit-tap-highlight-color: transparent; -webkit-user-drag: none; background-color: white; clear: both; cursor: text; direction: ltr; font-family: &amp;quot;Segoe UI&amp;quot;, &amp;quot;Segoe UI Web&amp;quot;, Arial, Verdana, sans-serif; font-size: 12px; margin: 0px; overflow: visible; padding: 0px; position: relative; user-select: text;&quot;&gt;&lt;div class=&quot;TableContainer Ltr SCXW105878675 BCX0&quot; style=&quot;-webkit-tap-highlight-color: transparent; -webkit-user-drag: none; display: flex; justify-content: flex-start; margin: 2px 0px 2px -5px; overflow: visible; padding: 0px; position: relative; user-select: text;&quot;&gt;&lt;div aria-hidden=&quot;true&quot; class=&quot;WACAltTextDescribedBy SCXW105878675 BCX0&quot; id=&quot;{6e56d7a9-9438-4caf-8fdd-f936d74b61da}{54}&quot; style=&quot;-webkit-tap-highlight-color: transparent; -webkit-user-drag: none; margin: 0px; padding: 0px; position: absolute; user-select: text; visibility: hidden; z-index: -100;&quot;&gt;&lt;/div&gt;&lt;table aria-rowcount=&quot;2&quot; border=&quot;1&quot; class=&quot;Table Ltr TableWordWrap SCXW105878675 BCX0&quot; data-tablelook=&quot;1696&quot; data-tablestyle=&quot;MsoTableGrid&quot; style=&quot;-webkit-tap-highlight-color: transparent; -webkit-user-drag: none; background: transparent; border-collapse: collapse; border-spacing: 0px; empty-cells: show; margin: 0px; overflow: visible; padding: 0px; position: relative; table-layout: fixed; user-select: text; width: 0px;&quot;&gt;&lt;tbody class=&quot;SCXW105878675 BCX0&quot; style=&quot;-webkit-tap-highlight-color: transparent; -webkit-user-drag: none; margin: 0px; padding: 0px; user-select: text;&quot;&gt;&lt;tr aria-rowindex=&quot;1&quot; class=&quot;TableRow SCXW105878675 BCX0&quot; role=&quot;row&quot; style=&quot;-webkit-tap-highlight-color: transparent; -webkit-user-drag: none; height: 20px; margin: 0px; overflow: visible; padding: 0px; user-select: text;&quot;&gt;&lt;td class=&quot;FirstRow FirstCol SCXW105878675 BCX0&quot; data-celllook=&quot;0&quot; role=&quot;rowheader&quot; style=&quot;-webkit-tap-highlight-color: transparent; -webkit-user-drag: none; background-clip: padding-box; background-color: transparent; border: 1px solid; margin: 0px; overflow: visible; padding: 0px; position: relative; user-select: text; vertical-align: top; width: 156px;&quot;&gt;&lt;div class=&quot;TableCellContent SCXW105878675 BCX0&quot; style=&quot;-webkit-tap-highlight-color: transparent; -webkit-user-drag: none; margin: 0px; overflow: visible; padding: 0px 7px; user-select: text;&quot;&gt;&lt;div class=&quot;OutlineElement Ltr SCXW105878675 BCX0&quot; style=&quot;-webkit-tap-highlight-color: transparent; -webkit-user-drag: none; clear: both; cursor: text; direction: ltr; margin: 0px; overflow: visible; padding: 0px; position: relative; user-select: text;&quot;&gt;&lt;p class=&quot;Paragraph SCXW105878675 BCX0&quot; lang=&quot;EN-US&quot; paraeid=&quot;{6b393b23-1d3f-4f44-964f-f56d936f5ccb}{135}&quot; paraid=&quot;1006414071&quot; style=&quot;-webkit-tap-highlight-color: transparent; -webkit-user-drag: none; background-color: transparent; color: windowtext; font-kerning: none; margin: 0px; overflow-wrap: break-word; padding: 0px; user-select: text; vertical-align: baseline; white-space-collapse: preserve;&quot; xml:lang=&quot;EN-US&quot;&gt;&lt;span class=&quot;TextRun SCXW105878675 BCX0&quot; data-contrast=&quot;auto&quot; face=&quot;Aptos, Aptos_EmbeddedFont, Aptos_MSFontService, sans-serif&quot; lang=&quot;EN-US&quot; style=&quot;-webkit-tap-highlight-color: transparent; -webkit-user-drag: none; font-size: 12pt; font-variant-ligatures: none; line-height: 20.925px; margin: 0px; padding: 0px; user-select: text;&quot; xml:lang=&quot;EN-US&quot;&gt;&lt;span class=&quot;NormalTextRun SpellingErrorV2Themed SCXW105878675 BCX0&quot; style=&quot;-webkit-tap-highlight-color: transparent; -webkit-user-drag: none; background-image: var(--urlSpellingErrorV2,url(&amp;quot;data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI1IiBoZWlnaHQ9IjQiPjxnIGZpbGw9Im5vbmUiIGZpbGwtcnVsZT0iZXZlbm9kZCI+PHBhdGggc3Ryb2tlPSIjRUIwMDAwIiBkPSJNMCAzYzEuMjUgMCAxLjI1LTIgMi41LTJTMy43NSAzIDUgMyIvPjxwYXRoIGQ9Ik0wIDBoNXY0SDB6Ii8+PC9nPjwvc3ZnPg==&amp;quot;)); background-position: 0px 100%; background-repeat: repeat-x; border-bottom: 1px solid transparent; margin: 0px; padding: 0px; user-select: text;&quot;&gt;Post_id&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;EOP SCXW105878675 BCX0&quot; data-ccp-props=&quot;{&amp;quot;201341983&amp;quot;:0,&amp;quot;335559740&amp;quot;:279}&quot; face=&quot;Aptos, Aptos_EmbeddedFont, Aptos_MSFontService, sans-serif&quot; style=&quot;-webkit-tap-highlight-color: transparent; -webkit-user-drag: none; font-size: 12pt; line-height: 20.925px; margin: 0px; padding: 0px; user-select: text;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;FirstRow SCXW105878675 BCX0&quot; data-celllook=&quot;0&quot; role=&quot;columnheader&quot; style=&quot;-webkit-tap-highlight-color: transparent; -webkit-user-drag: none; background-clip: padding-box; background-color: transparent; border: 1px solid; margin: 0px; overflow: visible; padding: 0px; position: relative; user-select: text; vertical-align: top; width: 156px;&quot;&gt;&lt;div class=&quot;TableCellContent SCXW105878675 BCX0&quot; style=&quot;-webkit-tap-highlight-color: transparent; -webkit-user-drag: none; margin: 0px; overflow: visible; padding: 0px 7px; user-select: text;&quot;&gt;&lt;div class=&quot;OutlineElement Ltr SCXW105878675 BCX0&quot; style=&quot;-webkit-tap-highlight-color: transparent; -webkit-user-drag: none; clear: both; cursor: text; direction: ltr; margin: 0px; overflow: visible; padding: 0px; position: relative; user-select: text;&quot;&gt;&lt;p class=&quot;Paragraph SCXW105878675 BCX0&quot; lang=&quot;EN-US&quot; paraeid=&quot;{6b393b23-1d3f-4f44-964f-f56d936f5ccb}{141}&quot; paraid=&quot;585864587&quot; style=&quot;-webkit-tap-highlight-color: transparent; -webkit-user-drag: none; background-color: transparent; color: windowtext; font-kerning: none; margin: 0px; overflow-wrap: break-word; padding: 0px; user-select: text; vertical-align: baseline; white-space-collapse: preserve;&quot; xml:lang=&quot;EN-US&quot;&gt;&lt;span class=&quot;TextRun SCXW105878675 BCX0&quot; data-contrast=&quot;auto&quot; face=&quot;Aptos, Aptos_EmbeddedFont, Aptos_MSFontService, sans-serif&quot; lang=&quot;EN-US&quot; style=&quot;-webkit-tap-highlight-color: transparent; -webkit-user-drag: none; font-size: 12pt; font-variant-ligatures: none; line-height: 20.925px; margin: 0px; padding: 0px; user-select: text;&quot; xml:lang=&quot;EN-US&quot;&gt;&lt;span class=&quot;NormalTextRun SpellingErrorV2Themed SCXW105878675 BCX0&quot; style=&quot;-webkit-tap-highlight-color: transparent; -webkit-user-drag: none; background-image: var(--urlSpellingErrorV2,url(&amp;quot;data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI1IiBoZWlnaHQ9IjQiPjxnIGZpbGw9Im5vbmUiIGZpbGwtcnVsZT0iZXZlbm9kZCI+PHBhdGggc3Ryb2tlPSIjRUIwMDAwIiBkPSJNMCAzYzEuMjUgMCAxLjI1LTIgMi41LTJTMy43NSAzIDUgMyIvPjxwYXRoIGQ9Ik0wIDBoNXY0SDB6Ii8+PC9nPjwvc3ZnPg==&amp;quot;)); background-position: 0px 100%; background-repeat: repeat-x; border-bottom: 1px solid transparent; margin: 0px; padding: 0px; user-select: text;&quot;&gt;User_id&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;EOP SCXW105878675 BCX0&quot; data-ccp-props=&quot;{&amp;quot;201341983&amp;quot;:0,&amp;quot;335559740&amp;quot;:279}&quot; face=&quot;Aptos, Aptos_EmbeddedFont, Aptos_MSFontService, sans-serif&quot; style=&quot;-webkit-tap-highlight-color: transparent; -webkit-user-drag: none; font-size: 12pt; line-height: 20.925px; margin: 0px; padding: 0px; user-select: text;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;FirstRow SCXW105878675 BCX0&quot; data-celllook=&quot;0&quot; role=&quot;columnheader&quot; style=&quot;-webkit-tap-highlight-color: transparent; -webkit-user-drag: none; background-clip: padding-box; background-color: transparent; border: 1px solid; margin: 0px; overflow: visible; padding: 0px; position: relative; user-select: text; vertical-align: top; width: 156px;&quot;&gt;&lt;div class=&quot;TableCellContent SCXW105878675 BCX0&quot; style=&quot;-webkit-tap-highlight-color: transparent; -webkit-user-drag: none; margin: 0px; overflow: visible; padding: 0px 7px; user-select: text;&quot;&gt;&lt;div class=&quot;OutlineElement Ltr SCXW105878675 BCX0&quot; style=&quot;-webkit-tap-highlight-color: transparent; -webkit-user-drag: none; clear: both; cursor: text; direction: ltr; margin: 0px; overflow: visible; padding: 0px; position: relative; user-select: text;&quot;&gt;&lt;p class=&quot;Paragraph SCXW105878675 BCX0&quot; lang=&quot;EN-US&quot; paraeid=&quot;{6b393b23-1d3f-4f44-964f-f56d936f5ccb}{147}&quot; paraid=&quot;1301968357&quot; style=&quot;-webkit-tap-highlight-color: transparent; -webkit-user-drag: none; background-color: transparent; color: windowtext; font-kerning: none; margin: 0px; overflow-wrap: break-word; padding: 0px; user-select: text; vertical-align: baseline; white-space-collapse: preserve;&quot; xml:lang=&quot;EN-US&quot;&gt;&lt;span class=&quot;TextRun SCXW105878675 BCX0&quot; data-contrast=&quot;auto&quot; face=&quot;Aptos, Aptos_EmbeddedFont, Aptos_MSFontService, sans-serif&quot; lang=&quot;EN-US&quot; style=&quot;-webkit-tap-highlight-color: transparent; -webkit-user-drag: none; font-size: 12pt; font-variant-ligatures: none; line-height: 20.925px; margin: 0px; padding: 0px; user-select: text;&quot; xml:lang=&quot;EN-US&quot;&gt;Vote (+1 / -1)&lt;/span&gt;&lt;span class=&quot;EOP SCXW105878675 BCX0&quot; data-ccp-props=&quot;{&amp;quot;201341983&amp;quot;:0,&amp;quot;335559740&amp;quot;:279}&quot; face=&quot;Aptos, Aptos_EmbeddedFont, Aptos_MSFontService, sans-serif&quot; style=&quot;-webkit-tap-highlight-color: transparent; -webkit-user-drag: none; font-size: 12pt; line-height: 20.925px; margin: 0px; padding: 0px; user-select: text;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;FirstRow LastCol SCXW105878675 BCX0&quot; data-celllook=&quot;0&quot; role=&quot;columnheader&quot; style=&quot;-webkit-tap-highlight-color: transparent; -webkit-user-drag: none; background-clip: padding-box; background-color: transparent; border: 1px solid; margin: 0px; overflow: visible; padding: 0px; position: relative; user-select: text; vertical-align: top; width: 156px;&quot;&gt;&lt;div class=&quot;TableCellContent SCXW105878675 BCX0&quot; style=&quot;-webkit-tap-highlight-color: transparent; -webkit-user-drag: none; margin: 0px; overflow: visible; padding: 0px 7px; user-select: text;&quot;&gt;&lt;div class=&quot;OutlineElement Ltr SCXW105878675 BCX0&quot; style=&quot;-webkit-tap-highlight-color: transparent; -webkit-user-drag: none; clear: both; cursor: text; direction: ltr; margin: 0px; overflow: visible; padding: 0px; position: relative; user-select: text;&quot;&gt;&lt;p class=&quot;Paragraph SCXW105878675 BCX0&quot; lang=&quot;EN-US&quot; paraeid=&quot;{6b393b23-1d3f-4f44-964f-f56d936f5ccb}{151}&quot; paraid=&quot;958251643&quot; style=&quot;-webkit-tap-highlight-color: transparent; -webkit-user-drag: none; background-color: transparent; color: windowtext; font-kerning: none; margin: 0px; overflow-wrap: break-word; padding: 0px; user-select: text; vertical-align: baseline; white-space-collapse: preserve;&quot; xml:lang=&quot;EN-US&quot;&gt;&lt;span class=&quot;TextRun SCXW105878675 BCX0&quot; data-contrast=&quot;auto&quot; face=&quot;Aptos, Aptos_EmbeddedFont, Aptos_MSFontService, sans-serif&quot; lang=&quot;EN-US&quot; style=&quot;-webkit-tap-highlight-color: transparent; -webkit-user-drag: none; font-size: 12pt; font-variant-ligatures: none; line-height: 20.925px; margin: 0px; padding: 0px; user-select: text;&quot; xml:lang=&quot;EN-US&quot;&gt;Timestamp&lt;/span&gt;&lt;span class=&quot;EOP SCXW105878675 BCX0&quot; data-ccp-props=&quot;{&amp;quot;201341983&amp;quot;:0,&amp;quot;335559740&amp;quot;:279}&quot; face=&quot;Aptos, Aptos_EmbeddedFont, Aptos_MSFontService, sans-serif&quot; style=&quot;-webkit-tap-highlight-color: transparent; -webkit-user-drag: none; font-size: 12pt; line-height: 20.925px; margin: 0px; padding: 0px; user-select: text;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr aria-rowindex=&quot;2&quot; class=&quot;TableRow SCXW105878675 BCX0&quot; role=&quot;row&quot; style=&quot;-webkit-tap-highlight-color: transparent; -webkit-user-drag: none; height: 20px; margin: 0px; overflow: visible; padding: 0px; user-select: text;&quot;&gt;&lt;td class=&quot;FirstCol LastRow SCXW105878675 BCX0&quot; data-celllook=&quot;0&quot; role=&quot;rowheader&quot; style=&quot;-webkit-tap-highlight-color: transparent; -webkit-user-drag: none; background-clip: padding-box; background-color: transparent; border: 1px solid; margin: 0px; overflow: visible; padding: 0px; position: relative; user-select: text; vertical-align: top; width: 0px;&quot;&gt;&lt;div class=&quot;TableCellContent SCXW105878675 BCX0&quot; style=&quot;-webkit-tap-highlight-color: transparent; -webkit-user-drag: none; margin: 0px; overflow: visible; padding: 0px 7px; user-select: text;&quot;&gt;&lt;div class=&quot;OutlineElement Ltr SCXW105878675 BCX0&quot; style=&quot;-webkit-tap-highlight-color: transparent; -webkit-user-drag: none; clear: both; cursor: text; direction: ltr; margin: 0px; overflow: visible; padding: 0px; position: relative; user-select: text;&quot;&gt;&lt;p class=&quot;Paragraph SCXW105878675 BCX0&quot; lang=&quot;EN-US&quot; paraeid=&quot;{05318274-1f6c-47bc-a6d7-2af78ed21636}{130}&quot; paraid=&quot;2138498222&quot; style=&quot;-webkit-tap-highlight-color: transparent; -webkit-user-drag: none; background-color: transparent; color: windowtext; font-kerning: none; margin: 0px; overflow-wrap: break-word; padding: 0px; user-select: text; vertical-align: baseline; white-space-collapse: preserve;&quot; xml:lang=&quot;EN-US&quot;&gt;&lt;span class=&quot;TextRun SCXW105878675 BCX0&quot; data-contrast=&quot;auto&quot; face=&quot;Aptos, Aptos_EmbeddedFont, Aptos_MSFontService, sans-serif&quot; lang=&quot;EN-US&quot; style=&quot;-webkit-tap-highlight-color: transparent; -webkit-user-drag: none; font-size: 12pt; font-variant-ligatures: none; line-height: 20.925px; margin: 0px; padding: 0px; user-select: text;&quot; xml:lang=&quot;EN-US&quot;&gt;&lt;span class=&quot;NormalTextRun SpellingErrorV2Themed SCXW105878675 BCX0&quot; style=&quot;-webkit-tap-highlight-color: transparent; -webkit-user-drag: none; background-image: var(--urlSpellingErrorV2,url(&amp;quot;data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI1IiBoZWlnaHQ9IjQiPjxnIGZpbGw9Im5vbmUiIGZpbGwtcnVsZT0iZXZlbm9kZCI+PHBhdGggc3Ryb2tlPSIjRUIwMDAwIiBkPSJNMCAzYzEuMjUgMCAxLjI1LTIgMi41LTJTMy43NSAzIDUgMyIvPjxwYXRoIGQ9Ik0wIDBoNXY0SDB6Ii8+PC9nPjwvc3ZnPg==&amp;quot;)); background-position: 0px 100%; background-repeat: repeat-x; border-bottom: 1px solid transparent; margin: 0px; padding: 0px; user-select: text;&quot;&gt;Comment_id&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;EOP SCXW105878675 BCX0&quot; data-ccp-props=&quot;{&amp;quot;201341983&amp;quot;:0,&amp;quot;335559740&amp;quot;:279}&quot; face=&quot;Aptos, Aptos_EmbeddedFont, Aptos_MSFontService, sans-serif&quot; style=&quot;-webkit-tap-highlight-color: transparent; -webkit-user-drag: none; font-size: 12pt; line-height: 20.925px; margin: 0px; padding: 0px; user-select: text;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;LastRow SCXW105878675 BCX0&quot; data-celllook=&quot;0&quot; style=&quot;-webkit-tap-highlight-color: transparent; -webkit-user-drag: none; background-clip: padding-box; background-color: transparent; border: 1px solid; margin: 0px; overflow: visible; padding: 0px; position: relative; user-select: text; vertical-align: top; width: 0px;&quot;&gt;&lt;div class=&quot;TableCellContent SCXW105878675 BCX0&quot; style=&quot;-webkit-tap-highlight-color: transparent; -webkit-user-drag: none; margin: 0px; overflow: visible; padding: 0px 7px; user-select: text;&quot;&gt;&lt;div class=&quot;OutlineElement Ltr SCXW105878675 BCX0&quot; style=&quot;-webkit-tap-highlight-color: transparent; -webkit-user-drag: none; clear: both; cursor: text; direction: ltr; margin: 0px; overflow: visible; padding: 0px; position: relative; user-select: text;&quot;&gt;&lt;p class=&quot;Paragraph SCXW105878675 BCX0&quot; lang=&quot;EN-US&quot; paraeid=&quot;{05318274-1f6c-47bc-a6d7-2af78ed21636}{136}&quot; paraid=&quot;800251400&quot; style=&quot;-webkit-tap-highlight-color: transparent; -webkit-user-drag: none; background-color: transparent; color: windowtext; font-kerning: none; margin: 0px; overflow-wrap: break-word; padding: 0px; user-select: text; vertical-align: baseline; white-space-collapse: preserve;&quot; xml:lang=&quot;EN-US&quot;&gt;&lt;span class=&quot;TextRun SCXW105878675 BCX0&quot; data-contrast=&quot;auto&quot; face=&quot;Aptos, Aptos_EmbeddedFont, Aptos_MSFontService, sans-serif&quot; lang=&quot;EN-US&quot; style=&quot;-webkit-tap-highlight-color: transparent; -webkit-user-drag: none; font-size: 12pt; font-variant-ligatures: none; line-height: 20.925px; margin: 0px; padding: 0px; user-select: text;&quot; xml:lang=&quot;EN-US&quot;&gt;&lt;span class=&quot;NormalTextRun SpellingErrorV2Themed SCXW105878675 BCX0&quot; style=&quot;-webkit-tap-highlight-color: transparent; -webkit-user-drag: none; background-image: var(--urlSpellingErrorV2,url(&amp;quot;data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI1IiBoZWlnaHQ9IjQiPjxnIGZpbGw9Im5vbmUiIGZpbGwtcnVsZT0iZXZlbm9kZCI+PHBhdGggc3Ryb2tlPSIjRUIwMDAwIiBkPSJNMCAzYzEuMjUgMCAxLjI1LTIgMi41LTJTMy43NSAzIDUgMyIvPjxwYXRoIGQ9Ik0wIDBoNXY0SDB6Ii8+PC9nPjwvc3ZnPg==&amp;quot;)); background-position: 0px 100%; background-repeat: repeat-x; border-bottom: 1px solid transparent; margin: 0px; padding: 0px; user-select: text;&quot;&gt;User_id&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;EOP SCXW105878675 BCX0&quot; data-ccp-props=&quot;{&amp;quot;201341983&amp;quot;:0,&amp;quot;335559740&amp;quot;:279}&quot; face=&quot;Aptos, Aptos_EmbeddedFont, Aptos_MSFontService, sans-serif&quot; style=&quot;-webkit-tap-highlight-color: transparent; -webkit-user-drag: none; font-size: 12pt; line-height: 20.925px; margin: 0px; padding: 0px; user-select: text;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;LastRow SCXW105878675 BCX0&quot; data-celllook=&quot;0&quot; style=&quot;-webkit-tap-highlight-color: transparent; -webkit-user-drag: none; background-clip: padding-box; background-color: transparent; border: 1px solid; margin: 0px; overflow: visible; padding: 0px; position: relative; user-select: text; vertical-align: top; width: 0px;&quot;&gt;&lt;div class=&quot;TableCellContent SCXW105878675 BCX0&quot; style=&quot;-webkit-tap-highlight-color: transparent; -webkit-user-drag: none; margin: 0px; overflow: visible; padding: 0px 7px; user-select: text;&quot;&gt;&lt;div class=&quot;OutlineElement Ltr SCXW105878675 BCX0&quot; style=&quot;-webkit-tap-highlight-color: transparent; -webkit-user-drag: none; clear: both; cursor: text; direction: ltr; margin: 0px; overflow: visible; padding: 0px; position: relative; user-select: text;&quot;&gt;&lt;p class=&quot;Paragraph SCXW105878675 BCX0&quot; lang=&quot;EN-US&quot; paraeid=&quot;{05318274-1f6c-47bc-a6d7-2af78ed21636}{142}&quot; paraid=&quot;122948466&quot; style=&quot;-webkit-tap-highlight-color: transparent; -webkit-user-drag: none; background-color: transparent; color: windowtext; font-kerning: none; margin: 0px; overflow-wrap: break-word; padding: 0px; user-select: text; vertical-align: baseline; white-space-collapse: preserve;&quot; xml:lang=&quot;EN-US&quot;&gt;&lt;span class=&quot;TextRun SCXW105878675 BCX0&quot; data-contrast=&quot;auto&quot; face=&quot;Aptos, Aptos_EmbeddedFont, Aptos_MSFontService, sans-serif&quot; lang=&quot;EN-US&quot; style=&quot;-webkit-tap-highlight-color: transparent; -webkit-user-drag: none; font-size: 12pt; font-variant-ligatures: none; line-height: 20.925px; margin: 0px; padding: 0px; user-select: text;&quot; xml:lang=&quot;EN-US&quot;&gt;Vote (+1 / -1)&lt;/span&gt;&lt;span class=&quot;EOP SCXW105878675 BCX0&quot; data-ccp-props=&quot;{&amp;quot;201341983&amp;quot;:0,&amp;quot;335559740&amp;quot;:279}&quot; face=&quot;Aptos, Aptos_EmbeddedFont, Aptos_MSFontService, sans-serif&quot; style=&quot;-webkit-tap-highlight-color: transparent; -webkit-user-drag: none; font-size: 12pt; line-height: 20.925px; margin: 0px; padding: 0px; user-select: text;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;LastCol LastRow SCXW105878675 BCX0&quot; data-celllook=&quot;0&quot; style=&quot;-webkit-tap-highlight-color: transparent; -webkit-user-drag: none; background-clip: padding-box; background-color: transparent; border: 1px solid; margin: 0px; overflow: visible; padding: 0px; position: relative; user-select: text; vertical-align: top; width: 0px;&quot;&gt;&lt;div class=&quot;TableCellContent SCXW105878675 BCX0&quot; style=&quot;-webkit-tap-highlight-color: transparent; -webkit-user-drag: none; margin: 0px; overflow: visible; padding: 0px 7px; user-select: text;&quot;&gt;&lt;div class=&quot;OutlineElement Ltr SCXW105878675 BCX0&quot; style=&quot;-webkit-tap-highlight-color: transparent; -webkit-user-drag: none; clear: both; cursor: text; direction: ltr; margin: 0px; overflow: visible; padding: 0px; position: relative; user-select: text;&quot;&gt;&lt;p class=&quot;Paragraph SCXW105878675 BCX0&quot; lang=&quot;EN-US&quot; paraeid=&quot;{05318274-1f6c-47bc-a6d7-2af78ed21636}{148}&quot; paraid=&quot;1469836807&quot; style=&quot;-webkit-tap-highlight-color: transparent; -webkit-user-drag: none; background-color: transparent; color: windowtext; font-kerning: none; margin: 0px; overflow-wrap: break-word; padding: 0px; user-select: text; vertical-align: baseline; white-space-collapse: preserve;&quot; xml:lang=&quot;EN-US&quot;&gt;&lt;span class=&quot;TextRun SCXW105878675 BCX0&quot; data-contrast=&quot;auto&quot; face=&quot;Aptos, Aptos_EmbeddedFont, Aptos_MSFontService, sans-serif&quot; lang=&quot;EN-US&quot; style=&quot;-webkit-tap-highlight-color: transparent; -webkit-user-drag: none; font-size: 12pt; font-variant-ligatures: none; line-height: 20.925px; margin: 0px; padding: 0px; user-select: text;&quot; xml:lang=&quot;EN-US&quot;&gt;Timestamp&lt;/span&gt;&lt;span class=&quot;EOP SCXW105878675 BCX0&quot; data-ccp-props=&quot;{&amp;quot;201341983&amp;quot;:0,&amp;quot;335559740&amp;quot;:279}&quot; face=&quot;Aptos, Aptos_EmbeddedFont, Aptos_MSFontService, sans-serif&quot; style=&quot;-webkit-tap-highlight-color: transparent; -webkit-user-drag: none; font-size: 12pt; line-height: 20.925px; margin: 0px; padding: 0px; user-select: text;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;OutlineElement Ltr SCXW105878675 BCX0&quot; style=&quot;-webkit-tap-highlight-color: transparent; -webkit-user-drag: none; background-color: white; clear: both; cursor: text; direction: ltr; font-family: &amp;quot;Segoe UI&amp;quot;, &amp;quot;Segoe UI Web&amp;quot;, Arial, Verdana, sans-serif; font-size: 12px; margin: 0px; overflow: visible; padding: 0px; position: relative; user-select: text;&quot;&gt;&lt;p class=&quot;Paragraph SCXW105878675 BCX0&quot; lang=&quot;EN-US&quot; paraeid=&quot;{6b393b23-1d3f-4f44-964f-f56d936f5ccb}{127}&quot; paraid=&quot;1354421949&quot; style=&quot;-webkit-tap-highlight-color: transparent; -webkit-user-drag: none; background-color: transparent; color: windowtext; font-kerning: none; margin: 0px 0px 10.6667px; overflow-wrap: break-word; padding: 0px; user-select: text; vertical-align: baseline; white-space-collapse: preserve;&quot; xml:lang=&quot;EN-US&quot;&gt;&lt;span class=&quot;TextRun SCXW105878675 BCX0&quot; data-contrast=&quot;auto&quot; face=&quot;Aptos, Aptos_EmbeddedFont, Aptos_MSFontService, sans-serif&quot; lang=&quot;EN-US&quot; style=&quot;-webkit-tap-highlight-color: transparent; -webkit-user-drag: none; font-size: 12pt; font-variant-ligatures: none; line-height: 20.925px; margin: 0px; padding: 0px; user-select: text;&quot; xml:lang=&quot;EN-US&quot;&gt;&lt;span class=&quot;NormalTextRun SCXW105878675 BCX0&quot; style=&quot;-webkit-tap-highlight-color: transparent; -webkit-user-drag: none; margin: 0px; padding: 0px; user-select: text;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;EOP SCXW105878675 BCX0&quot; data-ccp-props=&quot;{&amp;quot;201341983&amp;quot;:0,&amp;quot;335559739&amp;quot;:160,&amp;quot;335559740&amp;quot;:279}&quot; face=&quot;Aptos, Aptos_EmbeddedFont, Aptos_MSFontService, sans-serif&quot; style=&quot;-webkit-tap-highlight-color: transparent; -webkit-user-drag: none; font-size: 12pt; line-height: 20.925px; margin: 0px; padding: 0px; user-select: text;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;With this we can at least achieve the functinalties including &lt;i&gt;&lt;b&gt;FR 7&lt;/b&gt;&lt;/i&gt; too. We will see the performance part when we will address non functional requirements.&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhnVdJbKhl28Dem02-mchwEq3Avq5ChuNgoRgvM6zaBXf3hDv_5xaFCqjQBAO1YTR57TvNUcykUxyrjbP0FZJGaukqOp8SA9JeSCQ8D9LWF54uI-Bem3Tjn69SCZeRv1t7kOzkBO4KRF0kt_qJzvVvYqpmVE763tPJv2ZwuLsoK4HJyPBeidGtHmcFteFo/s711/HLD-SF.drawio%20(1).png&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;422&quot; data-original-width=&quot;711&quot; height=&quot;265&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhnVdJbKhl28Dem02-mchwEq3Avq5ChuNgoRgvM6zaBXf3hDv_5xaFCqjQBAO1YTR57TvNUcykUxyrjbP0FZJGaukqOp8SA9JeSCQ8D9LWF54uI-Bem3Tjn69SCZeRv1t7kOzkBO4KRF0kt_qJzvVvYqpmVE763tPJv2ZwuLsoK4HJyPBeidGtHmcFteFo/w445-h265/HLD-SF.drawio%20(1).png&quot; width=&quot;445&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style=&quot;text-align: left;&quot;&gt;&lt;b&gt;8: Home page contains the top popular posts:&lt;/b&gt; This is the most trickest functional requirement of this design. If you see the voting data is with Votes service and post content is with Posts service. Getting popular posts when the api call has been made could be very expensive. As this list is there in the home page, we can&#39;t risk of having delays in the page load.&lt;/div&gt;&lt;div style=&quot;text-align: left;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style=&quot;text-align: left;&quot;&gt;To solve this issue we are going to use &lt;a href=&quot;https://en.wikipedia.org/wiki/Command_Query_Responsibility_Segregation&quot; target=&quot;_blank&quot;&gt;CQRS&lt;/a&gt; pattern. We are now going to introduce a Ranking microservice which will pull voting data from Votes service and post content from Post service. It then sort this data based on ranking and save this data into its own &lt;i&gt;nosql&lt;/i&gt; DB. Now whenever the call for popular posts comes, it will be redirected to ranking service.&lt;/div&gt;&lt;div style=&quot;text-align: left;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style=&quot;text-align: left;&quot;&gt;There are some consideration here:&lt;/div&gt;&lt;div style=&quot;text-align: left;&quot;&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;We know that the sliding window here is 24 hours so rankng service can query only the posts which are kind of active in this window.&lt;/li&gt;&lt;li&gt;Given we don&#39;t have to show always the most recent data, we can use batch processing in the ranking service as this operation is heavy.&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;So here is what ranking service will do at a regular interval:&lt;/div&gt;&lt;div&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;Get the active votes from voting service for last 24 hours.&lt;/li&gt;&lt;li&gt;Group the votes (upvotes - downvotes) by post_id.&amp;nbsp;&lt;/li&gt;&lt;li&gt;Sort the post_ids in descending order according to votes.&lt;/li&gt;&lt;li&gt;Get the post content from POST service.&lt;/li&gt;&lt;li&gt;Save it in the DB.&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/a/AVvXsEi59LClhwdcKwEsq_8CQoukM-okNiYBr35nQ5wjq6J_0rwlXGhpKw7UXIPsVv5zx3kss4b7jGSS8yB50mJz-Bg36Plqr28lne-yJWiEVuIzvTl5H2OgAY1k1DWV5oCwj0uwua2WmOfHsCtEdgG8YMb5Smi3lcd_CoQXMX8KJKWwuw2FqBIGQ2VnWP_Sbj4&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img alt=&quot;&quot; data-original-height=&quot;422&quot; data-original-width=&quot;711&quot; height=&quot;254&quot; src=&quot;https://blogger.googleusercontent.com/img/a/AVvXsEi59LClhwdcKwEsq_8CQoukM-okNiYBr35nQ5wjq6J_0rwlXGhpKw7UXIPsVv5zx3kss4b7jGSS8yB50mJz-Bg36Plqr28lne-yJWiEVuIzvTl5H2OgAY1k1DWV5oCwj0uwua2WmOfHsCtEdgG8YMb5Smi3lcd_CoQXMX8KJKWwuw2FqBIGQ2VnWP_Sbj4=w428-h254&quot; width=&quot;428&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;So above is the final design of our product which is satisfying all the functional requirements. Now let&#39;s move to non functional requirements.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;Step 3: Mapping non functional requirements to architectural diagram:&lt;/b&gt;&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;1. Scalablity:&lt;/b&gt; Given we are talkng about millions of active users, a single instance of service won&#39;t work. Obviously we need to have multiple instances of every services and a load balancer to balance the traffic.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Another scalability issue here is the large data of posts and comments so we are going to shard the Post and comments data.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;For &lt;i&gt;posts we can use hash based sharding with hashing on post_id&lt;/i&gt;. I know this can be a bottlenect if we have to show all the posts from a particular user as posts might be distributed among multiple shards but this is not even our functional requirement. If it is added then we can still serve it and with little tweaks we can serve it effficiently.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;For &lt;i&gt;comments we&lt;/i&gt; &lt;i&gt;can&#39;t shard based on comment_id&lt;/i&gt; as in general the comments will be fetched according to post_id and if you see if we go with comment_id, we might end up retrieving comments from different shards which is a big performance issue.&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;So what we can do is we can shard the comments based on post_id using hash based sharding. This will work well but it will create problem when a post become popular it starts having too many comments then what will happen that a particular shard will become too big and can become the scalability issue and also performance bottleneck.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;To handle such issue we can use a &lt;i&gt;compound key (post_id, comment_id) &lt;/i&gt;and we can apply &lt;i&gt;range based sharding&lt;/i&gt;. If we use it, mostly we will get data from one shard or at most two shards.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;In this way we can handle the scalability.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/a/AVvXsEgVCXwATYNh6cHTAwlXtDlpHhLAyOj8h8zw5_RhX9HfG8etqIS0zgCgurWBkSG59GXrsbXoJ1CHx0lUQ-DtkRtRm7EqFEIiwWXYFQlv6k7LmlmhX6hnItNfgN3Tpx7hN5XNdDxgz5nI8lDunZwls-AZohVaPg8K5reR4CrKa_iyBlOXvwM6X9oEmleInX4&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img alt=&quot;&quot; data-original-height=&quot;491&quot; data-original-width=&quot;831&quot; height=&quot;273&quot; src=&quot;https://blogger.googleusercontent.com/img/a/AVvXsEgVCXwATYNh6cHTAwlXtDlpHhLAyOj8h8zw5_RhX9HfG8etqIS0zgCgurWBkSG59GXrsbXoJ1CHx0lUQ-DtkRtRm7EqFEIiwWXYFQlv6k7LmlmhX6hnItNfgN3Tpx7hN5XNdDxgz5nI8lDunZwls-AZohVaPg8K5reR4CrKa_iyBlOXvwM6X9oEmleInX4=w464-h273&quot; width=&quot;464&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;b&gt;2. Performance:&lt;/b&gt; There are multiple ways to make this system performant.&lt;/div&gt;&lt;div&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;Image load time can be greater while fetching from the blob store. To avoid that we can use &lt;i&gt;CDNs where we can store images&lt;/i&gt; of popular posts. We can also use &lt;i&gt;CDNs to serve the static html&lt;/i&gt; pages too.&lt;/li&gt;&lt;li&gt;We can use &lt;i&gt;cache to store the most popular posts and it&#39;s content&lt;/i&gt; in order to avoid traffic on GET requests of posts which are ultimately be directed to Posts service or Ranking service. Even the cache is not up to date, it is fine as we have chosen availability over consistency so eventual consistency is just fine.&lt;/li&gt;&lt;li&gt;&lt;i&gt;Index on post_id for post collection and compound index(post_id, comment_id) on comment collection&lt;/i&gt; really can help on speeding up the Get requests. We can do the similar indexing on other DBs too.&lt;/li&gt;&lt;li&gt;Now another problem is, for a post/comment to load, we also need to show the upvotes and downvotes of the post or comment but votes data are there in Votes service DB so to load the post we need to call two microservice. We can take following steps to make it faster to fetch all post data or comment data including votes from one microservice only:&lt;/li&gt;&lt;ul&gt;&lt;li&gt;Two fields will be added to post and comments collection schema:&lt;/li&gt;&lt;ul&gt;&lt;li&gt;upvotes_count&lt;/li&gt;&lt;li&gt;downvotes_count&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;&lt;i&gt;Queue the voting event from Votes service to Posts service&lt;/i&gt; so post service worker will fetch the events and can bulk update the DB with upvotes and downvotes count.&lt;/li&gt;&lt;/ul&gt;&lt;/ul&gt;I think we are good with the performance point of view and now our system looks like following:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/a/AVvXsEg0ZI61yU7y0sq0nme1xvv8fm6lcZU7ZzYcGzegetvOP-FZEwzttJ2HDsqtSQkXd2y1Y-jWvzVNl5rJX_2yAFjkc0OyuE0S8gDcX65yZI2JwYRa8cQePWGCF92-hRGtkBWhcmEGYjOuEKLwIF2bQ6r9HFC9TYsWqy5EE5ivCqJQJ_lIBVAW8UG8BQkO2A8&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img alt=&quot;&quot; data-original-height=&quot;518&quot; data-original-width=&quot;946&quot; height=&quot;285&quot; src=&quot;https://blogger.googleusercontent.com/img/a/AVvXsEg0ZI61yU7y0sq0nme1xvv8fm6lcZU7ZzYcGzegetvOP-FZEwzttJ2HDsqtSQkXd2y1Y-jWvzVNl5rJX_2yAFjkc0OyuE0S8gDcX65yZI2JwYRa8cQePWGCF92-hRGtkBWhcmEGYjOuEKLwIF2bQ6r9HFC9TYsWqy5EE5ivCqJQJ_lIBVAW8UG8BQkO2A8=w521-h285&quot; width=&quot;521&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;&lt;b&gt;3. Availability:&lt;/b&gt; To achieve the availability we can replicate the databases and our services. We can also have our system running and replicated in different regions. This will also boost the performance.&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;&lt;b&gt;4. Durability:&lt;/b&gt; We are already achiving the durability when we replicated the data accross regions. We can still periodically backed up our data to cheaper storage like S3 in order to have backups. This can also help us to cleanup old data from DBs to boost the performance if required.&lt;/div&gt;&lt;br /&gt;Now that we have handled our every functional and non function requirements. Here is our final design:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjUwskC5SvaKztczE-NZpibSPjO31cbo2F8klP-nL6be3fX7aQlRuuDqMJ5TD2rAYCTv5Iklv2ZlWzq7Z66Dyiw1XRMaXPpO_9dl-ssdCeJ-sXULYyRdiVnBjjVXJXVodpI8m1bIFLeHnRlf_FR9i-Z2QXqKMv8ZrMeNhVZHciiRpmqvRVvKE81VMcbGbs/s1161/HLD-SF.drawio%20(2).png&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;518&quot; data-original-width=&quot;1161&quot; height=&quot;285&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjUwskC5SvaKztczE-NZpibSPjO31cbo2F8klP-nL6be3fX7aQlRuuDqMJ5TD2rAYCTv5Iklv2ZlWzq7Z66Dyiw1XRMaXPpO_9dl-ssdCeJ-sXULYyRdiVnBjjVXJXVodpI8m1bIFLeHnRlf_FR9i-Z2QXqKMv8ZrMeNhVZHciiRpmqvRVvKE81VMcbGbs/w638-h285/HLD-SF.drawio%20(2).png&quot; width=&quot;638&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;That&#39;s all for this system design problem!&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;</content><link rel='replies' type='application/atom+xml' href='http://algods-cracker.blogspot.com/feeds/1985433497369941513/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://algods-cracker.blogspot.com/2024/08/design-stack-overflow.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7496974970329409400/posts/default/1985433497369941513'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7496974970329409400/posts/default/1985433497369941513'/><link rel='alternate' type='text/html' href='http://algods-cracker.blogspot.com/2024/08/design-stack-overflow.html' title='Design Stack overflow'/><author><name>Nishant Saxena</name><uri>http://www.blogger.com/profile/17860524009847591950</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjOdjS62BAEI1iMG_zd6lew4qyFGpfJhWHp0AJWQhiJvxQpSGg0AFZ5euJG7tK0D-EGQFno32hF-i1x4E2A49re_8-b9r0QHwXQ-9X_EvlAcekIjUYMaA1v6dWzDqzkBg/s220/2d230a1.jpg'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/a/AVvXsEjvKFa3iWZ5yB3raX948wnITi4jr675lwQ2bmr9lef1sQNmQ46_JMSiyq0IYlfPkVel8jx50G3sDs9OO8uSH51mAGH9tF5BsGYsTAdBjf6zsrAC_j4eDTD-ZChxvh4jU8pAVTUafuMQ0Jkj1lPBR93LC4ynHR_pWAl3j6ekmPONRIJBrK1pFl5ZuJcGe9Q=s72-w193-h313-c" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7496974970329409400.post-946390900734950754</id><published>2024-08-07T22:12:00.003+05:30</published><updated>2024-08-07T22:12:27.472+05:30</updated><category scheme="http://www.blogger.com/atom/ns#" term="LeetCode"/><title type='text'>[LeetCode] Minimum Number of Pushes to Type Word II</title><content type='html'>&lt;b&gt;Problem:&lt;/b&gt; You are given a string word containing lowercase English letters.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Telephone keypads have keys mapped with distinct collections of lowercase English letters, which can be used to form words by pushing them. For example, the key 2 is mapped with [&quot;a&quot;,&quot;b&quot;,&quot;c&quot;], we need to push the key one time to type &quot;a&quot;, two times to type &quot;b&quot;, and three times to type &quot;c&quot; .&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;It is allowed to remap the keys numbered 2 to 9 to distinct collections of letters. The keys can be remapped to any amount of letters, but each letter must be mapped to exactly one key. You need to find the minimum number of times the keys will be pushed to type the string word.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Return the minimum number of pushes needed to type word after remapping the keys.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;An example mapping of letters to keys on a telephone keypad is given below. Note that 1, *, #, and 0 do not map to any letters.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;img alt=&quot;&quot; src=&quot;https://assets.leetcode.com/uploads/2023/12/26/keypaddesc.png&quot; style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-translate-x: 0; --tw-translate-y: 0; background-color: #f0f0f0; border-color: hsl(var(--sd-border)); border-image: initial; border-style: none; border-width: 0px; box-sizing: border-box; color: #262626; display: block; font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe UI&amp;quot;, Helvetica, Arial, sans-serif, &amp;quot;Apple Color Emoji&amp;quot;, &amp;quot;Segoe UI Emoji&amp;quot;; font-size: 14px; height: 313px; max-width: 100%; overflow-wrap: break-word; vertical-align: middle; width: 329px;&quot; /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Example:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;img alt=&quot;&quot; src=&quot;https://assets.leetcode.com/uploads/2023/12/26/keypadv1e1.png&quot; style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-translate-x: 0; --tw-translate-y: 0; background-color: #f0f0f0; border-color: hsl(var(--sd-border)); border-image: initial; border-style: none; border-width: 0px; box-sizing: border-box; color: #262626; display: block; font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe UI&amp;quot;, Helvetica, Arial, sans-serif, &amp;quot;Apple Color Emoji&amp;quot;, &amp;quot;Segoe UI Emoji&amp;quot;; font-size: 14px; height: 313px; max-width: 100%; overflow-wrap: break-word; vertical-align: middle; width: 329px;&quot; /&gt;&lt;pre style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-translate-x: 0; --tw-translate-y: 0; background-color: #f0f0f0; border-color: var(--border-tertiary); border-image: initial; border-style: solid; border-width: 0px 0px 0px 2px; box-sizing: border-box; color: var(--text-secondary); font-family: Menlo, sans-serif; font-size: 14px; line-height: 1.25rem; margin-bottom: 1rem; margin-top: 1rem; overflow-wrap: break-word; overflow: visible; padding-left: 1rem; text-wrap: wrap;&quot;&gt;&lt;span style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-text-opacity: 1; --tw-translate-x: 0; --tw-translate-y: 0; border-color: hsl(var(--sd-border)); border-image: initial; border-style: solid; border-width: 0px; box-sizing: border-box; color: rgb(38 38 38/var(--tw-text-opacity)); font-weight: 700; overflow-wrap: break-word;&quot;&gt;Input:&lt;/span&gt; word = &quot;abcde&quot;
&lt;span style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-text-opacity: 1; --tw-translate-x: 0; --tw-translate-y: 0; border-color: hsl(var(--sd-border)); border-image: initial; border-style: solid; border-width: 0px; box-sizing: border-box; color: rgb(38 38 38/var(--tw-text-opacity)); font-weight: 700; overflow-wrap: break-word;&quot;&gt;Output:&lt;/span&gt; 5
&lt;span style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-text-opacity: 1; --tw-translate-x: 0; --tw-translate-y: 0; border-color: hsl(var(--sd-border)); border-image: initial; border-style: solid; border-width: 0px; box-sizing: border-box; color: rgb(38 38 38/var(--tw-text-opacity)); font-weight: 700; overflow-wrap: break-word;&quot;&gt;Explanation:&lt;/span&gt; The remapped keypad given in the image provides the minimum cost.
&quot;a&quot; -&amp;gt; one push on key 2
&quot;b&quot; -&amp;gt; one push on key 3
&quot;c&quot; -&amp;gt; one push on key 4
&quot;d&quot; -&amp;gt; one push on key 5
&quot;e&quot; -&amp;gt; one push on key 6
Total cost is 1 + 1 + 1 + 1 + 1 = 5.
It can be shown that no other mapping can provide a lower cost.&lt;/pre&gt;&lt;/div&gt;&lt;div&gt;&lt;img alt=&quot;&quot; src=&quot;https://assets.leetcode.com/uploads/2023/12/26/keypadv2e2.png&quot; style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-translate-x: 0; --tw-translate-y: 0; background-color: #f0f0f0; border-color: hsl(var(--sd-border)); border-image: initial; border-style: none; border-width: 0px; box-sizing: border-box; color: #262626; display: block; font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe UI&amp;quot;, Helvetica, Arial, sans-serif, &amp;quot;Apple Color Emoji&amp;quot;, &amp;quot;Segoe UI Emoji&amp;quot;; font-size: 14px; height: 313px; max-width: 100%; overflow-wrap: break-word; vertical-align: middle; width: 329px;&quot; /&gt;&lt;pre style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-translate-x: 0; --tw-translate-y: 0; background-color: #f0f0f0; border-color: var(--border-tertiary); border-image: initial; border-style: solid; border-width: 0px 0px 0px 2px; box-sizing: border-box; color: var(--text-secondary); font-family: Menlo, sans-serif; font-size: 14px; line-height: 1.25rem; margin-bottom: 1rem; margin-top: 1rem; overflow-wrap: break-word; overflow: visible; padding-left: 1rem; text-wrap: wrap;&quot;&gt;&lt;span style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-text-opacity: 1; --tw-translate-x: 0; --tw-translate-y: 0; border-color: hsl(var(--sd-border)); border-image: initial; border-style: solid; border-width: 0px; box-sizing: border-box; color: rgb(38 38 38/var(--tw-text-opacity)); font-weight: 700; overflow-wrap: break-word;&quot;&gt;Input:&lt;/span&gt; word = &quot;xyzxyzxyzxyz&quot;
&lt;span style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-text-opacity: 1; --tw-translate-x: 0; --tw-translate-y: 0; border-color: hsl(var(--sd-border)); border-image: initial; border-style: solid; border-width: 0px; box-sizing: border-box; color: rgb(38 38 38/var(--tw-text-opacity)); font-weight: 700; overflow-wrap: break-word;&quot;&gt;Output:&lt;/span&gt; 12
&lt;span style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-text-opacity: 1; --tw-translate-x: 0; --tw-translate-y: 0; border-color: hsl(var(--sd-border)); border-image: initial; border-style: solid; border-width: 0px; box-sizing: border-box; color: rgb(38 38 38/var(--tw-text-opacity)); font-weight: 700; overflow-wrap: break-word;&quot;&gt;Explanation:&lt;/span&gt; The remapped keypad given in the image provides the minimum cost.
&quot;x&quot; -&amp;gt; one push on key 2
&quot;y&quot; -&amp;gt; one push on key 3
&quot;z&quot; -&amp;gt; one push on key 4
Total cost is 1 * 4 + 1 * 4 + 1 * 4 = 12
It can be shown that no other mapping can provide a lower cost.
Note that the key 9 is not mapped to any letter: it is not necessary to map letters to every key, but to map all the letters.&lt;/pre&gt;&lt;/div&gt;&lt;div&gt;&lt;img alt=&quot;&quot; src=&quot;https://assets.leetcode.com/uploads/2023/12/27/keypadv2.png&quot; style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-translate-x: 0; --tw-translate-y: 0; background-color: #f0f0f0; border-color: hsl(var(--sd-border)); border-image: initial; border-style: none; border-width: 0px; box-sizing: border-box; color: #262626; display: block; font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe UI&amp;quot;, Helvetica, Arial, sans-serif, &amp;quot;Apple Color Emoji&amp;quot;, &amp;quot;Segoe UI Emoji&amp;quot;; font-size: 14px; height: 313px; max-width: 100%; overflow-wrap: break-word; vertical-align: middle; width: 329px;&quot; /&gt;&lt;pre style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-translate-x: 0; --tw-translate-y: 0; background-color: #f0f0f0; border-color: var(--border-tertiary); border-image: initial; border-style: solid; border-width: 0px 0px 0px 2px; box-sizing: border-box; color: var(--text-secondary); font-family: Menlo, sans-serif; font-size: 14px; line-height: 1.25rem; margin-bottom: 1rem; margin-top: 1rem; overflow-wrap: break-word; overflow: visible; padding-left: 1rem; text-wrap: wrap;&quot;&gt;&lt;span style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-text-opacity: 1; --tw-translate-x: 0; --tw-translate-y: 0; border-color: hsl(var(--sd-border)); border-image: initial; border-style: solid; border-width: 0px; box-sizing: border-box; color: rgb(38 38 38/var(--tw-text-opacity)); font-weight: 700; overflow-wrap: break-word;&quot;&gt;Input:&lt;/span&gt; word = &quot;aabbccddeeffgghhiiiiii&quot;
&lt;span style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-text-opacity: 1; --tw-translate-x: 0; --tw-translate-y: 0; border-color: hsl(var(--sd-border)); border-image: initial; border-style: solid; border-width: 0px; box-sizing: border-box; color: rgb(38 38 38/var(--tw-text-opacity)); font-weight: 700; overflow-wrap: break-word;&quot;&gt;Output:&lt;/span&gt; 24
&lt;span style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-text-opacity: 1; --tw-translate-x: 0; --tw-translate-y: 0; border-color: hsl(var(--sd-border)); border-image: initial; border-style: solid; border-width: 0px; box-sizing: border-box; color: rgb(38 38 38/var(--tw-text-opacity)); font-weight: 700; overflow-wrap: break-word;&quot;&gt;Explanation:&lt;/span&gt; The remapped keypad given in the image provides the minimum cost.
&quot;a&quot; -&amp;gt; one push on key 2
&quot;b&quot; -&amp;gt; one push on key 3
&quot;c&quot; -&amp;gt; one push on key 4
&quot;d&quot; -&amp;gt; one push on key 5
&quot;e&quot; -&amp;gt; one push on key 6
&quot;f&quot; -&amp;gt; one push on key 7
&quot;g&quot; -&amp;gt; one push on key 8
&quot;h&quot; -&amp;gt; two pushes on key 9
&quot;i&quot; -&amp;gt; one push on key 9
Total cost is 1 * 2 + 1 * 2 + 1 * 2 + 1 * 2 + 1 * 2 + 1 * 2 + 1 * 2 + 2 * 2 + 6 * 1 = 24.
It can be shown that no other mapping can provide a lower cost.&lt;/pre&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Constraints:&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;1 &amp;lt;= word.length &amp;lt;= 10^5&lt;/li&gt;&lt;li&gt;word consists of lowercase English letters&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;Approach:&lt;/b&gt;&amp;nbsp; If you see, we can only use 8 keys (2, 3, 4, ..., 9) in total that means we can type only 8 characters with one push each, then 8 characters with two pushes each and so on so the optimal way to map charaters to keys evenly.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Given the above facts we can see that it&#39;s clearly a &lt;i&gt;greedy&lt;/i&gt; problem where we need to start with most frequent characters in sorted and try to give the minimum numnber of pushes to those characters so that we can reduce the number of pushes as much as possible.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;What we can do is, we can sort the given word as per the frequency of characters in descending order. Now we can use following simple steps:&lt;/div&gt;&lt;div&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;charsAtCurrLevel = 1&lt;/li&gt;&lt;li&gt;currPushes = 1&lt;/li&gt;&lt;li&gt;totalPushes = 0&lt;/li&gt;&lt;li&gt;i = 0&lt;/li&gt;&lt;li&gt;WHILE i &amp;lt; n:&lt;/li&gt;&lt;ul&gt;&lt;li&gt;totalPushes = totalPushes + Count of word[i] * currPushes&lt;/li&gt;&lt;li&gt;charsAtCurrLevel = charsAtCurrLevel + 1&lt;/li&gt;&lt;li&gt;IF charsAtCurrLevel &amp;gt; 8&lt;/li&gt;&lt;ul&gt;&lt;li&gt;currPushes&amp;nbsp;= currPushes&amp;nbsp;+ 1&lt;/li&gt;&lt;li&gt;charsAtCurrLevel = 1&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;i = i + Count&amp;nbsp;of word[i]&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;RETURN totalPushes&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div&gt;This will solve the problem in nlogn time which is good but let&#39;s see how we can improve it. As such we can&#39;t do anything but what we can do is use of constraint 2 where the string characters are only small lowercase english characters. Let&#39;s see how;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Instead of using map for collecting frequency, we can use integer array of size 26. Once we collect all the frequency, we can now sort this frequency array in descending order. Now we know every index in this frequency array is representing a character in word string so we can use following steps to calculate total pushes:&lt;/div&gt;&lt;div&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;totalPushes = 0&lt;/li&gt;&lt;li&gt;currPushes = 1&lt;/li&gt;&lt;li&gt;FOR i = 0 To 26&lt;/li&gt;&lt;ul&gt;&lt;li&gt;IF freqMap[i] == 0&lt;/li&gt;&lt;ul&gt;&lt;li&gt;BREAK&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;IF i % 8 == 0&lt;/li&gt;&lt;ul&gt;&lt;li&gt;currPushes = currPushes + 1&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;totalPushes = totalPushes + freqMap[i] * currPushes&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;RETURN totalPushes&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div&gt;&amp;nbsp;That&#39;s all!&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;Implementation in C#:&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;Approach 1: Sort word based on frequency of characters:&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div style=&quot;background-color: white; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 13px; line-height: 18px; white-space: pre;&quot;&gt;&lt;div&gt;&lt;span style=&quot;color: blue;&quot;&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;/span&gt;public&lt;/span&gt; &lt;span style=&quot;color: blue;&quot;&gt;int&lt;/span&gt; &lt;span style=&quot;color: #795e26;&quot;&gt;MinimumPushes1&lt;/span&gt;(&lt;span style=&quot;color: blue;&quot;&gt;string&lt;/span&gt; &lt;span style=&quot;color: #001080;&quot;&gt;word&lt;/span&gt;)&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; {&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: blue;&quot;&gt;int&lt;/span&gt; &lt;span style=&quot;color: #001080;&quot;&gt;length&lt;/span&gt; = &lt;span style=&quot;color: #001080;&quot;&gt;word&lt;/span&gt;?.&lt;span style=&quot;color: #001080;&quot;&gt;Length&lt;/span&gt; ?? &lt;span style=&quot;color: #098658;&quot;&gt;0&lt;/span&gt;;&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #af00db;&quot;&gt;if&lt;/span&gt; (&lt;span style=&quot;color: #001080;&quot;&gt;length&lt;/span&gt; &amp;lt;= &lt;span style=&quot;color: #098658;&quot;&gt;8&lt;/span&gt;)&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; {&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #af00db;&quot;&gt;return&lt;/span&gt; &lt;span style=&quot;color: #001080;&quot;&gt;length&lt;/span&gt;;&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: blue;&quot;&gt;var&lt;/span&gt; &lt;span style=&quot;color: #001080;&quot;&gt;wordArr&lt;/span&gt; = &lt;span style=&quot;color: #001080;&quot;&gt;word&lt;/span&gt;.&lt;span style=&quot;color: #795e26;&quot;&gt;ToCharArray&lt;/span&gt;();&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: blue;&quot;&gt;int&lt;/span&gt;[] &lt;span style=&quot;color: #001080;&quot;&gt;map&lt;/span&gt; = &lt;span style=&quot;color: blue;&quot;&gt;new&lt;/span&gt; &lt;span style=&quot;color: blue;&quot;&gt;int&lt;/span&gt;[&lt;span style=&quot;color: #098658;&quot;&gt;26&lt;/span&gt;];&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #af00db;&quot;&gt;foreach&lt;/span&gt; (&lt;span style=&quot;color: blue;&quot;&gt;char&lt;/span&gt; &lt;span style=&quot;color: #001080;&quot;&gt;ch&lt;/span&gt; &lt;span style=&quot;color: #af00db;&quot;&gt;in&lt;/span&gt; &lt;span style=&quot;color: #001080;&quot;&gt;wordArr&lt;/span&gt;)&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; {&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ++&lt;span style=&quot;color: #001080;&quot;&gt;map&lt;/span&gt;[&lt;span style=&quot;color: #001080;&quot;&gt;ch&lt;/span&gt; - &lt;span style=&quot;color: #a31515;&quot;&gt;&#39;a&#39;&lt;/span&gt;];&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #001080;&quot;&gt;Array&lt;/span&gt;.&lt;span style=&quot;color: #795e26;&quot;&gt;Sort&lt;/span&gt;(&lt;span style=&quot;color: #001080;&quot;&gt;wordArr&lt;/span&gt;, (&lt;span style=&quot;color: #001080;&quot;&gt;c1&lt;/span&gt;, &lt;span style=&quot;color: #001080;&quot;&gt;c2&lt;/span&gt;) =&amp;gt; {&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #af00db;&quot;&gt;if&lt;/span&gt; (&lt;span style=&quot;color: #001080;&quot;&gt;map&lt;/span&gt;[&lt;span style=&quot;color: #001080;&quot;&gt;c2&lt;/span&gt; - &lt;span style=&quot;color: #a31515;&quot;&gt;&#39;a&#39;&lt;/span&gt;] == &lt;span style=&quot;color: #001080;&quot;&gt;map&lt;/span&gt;[&lt;span style=&quot;color: #001080;&quot;&gt;c1&lt;/span&gt; - &lt;span style=&quot;color: #a31515;&quot;&gt;&#39;a&#39;&lt;/span&gt;])&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; {&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #af00db;&quot;&gt;return&lt;/span&gt; &lt;span style=&quot;color: #001080;&quot;&gt;c1&lt;/span&gt;.&lt;span style=&quot;color: #795e26;&quot;&gt;CompareTo&lt;/span&gt;(&lt;span style=&quot;color: #001080;&quot;&gt;c2&lt;/span&gt;);&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #af00db;&quot;&gt;return&lt;/span&gt; &lt;span style=&quot;color: #001080;&quot;&gt;map&lt;/span&gt;[&lt;span style=&quot;color: #001080;&quot;&gt;c2&lt;/span&gt; - &lt;span style=&quot;color: #a31515;&quot;&gt;&#39;a&#39;&lt;/span&gt;].&lt;span style=&quot;color: #795e26;&quot;&gt;CompareTo&lt;/span&gt;(&lt;span style=&quot;color: #001080;&quot;&gt;map&lt;/span&gt;[&lt;span style=&quot;color: #001080;&quot;&gt;c1&lt;/span&gt; - &lt;span style=&quot;color: #a31515;&quot;&gt;&#39;a&#39;&lt;/span&gt;]);&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; });&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: blue;&quot;&gt;int&lt;/span&gt; &lt;span style=&quot;color: #001080;&quot;&gt;totalPushes&lt;/span&gt; = &lt;span style=&quot;color: #098658;&quot;&gt;0&lt;/span&gt;;&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: blue;&quot;&gt;int&lt;/span&gt; &lt;span style=&quot;color: #001080;&quot;&gt;currReqdPushes&lt;/span&gt; = &lt;span style=&quot;color: #098658;&quot;&gt;1&lt;/span&gt;;&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: blue;&quot;&gt;int&lt;/span&gt; &lt;span style=&quot;color: #001080;&quot;&gt;distintCharsAtCurrLevel&lt;/span&gt; = &lt;span style=&quot;color: #098658;&quot;&gt;1&lt;/span&gt;;&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #af00db;&quot;&gt;for&lt;/span&gt; (&lt;span style=&quot;color: blue;&quot;&gt;int&lt;/span&gt; &lt;span style=&quot;color: #001080;&quot;&gt;i&lt;/span&gt; = &lt;span style=&quot;color: #098658;&quot;&gt;0&lt;/span&gt;; &lt;span style=&quot;color: #001080;&quot;&gt;i&lt;/span&gt; &amp;lt; &lt;span style=&quot;color: #001080;&quot;&gt;length&lt;/span&gt;; )&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; {&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #001080;&quot;&gt;totalPushes&lt;/span&gt; += &lt;span style=&quot;color: #001080;&quot;&gt;map&lt;/span&gt;[&lt;span style=&quot;color: #001080;&quot;&gt;wordArr&lt;/span&gt;[&lt;span style=&quot;color: #001080;&quot;&gt;i&lt;/span&gt;] - &lt;span style=&quot;color: #a31515;&quot;&gt;&#39;a&#39;&lt;/span&gt;] * &lt;span style=&quot;color: #001080;&quot;&gt;currReqdPushes&lt;/span&gt;;&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ++&lt;span style=&quot;color: #001080;&quot;&gt;distintCharsAtCurrLevel&lt;/span&gt;;&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #af00db;&quot;&gt;if&lt;/span&gt; (&lt;span style=&quot;color: #001080;&quot;&gt;distintCharsAtCurrLevel&lt;/span&gt; &amp;gt; &lt;span style=&quot;color: #098658;&quot;&gt;8&lt;/span&gt;)&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; {&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #001080;&quot;&gt;distintCharsAtCurrLevel&lt;/span&gt; = &lt;span style=&quot;color: #098658;&quot;&gt;1&lt;/span&gt;;&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ++&lt;span style=&quot;color: #001080;&quot;&gt;currReqdPushes&lt;/span&gt;;&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #001080;&quot;&gt;i&lt;/span&gt; += &lt;span style=&quot;color: #001080;&quot;&gt;map&lt;/span&gt;[&lt;span style=&quot;color: #001080;&quot;&gt;wordArr&lt;/span&gt;[&lt;span style=&quot;color: #001080;&quot;&gt;i&lt;/span&gt;] - &lt;span style=&quot;color: #a31515;&quot;&gt;&#39;a&#39;&lt;/span&gt;];&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #af00db;&quot;&gt;return&lt;/span&gt; &lt;span style=&quot;color: #001080;&quot;&gt;totalPushes&lt;/span&gt;;&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; }&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;Approach 2: Sort frequency array:&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div style=&quot;background-color: white; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 13px; line-height: 18px; white-space: pre;&quot;&gt;&lt;div&gt;&lt;span style=&quot;color: blue;&quot;&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;/span&gt;public&lt;/span&gt; &lt;span style=&quot;color: blue;&quot;&gt;int&lt;/span&gt; &lt;span style=&quot;color: #795e26;&quot;&gt;MinimumPushes&lt;/span&gt;(&lt;span style=&quot;color: blue;&quot;&gt;string&lt;/span&gt; &lt;span style=&quot;color: #001080;&quot;&gt;word&lt;/span&gt;)&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; {&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: blue;&quot;&gt;int&lt;/span&gt; &lt;span style=&quot;color: #001080;&quot;&gt;length&lt;/span&gt; = &lt;span style=&quot;color: #001080;&quot;&gt;word&lt;/span&gt;?.&lt;span style=&quot;color: #001080;&quot;&gt;Length&lt;/span&gt; ?? &lt;span style=&quot;color: #098658;&quot;&gt;0&lt;/span&gt;;&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #af00db;&quot;&gt;if&lt;/span&gt; (&lt;span style=&quot;color: #001080;&quot;&gt;length&lt;/span&gt; &amp;lt;= &lt;span style=&quot;color: #098658;&quot;&gt;8&lt;/span&gt;)&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; {&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #af00db;&quot;&gt;return&lt;/span&gt; &lt;span style=&quot;color: #001080;&quot;&gt;length&lt;/span&gt;;&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: blue;&quot;&gt;var&lt;/span&gt; &lt;span style=&quot;color: #001080;&quot;&gt;wordArr&lt;/span&gt; = &lt;span style=&quot;color: #001080;&quot;&gt;word&lt;/span&gt;.&lt;span style=&quot;color: #795e26;&quot;&gt;ToCharArray&lt;/span&gt;();&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: blue;&quot;&gt;int&lt;/span&gt;[] &lt;span style=&quot;color: #001080;&quot;&gt;map&lt;/span&gt; = &lt;span style=&quot;color: blue;&quot;&gt;new&lt;/span&gt; &lt;span style=&quot;color: blue;&quot;&gt;int&lt;/span&gt;[&lt;span style=&quot;color: #098658;&quot;&gt;26&lt;/span&gt;];&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #af00db;&quot;&gt;foreach&lt;/span&gt; (&lt;span style=&quot;color: blue;&quot;&gt;char&lt;/span&gt; &lt;span style=&quot;color: #001080;&quot;&gt;ch&lt;/span&gt; &lt;span style=&quot;color: #af00db;&quot;&gt;in&lt;/span&gt; &lt;span style=&quot;color: #001080;&quot;&gt;word&lt;/span&gt;)&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; {&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ++&lt;span style=&quot;color: #001080;&quot;&gt;map&lt;/span&gt;[&lt;span style=&quot;color: #001080;&quot;&gt;ch&lt;/span&gt; - &lt;span style=&quot;color: #a31515;&quot;&gt;&#39;a&#39;&lt;/span&gt;];&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #001080;&quot;&gt;Array&lt;/span&gt;.&lt;span style=&quot;color: #795e26;&quot;&gt;Sort&lt;/span&gt;(&lt;span style=&quot;color: #001080;&quot;&gt;map&lt;/span&gt;, (&lt;span style=&quot;color: #001080;&quot;&gt;i1&lt;/span&gt;, &lt;span style=&quot;color: #001080;&quot;&gt;i2&lt;/span&gt;) =&amp;gt; {&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #af00db;&quot;&gt;return&lt;/span&gt; &lt;span style=&quot;color: #001080;&quot;&gt;i2&lt;/span&gt;.&lt;span style=&quot;color: #795e26;&quot;&gt;CompareTo&lt;/span&gt;(&lt;span style=&quot;color: #001080;&quot;&gt;i1&lt;/span&gt;);&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; });&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: blue;&quot;&gt;int&lt;/span&gt; &lt;span style=&quot;color: #001080;&quot;&gt;totalPushes&lt;/span&gt; = &lt;span style=&quot;color: #098658;&quot;&gt;0&lt;/span&gt;;&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: blue;&quot;&gt;int&lt;/span&gt; &lt;span style=&quot;color: #001080;&quot;&gt;currReqdPushes&lt;/span&gt; = &lt;span style=&quot;color: #098658;&quot;&gt;1&lt;/span&gt;;&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #af00db;&quot;&gt;for&lt;/span&gt; (&lt;span style=&quot;color: blue;&quot;&gt;int&lt;/span&gt; &lt;span style=&quot;color: #001080;&quot;&gt;i&lt;/span&gt; = &lt;span style=&quot;color: #098658;&quot;&gt;0&lt;/span&gt;; &lt;span style=&quot;color: #001080;&quot;&gt;i&lt;/span&gt; &amp;lt; &lt;span style=&quot;color: #098658;&quot;&gt;26&lt;/span&gt;; ++&lt;span style=&quot;color: #001080;&quot;&gt;i&lt;/span&gt;)&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; {&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #af00db;&quot;&gt;if&lt;/span&gt; (&lt;span style=&quot;color: #001080;&quot;&gt;map&lt;/span&gt;[&lt;span style=&quot;color: #001080;&quot;&gt;i&lt;/span&gt;] == &lt;span style=&quot;color: #098658;&quot;&gt;0&lt;/span&gt;)&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; {&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #af00db;&quot;&gt;break&lt;/span&gt;;&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #af00db;&quot;&gt;if&lt;/span&gt; (&lt;span style=&quot;color: #001080;&quot;&gt;i&lt;/span&gt; != &lt;span style=&quot;color: #098658;&quot;&gt;0&lt;/span&gt; &amp;amp;&amp;amp; &lt;span style=&quot;color: #001080;&quot;&gt;i&lt;/span&gt; % &lt;span style=&quot;color: #098658;&quot;&gt;8&lt;/span&gt; == &lt;span style=&quot;color: #098658;&quot;&gt;0&lt;/span&gt;)&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; {&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ++&lt;span style=&quot;color: #001080;&quot;&gt;currReqdPushes&lt;/span&gt;;&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #001080;&quot;&gt;totalPushes&lt;/span&gt; += &lt;span style=&quot;color: #001080;&quot;&gt;map&lt;/span&gt;[&lt;span style=&quot;color: #001080;&quot;&gt;i&lt;/span&gt;] * &lt;span style=&quot;color: #001080;&quot;&gt;currReqdPushes&lt;/span&gt;;&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #af00db;&quot;&gt;return&lt;/span&gt; &lt;span style=&quot;color: #001080;&quot;&gt;totalPushes&lt;/span&gt;;&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; }&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;Complexity:&lt;/b&gt; &lt;b&gt;Approach 1:&lt;/b&gt; O(nlogn)&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;b&gt;Approach 2:&lt;/b&gt; O(n)&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://algods-cracker.blogspot.com/feeds/946390900734950754/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://algods-cracker.blogspot.com/2024/08/leetcode-minimum-number-of-pushes-to.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7496974970329409400/posts/default/946390900734950754'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7496974970329409400/posts/default/946390900734950754'/><link rel='alternate' type='text/html' href='http://algods-cracker.blogspot.com/2024/08/leetcode-minimum-number-of-pushes-to.html' title='[LeetCode] Minimum Number of Pushes to Type Word II'/><author><name>Nishant Saxena</name><uri>http://www.blogger.com/profile/17860524009847591950</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjOdjS62BAEI1iMG_zd6lew4qyFGpfJhWHp0AJWQhiJvxQpSGg0AFZ5euJG7tK0D-EGQFno32hF-i1x4E2A49re_8-b9r0QHwXQ-9X_EvlAcekIjUYMaA1v6dWzDqzkBg/s220/2d230a1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7496974970329409400.post-1606954727530962341</id><published>2024-07-27T01:22:00.005+05:30</published><updated>2024-07-27T01:22:40.125+05:30</updated><category scheme="http://www.blogger.com/atom/ns#" term="Graph"/><category scheme="http://www.blogger.com/atom/ns#" term="LeetCode"/><title type='text'>[LeetCode] Find the City With the Smallest Number of Neighbors at a Threshold Distance</title><content type='html'>&lt;p&gt;&lt;b&gt;Problem:&lt;/b&gt; There are n cities numbered from 0 to n-1. Given the array edges where &lt;i&gt;edges[i] = [fromi, toi, weighti]&lt;/i&gt; represents a bidirectional and weighted edge between cities fromi and toi, and given the integer distanceThreshold.&lt;/p&gt;&lt;p&gt;Return the city with the smallest number of cities that are reachable through some path and whose distance is at most distanceThreshold, If there are multiple such cities, return the city with the greatest number.&lt;/p&gt;&lt;p&gt;Notice that the distance of a path connecting cities i and j is equal to the sum of the edges&#39; weights along that path.&lt;/p&gt;&lt;p&gt;Example:&lt;/p&gt;&lt;p&gt;&lt;img alt=&quot;&quot; src=&quot;https://assets.leetcode.com/uploads/2020/01/16/find_the_city_01.png&quot; style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-translate-x: 0; --tw-translate-y: 0; background-color: #f0f0f0; border-color: hsl(var(--sd-border)); border-image: initial; border-style: none; border-width: 0px; box-sizing: border-box; color: #262626; display: block; font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe UI&amp;quot;, Helvetica, Arial, sans-serif, &amp;quot;Apple Color Emoji&amp;quot;, &amp;quot;Segoe UI Emoji&amp;quot;; font-size: 14px; height: 225px; max-width: 100%; overflow-wrap: break-word; vertical-align: middle; width: 300px;&quot; /&gt;&lt;/p&gt;&lt;pre style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-translate-x: 0; --tw-translate-y: 0; background-color: #f0f0f0; border-color: var(--border-tertiary); border-image: initial; border-style: solid; border-width: 0px 0px 0px 2px; box-sizing: border-box; color: var(--text-secondary); font-family: Menlo, sans-serif; font-size: 14px; line-height: 1.25rem; margin-bottom: 1rem; margin-top: 1rem; overflow-wrap: break-word; overflow: visible; padding-left: 1rem; text-wrap: wrap;&quot;&gt;&lt;span style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-text-opacity: 1; --tw-translate-x: 0; --tw-translate-y: 0; border-color: hsl(var(--sd-border)); border-image: initial; border-style: solid; border-width: 0px; box-sizing: border-box; color: rgb(38 38 38/var(--tw-text-opacity)); font-weight: 700; overflow-wrap: break-word;&quot;&gt;Input:&lt;/span&gt; n = 4, edges = [[0,1,3],[1,2,1],[1,3,4],[2,3,1]], distanceThreshold = 4
&lt;span style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-text-opacity: 1; --tw-translate-x: 0; --tw-translate-y: 0; border-color: hsl(var(--sd-border)); border-image: initial; border-style: solid; border-width: 0px; box-sizing: border-box; color: rgb(38 38 38/var(--tw-text-opacity)); font-weight: 700; overflow-wrap: break-word;&quot;&gt;Output:&lt;/span&gt; 3
&lt;span style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-text-opacity: 1; --tw-translate-x: 0; --tw-translate-y: 0; border-color: hsl(var(--sd-border)); border-image: initial; border-style: solid; border-width: 0px; box-sizing: border-box; color: rgb(38 38 38/var(--tw-text-opacity)); font-weight: 700; overflow-wrap: break-word;&quot;&gt;Explanation: &lt;/span&gt;The figure above describes the graph.&amp;nbsp;
The neighboring cities at a distanceThreshold = 4 for each city are:
City 0 -&amp;gt; [City 1, City 2]&amp;nbsp;
City 1 -&amp;gt; [City 0, City 2, City 3]&amp;nbsp;
City 2 -&amp;gt; [City 0, City 1, City 3]&amp;nbsp;
City 3 -&amp;gt; [City 1, City 2]&amp;nbsp;
Cities 0 and 3 have 2 neighboring cities at a distanceThreshold = 4, but we have to return city 3 since it has the greatest number.&lt;/pre&gt;&lt;p&gt;&lt;img alt=&quot;&quot; src=&quot;https://assets.leetcode.com/uploads/2020/01/16/find_the_city_02.png&quot; style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-translate-x: 0; --tw-translate-y: 0; background-color: #f0f0f0; border-color: hsl(var(--sd-border)); border-image: initial; border-style: none; border-width: 0px; box-sizing: border-box; color: #262626; display: block; font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe UI&amp;quot;, Helvetica, Arial, sans-serif, &amp;quot;Apple Color Emoji&amp;quot;, &amp;quot;Segoe UI Emoji&amp;quot;; font-size: 14px; height: 225px; max-width: 100%; overflow-wrap: break-word; vertical-align: middle; width: 300px;&quot; /&gt;&lt;/p&gt;&lt;pre style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-translate-x: 0; --tw-translate-y: 0; background-color: #f0f0f0; border-color: var(--border-tertiary); border-image: initial; border-style: solid; border-width: 0px 0px 0px 2px; box-sizing: border-box; color: var(--text-secondary); font-family: Menlo, sans-serif; font-size: 14px; line-height: 1.25rem; margin-bottom: 1rem; margin-top: 1rem; overflow-wrap: break-word; overflow: visible; padding-left: 1rem; text-wrap: wrap;&quot;&gt;&lt;span style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-text-opacity: 1; --tw-translate-x: 0; --tw-translate-y: 0; border-color: hsl(var(--sd-border)); border-image: initial; border-style: solid; border-width: 0px; box-sizing: border-box; color: rgb(38 38 38/var(--tw-text-opacity)); font-weight: 700; overflow-wrap: break-word;&quot;&gt;Input:&lt;/span&gt; n = 5, edges = [[0,1,2],[0,4,8],[1,2,3],[1,4,2],[2,3,1],[3,4,1]], distanceThreshold = 2
&lt;span style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-text-opacity: 1; --tw-translate-x: 0; --tw-translate-y: 0; border-color: hsl(var(--sd-border)); border-image: initial; border-style: solid; border-width: 0px; box-sizing: border-box; color: rgb(38 38 38/var(--tw-text-opacity)); font-weight: 700; overflow-wrap: break-word;&quot;&gt;Output:&lt;/span&gt; 0
&lt;span style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-text-opacity: 1; --tw-translate-x: 0; --tw-translate-y: 0; border-color: hsl(var(--sd-border)); border-image: initial; border-style: solid; border-width: 0px; box-sizing: border-box; color: rgb(38 38 38/var(--tw-text-opacity)); font-weight: 700; overflow-wrap: break-word;&quot;&gt;Explanation: &lt;/span&gt;The figure above describes the graph.&amp;nbsp;
The neighboring cities at a distanceThreshold = 2 for each city are:
City 0 -&amp;gt; [City 1]&amp;nbsp;
City 1 -&amp;gt; [City 0, City 4]&amp;nbsp;
City 2 -&amp;gt; [City 3, City 4]&amp;nbsp;
City 3 -&amp;gt; [City 2, City 4]
City 4 -&amp;gt; [City 1, City 2, City 3]&amp;nbsp;
The city 0 has 1 neighboring city at a distanceThreshold = 2.&lt;/pre&gt;&lt;p&gt;Constraints:&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;2 &amp;lt;= n &amp;lt;= 100&lt;/li&gt;&lt;li&gt;1 &amp;lt;= edges.length &amp;lt;= n * (n - 1) / 2&lt;/li&gt;&lt;li&gt;edges[i].length == 3&lt;/li&gt;&lt;li&gt;0 &amp;lt;= fromi &amp;lt; toi &amp;lt; n&lt;/li&gt;&lt;li&gt;1 &amp;lt;= weighti, distanceThreshold &amp;lt;= 10^4&lt;/li&gt;&lt;li&gt;All pairs (fromi, toi) are distinct.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;Approach:&lt;/b&gt; This is clearly a &lt;a href=&quot;https://algods-cracker.blogspot.com/2024/07/floyd-warshall-algorithm.html&quot; target=&quot;_blank&quot;&gt;Floyd-Warshall&lt;/a&gt; problem as we can do BFS here but the complexity will be n^n. Once we get the dist matrix from Floy Warshall algorithm, things becomes simpler. Now we know that we have the shortest path matrix &#39;dist&#39; with us so we just need to traverse this matrix:&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;For every node i from 0...n-1:&amp;nbsp;&lt;/li&gt;&lt;ul&gt;&lt;li&gt;Check if dist[i][j] &amp;lt;= distanceThreshold then we know j is reachable from i.&lt;/li&gt;&lt;/ul&gt;&lt;/ul&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;Now in this way we just need to calculate the number of cities reachable from every city i and return the city with minimum number of connected cities.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;Implementation in C#:&lt;/b&gt;&lt;/p&gt;&lt;div style=&quot;background-color: white; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 13px; line-height: 18px; white-space: pre;&quot;&gt;&lt;div&gt;&lt;span style=&quot;color: blue;&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color: blue;&quot;&gt;class&lt;/span&gt; &lt;span style=&quot;color: #267f99;&quot;&gt;Solution&lt;/span&gt; &lt;/div&gt;&lt;div style=&quot;line-height: 18px;&quot;&gt;&lt;div&gt;{&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: blue;&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color: blue;&quot;&gt;int&lt;/span&gt; &lt;span style=&quot;color: #795e26;&quot;&gt;FindTheCity&lt;/span&gt;(&lt;span style=&quot;color: blue;&quot;&gt;int&lt;/span&gt; &lt;span style=&quot;color: #001080;&quot;&gt;n&lt;/span&gt;,&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;span style=&quot;color: blue;&quot;&gt;int&lt;/span&gt;[][] &lt;span style=&quot;color: #001080;&quot;&gt;edges&lt;/span&gt;,&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;span style=&quot;color: blue;&quot;&gt;int&lt;/span&gt; &lt;span style=&quot;color: #001080;&quot;&gt;distanceThreshold&lt;/span&gt;)&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; {&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: blue;&quot;&gt;int&lt;/span&gt;[,] &lt;span style=&quot;color: #001080;&quot;&gt;dist&lt;/span&gt; = &lt;span style=&quot;color: blue;&quot;&gt;this&lt;/span&gt;.&lt;span style=&quot;color: #795e26;&quot;&gt;FloydWarshall&lt;/span&gt;(&lt;span style=&quot;color: #001080;&quot;&gt;edges&lt;/span&gt;, &lt;span style=&quot;color: #001080;&quot;&gt;n&lt;/span&gt;);&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: blue;&quot;&gt;int&lt;/span&gt; &lt;span style=&quot;color: #001080;&quot;&gt;minCount&lt;/span&gt; = &lt;span style=&quot;color: #001080;&quot;&gt;INF&lt;/span&gt;;&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: blue;&quot;&gt;int&lt;/span&gt; &lt;span style=&quot;color: #001080;&quot;&gt;minCity&lt;/span&gt; = -&lt;span style=&quot;color: #098658;&quot;&gt;1&lt;/span&gt;;&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #af00db;&quot;&gt;for&lt;/span&gt; (&lt;span style=&quot;color: blue;&quot;&gt;int&lt;/span&gt; &lt;span style=&quot;color: #001080;&quot;&gt;i&lt;/span&gt; = &lt;span style=&quot;color: #098658;&quot;&gt;0&lt;/span&gt;; &lt;span style=&quot;color: #001080;&quot;&gt;i&lt;/span&gt; &amp;lt; &lt;span style=&quot;color: #001080;&quot;&gt;n&lt;/span&gt;; ++&lt;span style=&quot;color: #001080;&quot;&gt;i&lt;/span&gt;)&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; {&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: blue;&quot;&gt;int&lt;/span&gt; &lt;span style=&quot;color: #001080;&quot;&gt;currCount&lt;/span&gt; = &lt;span style=&quot;color: #098658;&quot;&gt;0&lt;/span&gt;;&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #af00db;&quot;&gt;for&lt;/span&gt; (&lt;span style=&quot;color: blue;&quot;&gt;int&lt;/span&gt; &lt;span style=&quot;color: #001080;&quot;&gt;j&lt;/span&gt; = &lt;span style=&quot;color: #098658;&quot;&gt;0&lt;/span&gt;; &lt;span style=&quot;color: #001080;&quot;&gt;j&lt;/span&gt; &amp;lt; &lt;span style=&quot;color: #001080;&quot;&gt;n&lt;/span&gt;; ++&lt;span style=&quot;color: #001080;&quot;&gt;j&lt;/span&gt;)&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; {&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #af00db;&quot;&gt;if&lt;/span&gt; (&lt;span style=&quot;color: #001080;&quot;&gt;i&lt;/span&gt; != &lt;span style=&quot;color: #001080;&quot;&gt;j&lt;/span&gt;)&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; {&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #af00db;&quot;&gt;if&lt;/span&gt; (&lt;span style=&quot;color: #001080;&quot;&gt;dist&lt;/span&gt;[&lt;span style=&quot;color: #001080;&quot;&gt;i&lt;/span&gt;, &lt;span style=&quot;color: #001080;&quot;&gt;j&lt;/span&gt;] &amp;lt;= &lt;span style=&quot;color: #001080;&quot;&gt;distanceThreshold&lt;/span&gt;)&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; {&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ++&lt;span style=&quot;color: #001080;&quot;&gt;currCount&lt;/span&gt;;&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #af00db;&quot;&gt;if&lt;/span&gt; (&lt;span style=&quot;color: #001080;&quot;&gt;currCount&lt;/span&gt; &amp;lt;= &lt;span style=&quot;color: #001080;&quot;&gt;minCount&lt;/span&gt;)&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; {&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #001080;&quot;&gt;minCount&lt;/span&gt; = &lt;span style=&quot;color: #001080;&quot;&gt;currCount&lt;/span&gt;;&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #001080;&quot;&gt;minCity&lt;/span&gt; = &lt;span style=&quot;color: #001080;&quot;&gt;i&lt;/span&gt;;&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; } &lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #af00db;&quot;&gt;return&lt;/span&gt; &lt;span style=&quot;color: #001080;&quot;&gt;minCity&lt;/span&gt;;&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; }&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: blue;&quot;&gt;private&lt;/span&gt; &lt;span style=&quot;color: blue;&quot;&gt;int&lt;/span&gt;[,] &lt;span style=&quot;color: #795e26;&quot;&gt;FloydWarshall&lt;/span&gt;(&lt;span style=&quot;color: blue;&quot;&gt;int&lt;/span&gt;[][] &lt;span style=&quot;color: #001080;&quot;&gt;edges&lt;/span&gt;, &lt;span style=&quot;color: blue;&quot;&gt;int&lt;/span&gt; &lt;span style=&quot;color: #001080;&quot;&gt;n&lt;/span&gt;)&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; {&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: blue;&quot;&gt;int&lt;/span&gt;[,] &lt;span style=&quot;color: #001080;&quot;&gt;dist&lt;/span&gt; = &lt;span style=&quot;color: blue;&quot;&gt;this&lt;/span&gt;.&lt;span style=&quot;color: #795e26;&quot;&gt;InitDist&lt;/span&gt;(&lt;span style=&quot;color: #001080;&quot;&gt;edges&lt;/span&gt;, &lt;span style=&quot;color: #001080;&quot;&gt;n&lt;/span&gt;);&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #af00db;&quot;&gt;for&lt;/span&gt; (&lt;span style=&quot;color: blue;&quot;&gt;int&lt;/span&gt; &lt;span style=&quot;color: #001080;&quot;&gt;k&lt;/span&gt; = &lt;span style=&quot;color: #098658;&quot;&gt;0&lt;/span&gt;; &lt;span style=&quot;color: #001080;&quot;&gt;k&lt;/span&gt; &amp;lt; &lt;span style=&quot;color: #001080;&quot;&gt;n&lt;/span&gt;; ++&lt;span style=&quot;color: #001080;&quot;&gt;k&lt;/span&gt;)&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; {&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #af00db;&quot;&gt;for&lt;/span&gt; (&lt;span style=&quot;color: blue;&quot;&gt;int&lt;/span&gt; &lt;span style=&quot;color: #001080;&quot;&gt;i&lt;/span&gt; = &lt;span style=&quot;color: #098658;&quot;&gt;0&lt;/span&gt;; &lt;span style=&quot;color: #001080;&quot;&gt;i&lt;/span&gt; &amp;lt; &lt;span style=&quot;color: #001080;&quot;&gt;n&lt;/span&gt;; ++&lt;span style=&quot;color: #001080;&quot;&gt;i&lt;/span&gt;)&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; {&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #af00db;&quot;&gt;for&lt;/span&gt; (&lt;span style=&quot;color: blue;&quot;&gt;int&lt;/span&gt; &lt;span style=&quot;color: #001080;&quot;&gt;j&lt;/span&gt; = &lt;span style=&quot;color: #098658;&quot;&gt;0&lt;/span&gt;; &lt;span style=&quot;color: #001080;&quot;&gt;j&lt;/span&gt; &amp;lt; &lt;span style=&quot;color: #001080;&quot;&gt;n&lt;/span&gt;; ++&lt;span style=&quot;color: #001080;&quot;&gt;j&lt;/span&gt;)&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; {&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #af00db;&quot;&gt;if&lt;/span&gt; (&lt;span style=&quot;color: #001080;&quot;&gt;dist&lt;/span&gt;[&lt;span style=&quot;color: #001080;&quot;&gt;i&lt;/span&gt;, &lt;span style=&quot;color: #001080;&quot;&gt;j&lt;/span&gt;] &amp;gt; &lt;span style=&quot;color: #001080;&quot;&gt;dist&lt;/span&gt;[&lt;span style=&quot;color: #001080;&quot;&gt;i&lt;/span&gt;, &lt;span style=&quot;color: #001080;&quot;&gt;k&lt;/span&gt;] + &lt;span style=&quot;color: #001080;&quot;&gt;dist&lt;/span&gt;[&lt;span style=&quot;color: #001080;&quot;&gt;k&lt;/span&gt;, &lt;span style=&quot;color: #001080;&quot;&gt;j&lt;/span&gt;])&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; {&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #001080;&quot;&gt;dist&lt;/span&gt;[&lt;span style=&quot;color: #001080;&quot;&gt;i&lt;/span&gt;, &lt;span style=&quot;color: #001080;&quot;&gt;j&lt;/span&gt;] = &lt;span style=&quot;color: #001080;&quot;&gt;dist&lt;/span&gt;[&lt;span style=&quot;color: #001080;&quot;&gt;i&lt;/span&gt;, &lt;span style=&quot;color: #001080;&quot;&gt;k&lt;/span&gt;] + &lt;span style=&quot;color: #001080;&quot;&gt;dist&lt;/span&gt;[&lt;span style=&quot;color: #001080;&quot;&gt;k&lt;/span&gt;, &lt;span style=&quot;color: #001080;&quot;&gt;j&lt;/span&gt;];&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #af00db;&quot;&gt;return&lt;/span&gt; &lt;span style=&quot;color: #001080;&quot;&gt;dist&lt;/span&gt;;&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; }&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: blue;&quot;&gt;private&lt;/span&gt; &lt;span style=&quot;color: blue;&quot;&gt;int&lt;/span&gt;[,] &lt;span style=&quot;color: #795e26;&quot;&gt;InitDist&lt;/span&gt;(&lt;span style=&quot;color: blue;&quot;&gt;int&lt;/span&gt;[][] &lt;span style=&quot;color: #001080;&quot;&gt;edges&lt;/span&gt;, &lt;span style=&quot;color: blue;&quot;&gt;int&lt;/span&gt; &lt;span style=&quot;color: #001080;&quot;&gt;n&lt;/span&gt;)&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; {&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: blue;&quot;&gt;int&lt;/span&gt;[,] &lt;span style=&quot;color: #001080;&quot;&gt;dist&lt;/span&gt; = &lt;span style=&quot;color: blue;&quot;&gt;new&lt;/span&gt; &lt;span style=&quot;color: blue;&quot;&gt;int&lt;/span&gt;[&lt;span style=&quot;color: #001080;&quot;&gt;n&lt;/span&gt;, &lt;span style=&quot;color: #001080;&quot;&gt;n&lt;/span&gt;];&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #af00db;&quot;&gt;for&lt;/span&gt; (&lt;span style=&quot;color: blue;&quot;&gt;int&lt;/span&gt; &lt;span style=&quot;color: #001080;&quot;&gt;i&lt;/span&gt; = &lt;span style=&quot;color: #098658;&quot;&gt;0&lt;/span&gt;; &lt;span style=&quot;color: #001080;&quot;&gt;i&lt;/span&gt; &amp;lt; &lt;span style=&quot;color: #001080;&quot;&gt;n&lt;/span&gt;; ++&lt;span style=&quot;color: #001080;&quot;&gt;i&lt;/span&gt;)&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; {&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #af00db;&quot;&gt;for&lt;/span&gt; (&lt;span style=&quot;color: blue;&quot;&gt;int&lt;/span&gt; &lt;span style=&quot;color: #001080;&quot;&gt;j&lt;/span&gt; = &lt;span style=&quot;color: #098658;&quot;&gt;0&lt;/span&gt;; &lt;span style=&quot;color: #001080;&quot;&gt;j&lt;/span&gt; &amp;lt; &lt;span style=&quot;color: #001080;&quot;&gt;n&lt;/span&gt;; ++&lt;span style=&quot;color: #001080;&quot;&gt;j&lt;/span&gt;)&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; {&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #001080;&quot;&gt;dist&lt;/span&gt;[&lt;span style=&quot;color: #001080;&quot;&gt;i&lt;/span&gt;, &lt;span style=&quot;color: #001080;&quot;&gt;j&lt;/span&gt;] = &lt;span style=&quot;color: #001080;&quot;&gt;i&lt;/span&gt; == &lt;span style=&quot;color: #001080;&quot;&gt;j&lt;/span&gt; ? &lt;span style=&quot;color: #098658;&quot;&gt;0&lt;/span&gt; : &lt;span style=&quot;color: #001080;&quot;&gt;INF&lt;/span&gt;;&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #af00db;&quot;&gt;foreach&lt;/span&gt; (&lt;span style=&quot;color: blue;&quot;&gt;var&lt;/span&gt; &lt;span style=&quot;color: #001080;&quot;&gt;edge&lt;/span&gt; &lt;span style=&quot;color: #af00db;&quot;&gt;in&lt;/span&gt; &lt;span style=&quot;color: #001080;&quot;&gt;edges&lt;/span&gt;)&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; {&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #001080;&quot;&gt;dist&lt;/span&gt;[&lt;span style=&quot;color: #001080;&quot;&gt;edge&lt;/span&gt;[&lt;span style=&quot;color: #098658;&quot;&gt;0&lt;/span&gt;], &lt;span style=&quot;color: #001080;&quot;&gt;edge&lt;/span&gt;[&lt;span style=&quot;color: #098658;&quot;&gt;1&lt;/span&gt;]] = &lt;span style=&quot;color: #001080;&quot;&gt;edge&lt;/span&gt;[&lt;span style=&quot;color: #098658;&quot;&gt;2&lt;/span&gt;];&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #001080;&quot;&gt;dist&lt;/span&gt;[&lt;span style=&quot;color: #001080;&quot;&gt;edge&lt;/span&gt;[&lt;span style=&quot;color: #098658;&quot;&gt;1&lt;/span&gt;], &lt;span style=&quot;color: #001080;&quot;&gt;edge&lt;/span&gt;[&lt;span style=&quot;color: #098658;&quot;&gt;0&lt;/span&gt;]] = &lt;span style=&quot;color: #001080;&quot;&gt;edge&lt;/span&gt;[&lt;span style=&quot;color: #098658;&quot;&gt;2&lt;/span&gt;];&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #af00db;&quot;&gt;return&lt;/span&gt; &lt;span style=&quot;color: #001080;&quot;&gt;dist&lt;/span&gt;;&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; }&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: green;&quot;&gt;// Max sum could be 10^4 * 10^2 = 10^6&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: blue;&quot;&gt;private&lt;/span&gt; &lt;span style=&quot;color: blue;&quot;&gt;const&lt;/span&gt; &lt;span style=&quot;color: blue;&quot;&gt;int&lt;/span&gt; &lt;span style=&quot;color: #001080;&quot;&gt;INF&lt;/span&gt; = &lt;span style=&quot;color: #098658;&quot;&gt;9999999&lt;/span&gt;;&lt;/div&gt;&lt;div&gt;}&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;Complexity:&lt;/b&gt; O(n^3)&lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='http://algods-cracker.blogspot.com/feeds/1606954727530962341/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://algods-cracker.blogspot.com/2024/07/leetcode-find-city-with-smallest-number.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7496974970329409400/posts/default/1606954727530962341'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7496974970329409400/posts/default/1606954727530962341'/><link rel='alternate' type='text/html' href='http://algods-cracker.blogspot.com/2024/07/leetcode-find-city-with-smallest-number.html' title='[LeetCode] Find the City With the Smallest Number of Neighbors at a Threshold Distance'/><author><name>Nishant Saxena</name><uri>http://www.blogger.com/profile/17860524009847591950</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjOdjS62BAEI1iMG_zd6lew4qyFGpfJhWHp0AJWQhiJvxQpSGg0AFZ5euJG7tK0D-EGQFno32hF-i1x4E2A49re_8-b9r0QHwXQ-9X_EvlAcekIjUYMaA1v6dWzDqzkBg/s220/2d230a1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7496974970329409400.post-6170480625353416711</id><published>2024-07-27T00:37:00.004+05:30</published><updated>2024-07-27T00:37:32.973+05:30</updated><category scheme="http://www.blogger.com/atom/ns#" term="Algorithm"/><title type='text'>Floyd Warshall Algorithm</title><content type='html'>&lt;b&gt;Description:&lt;/b&gt; As per &lt;a href=&quot;https://en.wikipedia.org/wiki/Floyd%E2%80%93Warshall_algorithm&quot; target=&quot;_blank&quot;&gt;wiki&lt;/a&gt;, in computer science, the &lt;i&gt;Floyd–Warshall&lt;/i&gt; algorithm (also known as Floyd&#39;s algorithm, the Roy–Warshall algorithm, the Roy–Floyd algorithm, or the WFI algorithm) is an algorithm for &lt;i&gt;finding shortest paths in a directed weighted graph with positive or negative edge weights&lt;/i&gt; (but with no negative cycles). A single execution of the algorithm will find the lengths (summed weights) of shortest paths between all pairs of vertices.&amp;nbsp;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Although it does not return details of the paths themselves, it is possible to &lt;i&gt;reconstruct the paths with simple modifications&lt;/i&gt; to the algorithm.&amp;nbsp;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;Algorithm:&lt;/b&gt; Given a graph Graph[][] with nodes 1...N, we need to evaluate the matrix say shortestPathMatrix[][] where shortestPathMatrix[ni][nj] tells the shortest path between nodes ni and nj.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The algorithm uses &lt;i&gt;dynamic programming&lt;/i&gt; to evaluate the above matrix. It relies on a obvious thing that the &lt;i&gt;shortest path between n1 and n2 will have a intermediate node say nk&lt;/i&gt;:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class=&quot;SCXW243703675 BCX0&quot; style=&quot;-webkit-tap-highlight-color: transparent; -webkit-user-drag: none; background-color: white; display: inline-block; font-family: &amp;quot;Segoe UI&amp;quot;, &amp;quot;Segoe UI Web&amp;quot;, Arial, Verdana, sans-serif; font-size: 12px; margin: 0px; padding: 0px; user-select: text; white-space-collapse: preserve;&quot;&gt;&lt;span class=&quot;WACImageContainer NoPadding DragDrop BlobObject SCXW243703675 BCX0&quot; role=&quot;presentation&quot; style=&quot;-webkit-tap-highlight-color: transparent; -webkit-user-drag: none; cursor: move; display: inline-block; left: 0px; margin: 0px; padding: 0px; position: relative; top: 2px; user-select: text;&quot;&gt;&lt;img class=&quot;WACImage SCXW243703675 BCX0&quot; src=&quot;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAtwAAABXCAYAAAA3QZJbAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAAFiUAABYlAUlSJPAAABZwSURBVHhe7Z1bbBzXecf9aIikSJGUaqAP6UsBP7pvQh8qQ0tJ9F22Y1m2uTvrSx3FjmP5Lhu2yaVbsMgL2zxUBfog9KFQL0D1VAgo2iooECgvhWDUgIo0CdEgLdOkAdMCDW0H8fb8z5yznCVnyb3M7pyZ/f2AP8i9zO7st7P/+c6Z75xzR55MLUTHJxaqFycWatcmF6qbkwu15uCqbpu/1ycq1ZWJSnSveysAgLEDjwWAUMGfhowCYIJxxQR5qz1IRqfrzcMPXGjOPPJK88jjrzXnnnr3QB358uvNmUdftdtNnXm2/fV2dHXi5NJ5twsAAKUFjwWAUMGfhsyhE9FdE5Xamml5bCSDMLX4vAns15qz595szlc/bB6trw6s+epyc/bJt5szZ7/ePHzfC8mAN/UFm/24PH0m+g23awAAhQePBYBQwZ9GwPSJaEbd+pOV6qetAJsWiAIxv/RBarCylr5EtZT0xSYDb3RFB4HbVQCAwoHHAkCo4E+j4ER0p2nJXDKtiZ/7Dzf90Eu2+z8tIKOSvmC1ploB10FQqa1zUgCAQoHHAkCo4E+jwQT4ogl0q/hddTV5B3m31OKZfvjlnaAvVLfVClNrzH0MAIAgwWMBIFTwpxFwqLK0aHa6VZ+j2pnZ8++kfthQNPfM+7bV5ffZHChbOljcRwIACAY8FgBCBX8aEbZGxwd58TlbsJ724UKVWl9qhfnPYHRVl0TcxwMAyBU8FgBCBX8aAbYg3s6fWGtOnYq+0PQsaR+mKFJrbPJ0/Qsb8Er1FiPtASBP8FgACBX8aUQcOhXd4y8faNTp3NPvpX6Aokm1PX4qmQkV/J9cOus+MgBAVxyNGivz9caVo9HyPe6unsFjASBU8KcRoQnE7ehOs0OH73/R7OBy6o4XVfNRo62gXpdL3EcHADgQJdwtP6k3rh2Llo+7h7oCjwWAUMGfRoSmUPE7odWAtGNpO1wG6fJIK+ALtWvUHAJANyQT7oRuzEUfHbjUMB4LAKGCP42IeKUgV6vzxBupO1g2qZi+VdOzULvuQgEA0JEOCbfVfH311rFoNfUyJR6LxwKECv40In+aOrVUd29YuBGog0qTpe8U0tfWXUgAAFI5Gq3W07xkl27reW4TPBaPBQgW/GlE/mTnV3T1OkUfhdqvNHpVrTrFIPh5GgGgL1TysVu2t7pHqW47zUfSNF9f3Zh++KXfxWPxWIAQIQcckT9Nno7utiM1zZuoXidtR8ZFuoSiOEg6AF2IACAApqPlmWSiPB81LraS4PrqutGNXUr7ne9+zo1kIt2tuk249by5c6+fxWNjeY+dfvBCc7668rG5b+/3kZCJ3/W0+KdJZTzJ48MdNgCwD+SAOxpqDqj15f20L9MPfjV1B8ZNM4++6gJe3da0OC5UAJAxX4qW7/TJkZIlnziZJOuK+S36pGvL/zbd/8mEbL21jUm+k8mW5N5mKHRRUmIHUOKxeyWPnTrzXPPw/V/5bPrcWy/s/t6SOhp9tOi/44Nkk/P246P1nvP11e3E/UaNq+3br9aT76vGnfuqAUoL/rRXw8kBT0R3TlSqN/XCmpPwaG0l9c3HUTtLgVY3WbgBoHc0P3WcMJnEVAlNogfaJT+21CJx32Wf/MxHq+dDT3w6Jdzmc9xSkmifhMd21Kg9du/VkdXzO8m2jk+TgLtjUfLHqFPbMZps3KnR6N4CoFjgTx2VuT/5qV80ofl89cPUNx1XaRoczT0ZB5xR9QBJTDJ9V1vS0l7Ood/QTk+0S2j85f5fi5ZL0YDdnXCr8bB7ZhI8trOK5LE+uU4m6Yne9Nv286ihZW7vJOVxo1G/FfcyAEGBP3VWpv6kjN0XyJdl9aDMZVp75kCMR62yUhqMEb7Uo1Xm4RJql1S0kgt7v01APlosUzLdDT7hNrHY1P/u7hZ4bBcqkcd2aoT634yREnPdXjOPXxq33wuEBf7UhbLyJ782/rgXyB+k1qToleotFzqA0qATftwL17hkjnffS63eadtDbZIDeus6oEaGSgs6lRTgsd1pXDzWJ+THosYFl5C3NWD94NA4YV9m7BAMFfypOw3sT/H6+HZi89It15m17GWFnTX3mcYKCok/2dsTer1xzZzgb9rjO3GiVy+tnkNN6uDgsd0Lj21v+Jrf45XE79P8jQd36nEGckIW4E/da2B/UqaujY88/lrqG6B2aQJ4xUvF8yxLDKFzLFo+ruTZnKzXzPHre6xvK9GOE2vN+kAP2jDBY3sTHpvOXLR8ty/rUsPY/KY3jTZcEm7LUtxTAboGf+pNffuT6lC0oS2SN5l72oujvdJ0OYqblj11oQTIHZ2QXS3xuu8VM7KlICp3oMd69OCx/QmP7Q5drVIS7hvU5u+2fvvxb96Wo1D2BR3Bn/pT7/5kMnOTodv5FmfPvZX6oihdc8+871s425q30kUUYGT4ac18b5c5LrfMSVYlIVfiulB6rXMHj+1beGz/6LdvPaDeuGo8YSNW7AtqlLunwbiDP/Wtnv1J9SfawM63mPKCaH9pcIENeGXI6+wDGNQzbQfm1VfXjNR7bRLsuN6anuswwWMHEx6bDaoJd2Vll3cScA2AdvPDw1iCPw2mnvzJ1+2oHiXtxdD+0uACG2zTwqHOEIZBMsE22rZ1m3b5cnqviwAeO5jw2OGgXm7rI60SFI3nWK0zCHO8wJ8GU9f+1BqVeubZ1BcKWbVv/mVTfOe7P0x9fJTydTwm4BdcaAH6Rr3UcT2mXco8XiwmalzSwEf3FCgIRfbYkITHDhcl2bbWOy4/2bZ/zW2umJUbcsBs1JU/TVRql/UkrRGf9iIhS8H+xWefN//q2x+nPj5K+dGqWg7VhRagJ3RiS57w1IvtarCpWy0wRfNYfxL783+6lfp4XsJjR0dctqbSEz8mxDT8uZpWSsgBs9HB/hQXym/rSfMs3zmQNKrXtBDjlYdORwxGga6xl3VVR9mqxeaSbmkooMeGmnDjsfmgBn88IFtTDzauM+VgiSAHzEwH+tNEJbpXDx5efC71BVBvmn7opbiFM6aLNEBvxL3ZtnZSc+iusZxz+Siix4aacEt4bH7EZW6NC8arNNDyFuVtxYccMFvt608TleqKHgxlCc+k0f/O+3/S/OSHP7a3xY9+9j/NpT/8i47PT96fl2bPvemCXbvmQgywB/UQ6YRldFO92dRIlpcQPDYrX60s/6m9fPvvP9lq/ubL32h7bFTCY8NAnQXGv9RRcJmrccWFHDBb7etP5oEbejCUkak+eD/4r59ZY//uf/60+fcf/1vzW598397/6ee/bP7WG3+05/mhBFuXZOJgV7dciAFaxKUjtibyNtNwjQcheGwWvuqT7d3PHbXw2HCwgyzrdrn5Teq7i0kI/pRUqXNAX7tztLaSuvGo5YP3y1/9ak9L5hvXvmUf+/Dq3+15fijBlnRpRjHVyF8XZgBfPrKlS7LuLhgDQvDYQX31S19Za/73//6fPdmd/YM/az0vL+GxYeHm9d6kJK54kANmr47+pDunFp9P3SgP7Re8tMdCDPb0wy/HLZyTS+ddmGHMcZdfN+gFGi80cCYEjx3EV5Vs/+uPfpJ6AsxLeGx4uKR7g/K44hCKPyU1iFcln5unOvqT7lSRd9pGeagMwZ557KINtmk5XnJhhjFGSbZ6f1hGefyYPLl0NgSP7ddXNdXWP3//P4JKtiU8NkyMz91kBpPiEIo/JdWvVxUiB9SdIc29WIZgz557ywW7dsWFGcaYePGIBjMqjCEaqR6Cx/brq6qjFHnXbe8WHhsmWpjLfD8svV8QQvGnpPr1qkLkgLrzyBNvpG6Uh8oQ7Lln3rfBZnEGEOaYuK15bN1NGCP8ghJ5e+wgvur/z3Nmkt3CY8PErSew4W5C4ITiT0kN4lXJ5+apjv6kO+eeejd1ozxUhmD7UaqTC1WMZ8yxC0bUV5lNYUzR1FAheOygvuoHK4WwfLKEx4aLEu5j0epZdxMCJhR/SmpQrwpBHf2JYGcvTgbgcUu0r7mbMGYYH7BTbhU94Zb+5juf2Pv+8V++17ovL+Gx4eLHrDDtafiE4k9JZeFVeWvfhFsPpm2Uh8oQbCkOdq3pwgxjiDkO1jWIiFH748tEpXo7BI/Nwld//YXftwMod9+fl/DYcFGybb4jpkANnFD8KaksvCoEpfoTwR6OUoMNY4HKSObrjWtKtlmBbbxRD0cIHpuVryaT7uRcuHkIjw0bV899U2KGpjAJxZ+Sysqr8laqP4UW7LIoNdhQatSTfTRqrOhyqtEaPdtgTmibeOxwhMcWA83QZL6vLa1IqXITdzcEQBn8iYQbcTIYI+JEO15pTT3brLYGnhB7kMoiPLY46ErfTmdE4zpzdYdBGfypcAn33NPvpW6A+tN8ddkFu7rpwgwlRIm1OYFcNt+5em84icAejA/Eg5Lw2EyFxxYTdU6ortv45oakJJwOivwosj/99rt/3Pzm3367+YvPPg9uYa6O/mSDHdAI1TJIrUUXbEbQlwydMOJl2hvX496a1TVOGNAJ4wPX8djshccWHzebyWXnozeViGv8i3sYRkCR/cn3bCvZ/r2//ofU5+Sljv6kO7UqTtpGqD/NL30QB7tSveXCDAUmvhy6WndT/G2rbES3qdGGgzA+cAWPzV54bLnQvN3yV/PdbhmPvWVXrKTee+jgT8NRR3/SnUcefy11I9SfZp982wZbk8q7MEPBUK91fOnTzjaybU8GJslm1hHohcmF6iU8NnvhseXlWLR83HzH60a3Xe/3ZV1VpPc7e/Cn4aijP+nO6YdfTt0I9acjX349DnalxoInBUEJdjzwsXHFGLytL7T/G6OnJxv6ZeLk0nk8NnvhseOBHSdjZzmxVxc3zXdvknDNdrJap5RvcPCn4aijP+nOw/e/mLoR6k8zj7xig21aj0z6HyixkasW2w56tD0pvhcbI4esOHQqugePzV547HiS7Bgxx4HrAVeJX2NFg9bpHOkN/Gk46uhP9s7T9aZpRaZuiHrX4ftesMGeWoiOuzBDjsiEZcbxtFTxYEfzPdmeEpWNsCgDDIvpE9EMHpu98FgQ8fiajxa9t5tjY8vIert6xknC9wd/Go46+pOKuvUAo+gzUm3Ft2y27zgR8UMfMTJgl1xfsqarAThu2j6ZssyZOmwYJXhsxsJjYR8SVy/XzPFyI+4FX93Q/zYxj+vBSz8gU3HoZqpa/Clj7edPk5Xauh6ceexi+saoJ/lieaMbLsQwJNQzbUe37/Rcq/ZavdctY6X3GvIGj81WeCz0SkpHzE0dS+avOmTc+SLuES/L4Ez7WexnVMlN5wYG/pSt9vWnyZNLZ/Xg4QcupG6MetPM2a/bYE9UqisuxDAgGrUe90rYxFqzhiTMUnXXjUsyF3quIUTw2GyFx0JW+F5gJdvmfGJ7xI1u6zjTeWbnymh8jtG5yG0aPLbUJvG7UUMjbXwS/pSt9vUnX8MzdSqihicDTS0+74IdsepgD6gFvtv4zF/1WG/H/2tkelwSQq81FAk8NlvhsTAKdJ7x5yTf2WOOP1ui4o5FJee2d9w+bq+ofnSv5F4iVzS41O3nbq0ne/Hxp2x1oD+ZB+1qQ0eeeCP1BVB30vKoiuMkyw3vwZtXvJqYMah4kQMZlhY68Em17U2IBzLSYw3lAY/NRngshMKec5o9r8VJuDqLdLy6v3FiLvnnGSmR9wl6rGw7kvZJuLVf29oHf47Fn7JRV/7UuqTA1DADyU8FM25zw/rLcr6e2mrHZDRqXPFpMxxvMu4lAEoNHpuNxtVjobioDMWf71rnx/gcqcV9Wsm4T9ITUmlL63Gj9eT2/jU7yb1H8vXStGWed2n6VP0J/GlwdedPJ6I7lZHriXPPvJ/6Qmh/6VLM5On6F4rh9Jmo0PM4+2n0pF1JdJtBGLUn0y1DWK3HP3iW5gWw4LEDq0weC3AQvgfdS4mxPxeb5NzXm3eUeY4vfTlQ5rf146nF53+KP/WvnvypNVL1ka+lvhjaX35lIaPrLqRBkPzR+vlKW9op69CP0w5ElOzlptb9rUEjbZfASKYBegOPHUyheixAiOh8nfY7Skrnej+YEn8aTD3506ET0V2TC9VtbUALpzfNV5ebU2eetS2bbgby7G65diOT8LZat60EWMmwS4y9XLKc3L/WZalk8my3TwzyKNLoa4Aigsf2r149FmDcsef5lN+S5PKEtsGT+FP/6sufVHeiDZgeZujaXZt1oMwPZC2ZLMfSjB3tiTmragGECx7bn1pTbS3UrrlQAsA+dEi4VbPdGiy5G/ypP/XnT4k6Q03enfbCqF3zSx9oOh3TsqluHzoVUWYBAJ3BY3sWHgvQO8mEe16rbUaNiwd2yOFPPWsgf5pYqF60LZz7XmBOxi40/dBLcd1OpbbuQggA0BE8tjfhsQC9o4TbJNobmsSglyvf+FNvGtif/Nr6KgJPewMUKzHn4rbqn1z4AAD2BY/tTngsQH+krSrZLfhTd8rEn/ycsSoCP1pbSX0jtGpbgIqTWoQudAAAB4LHdic8FmD04E/dKTN/Mi9iVx6afvCrqW807vJF8qp3Ut2TCxsAQFfgsfsLjwXID/xpf2XqT5Ono7tN1v5zvaBWz0l7w3GVlj+NA11rHqosLbqQAQB0DR7bWXgsQL7gT501FH/SC01Wqp/qRanliTV7/h03IpXLnAAwGHjsXuGxAGGAP+3VUP1pcqF6QS8s6Y3SdmBcpOlf/NKdjJgHgCzAY3eExwKEBf60o5H4k58M3WT147sCUW2leXjxOX8ZgaWFASAz8FgjPBYgSPAno1H6k1bQ0RvpDbWMZeoOlVSai/Lw/S/Gga5Ub02fiFJXaQIA6Bc8Fo8FCBX8aZT+pBWI3NyMdkL06oepO1Y6mVaNRunaQC9UN6fPRH3PbQkA0BE8Fo8FCBX8abT+pIm9JyrV2/aNT9e/mHvq3fQdLInskp2Lz9tATyxUt1hWGACGCR6LxwKECv40Yn9SV7q/tCCVdeTq7JNvJ4rjq7fodQGAUYDHAkCo4E85YFo5Kz7gWkte3e5pO11E7UxobnWVRRcAYNTgsQAQKvjTiJmoRPeqm107pW53db+n7XxhZA6Yww9ccEGubms6HPdRAQBGDh4LAKGCP40YdbP7QnpNGaOWQdFaOhqBqssiU2ee9YHenFqIjruPCACQG3gsAIQK/jRqTkR3TlRql+MdNTpdb848drEQQZ8992YiyFY3NDDAfTIAgPzBYwEgVPCn0aMRnNpZv+P6EGo1qPWQ9kHz1Oy5t5KTmNui+MmTS2fdRwEACA48FgBCBX/KAVvXU6neTAZdrYi0Dz1qaeSp5pBsBXmhujFxcum823UAgODBYwEgVPCnHFBrwdf2WOkywyOvNOeefi81EMOSCvlnHn21vTWzUN00YsAOABQWPBYAQgV/yoGpU0t109qJJ0t30gdXAGbPvzOUOh9NyK4aovaWTBzkiYXqRaahAoCygMcCQKjgTzmg+p64sF4ti2QA4qVC1fJRgBSobpcN1Zr+er7qhDQ6trXefZs0vUvtyqHK0qLbFQCA0oHHAkCo4E85oQ9uWjyaOL1VYJ+lbP1QpbZui+DpaQGAMQOPBYBQwZ9yRHMemlbIBf8FmL9tlx86q7ph/prn19Z0mUDF+gQXAKAdPBYAQgV/AgAAAAAAAAAAAAAIkzvu+H90XSAeEoVWfgAAAABJRU5ErkJggg==&quot; srcset=&quot;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAtwAAABXCAYAAAA3QZJbAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAAFiUAABYlAUlSJPAAABZwSURBVHhe7Z1bbBzXecf9aIikSJGUaqAP6UsBP7pvQh8qQ0tJ9F22Y1m2uTvrSx3FjmP5Lhu2yaVbsMgL2zxUBfog9KFQL0D1VAgo2iooECgvhWDUgIo0CdEgLdOkAdMCDW0H8fb8z5yznCVnyb3M7pyZ/f2AP8i9zO7st7P/+c6Z75xzR55MLUTHJxaqFycWatcmF6qbkwu15uCqbpu/1ycq1ZWJSnSveysAgLEDjwWAUMGfhowCYIJxxQR5qz1IRqfrzcMPXGjOPPJK88jjrzXnnnr3QB358uvNmUdftdtNnXm2/fV2dHXi5NJ5twsAAKUFjwWAUMGfhsyhE9FdE5Xamml5bCSDMLX4vAns15qz595szlc/bB6trw6s+epyc/bJt5szZ7/ePHzfC8mAN/UFm/24PH0m+g23awAAhQePBYBQwZ9GwPSJaEbd+pOV6qetAJsWiAIxv/RBarCylr5EtZT0xSYDb3RFB4HbVQCAwoHHAkCo4E+j4ER0p2nJXDKtiZ/7Dzf90Eu2+z8tIKOSvmC1ploB10FQqa1zUgCAQoHHAkCo4E+jwQT4ogl0q/hddTV5B3m31OKZfvjlnaAvVLfVClNrzH0MAIAgwWMBIFTwpxFwqLK0aHa6VZ+j2pnZ8++kfthQNPfM+7bV5ffZHChbOljcRwIACAY8FgBCBX8aEbZGxwd58TlbsJ724UKVWl9qhfnPYHRVl0TcxwMAyBU8FgBCBX8aAbYg3s6fWGtOnYq+0PQsaR+mKFJrbPJ0/Qsb8Er1FiPtASBP8FgACBX8aUQcOhXd4y8faNTp3NPvpX6Aokm1PX4qmQkV/J9cOus+MgBAVxyNGivz9caVo9HyPe6unsFjASBU8KcRoQnE7ehOs0OH73/R7OBy6o4XVfNRo62gXpdL3EcHADgQJdwtP6k3rh2Llo+7h7oCjwWAUMGfRoSmUPE7odWAtGNpO1wG6fJIK+ALtWvUHAJANyQT7oRuzEUfHbjUMB4LAKGCP42IeKUgV6vzxBupO1g2qZi+VdOzULvuQgEA0JEOCbfVfH311rFoNfUyJR6LxwKECv40In+aOrVUd29YuBGog0qTpe8U0tfWXUgAAFI5Gq3W07xkl27reW4TPBaPBQgW/GlE/mTnV3T1OkUfhdqvNHpVrTrFIPh5GgGgL1TysVu2t7pHqW47zUfSNF9f3Zh++KXfxWPxWIAQIQcckT9Nno7utiM1zZuoXidtR8ZFuoSiOEg6AF2IACAApqPlmWSiPB81LraS4PrqutGNXUr7ne9+zo1kIt2tuk249by5c6+fxWNjeY+dfvBCc7668rG5b+/3kZCJ3/W0+KdJZTzJ48MdNgCwD+SAOxpqDqj15f20L9MPfjV1B8ZNM4++6gJe3da0OC5UAJAxX4qW7/TJkZIlnziZJOuK+S36pGvL/zbd/8mEbL21jUm+k8mW5N5mKHRRUmIHUOKxeyWPnTrzXPPw/V/5bPrcWy/s/t6SOhp9tOi/44Nkk/P246P1nvP11e3E/UaNq+3br9aT76vGnfuqAUoL/rRXw8kBT0R3TlSqN/XCmpPwaG0l9c3HUTtLgVY3WbgBoHc0P3WcMJnEVAlNogfaJT+21CJx32Wf/MxHq+dDT3w6Jdzmc9xSkmifhMd21Kg9du/VkdXzO8m2jk+TgLtjUfLHqFPbMZps3KnR6N4CoFjgTx2VuT/5qV80ofl89cPUNx1XaRoczT0ZB5xR9QBJTDJ9V1vS0l7Ood/QTk+0S2j85f5fi5ZL0YDdnXCr8bB7ZhI8trOK5LE+uU4m6Yne9Nv286ihZW7vJOVxo1G/FfcyAEGBP3VWpv6kjN0XyJdl9aDMZVp75kCMR62yUhqMEb7Uo1Xm4RJql1S0kgt7v01APlosUzLdDT7hNrHY1P/u7hZ4bBcqkcd2aoT634yREnPdXjOPXxq33wuEBf7UhbLyJ782/rgXyB+k1qToleotFzqA0qATftwL17hkjnffS63eadtDbZIDeus6oEaGSgs6lRTgsd1pXDzWJ+THosYFl5C3NWD94NA4YV9m7BAMFfypOw3sT/H6+HZi89It15m17GWFnTX3mcYKCok/2dsTer1xzZzgb9rjO3GiVy+tnkNN6uDgsd0Lj21v+Jrf45XE79P8jQd36nEGckIW4E/da2B/UqaujY88/lrqG6B2aQJ4xUvF8yxLDKFzLFo+ruTZnKzXzPHre6xvK9GOE2vN+kAP2jDBY3sTHpvOXLR8ty/rUsPY/KY3jTZcEm7LUtxTAboGf+pNffuT6lC0oS2SN5l72oujvdJ0OYqblj11oQTIHZ2QXS3xuu8VM7KlICp3oMd69OCx/QmP7Q5drVIS7hvU5u+2fvvxb96Wo1D2BR3Bn/pT7/5kMnOTodv5FmfPvZX6oihdc8+871s425q30kUUYGT4ac18b5c5LrfMSVYlIVfiulB6rXMHj+1beGz/6LdvPaDeuGo8YSNW7AtqlLunwbiDP/Wtnv1J9SfawM63mPKCaH9pcIENeGXI6+wDGNQzbQfm1VfXjNR7bRLsuN6anuswwWMHEx6bDaoJd2Vll3cScA2AdvPDw1iCPw2mnvzJ1+2oHiXtxdD+0uACG2zTwqHOEIZBMsE22rZ1m3b5cnqviwAeO5jw2OGgXm7rI60SFI3nWK0zCHO8wJ8GU9f+1BqVeubZ1BcKWbVv/mVTfOe7P0x9fJTydTwm4BdcaAH6Rr3UcT2mXco8XiwmalzSwEf3FCgIRfbYkITHDhcl2bbWOy4/2bZ/zW2umJUbcsBs1JU/TVRql/UkrRGf9iIhS8H+xWefN//q2x+nPj5K+dGqWg7VhRagJ3RiS57w1IvtarCpWy0wRfNYfxL783+6lfp4XsJjR0dctqbSEz8mxDT8uZpWSsgBs9HB/hQXym/rSfMs3zmQNKrXtBDjlYdORwxGga6xl3VVR9mqxeaSbmkooMeGmnDjsfmgBn88IFtTDzauM+VgiSAHzEwH+tNEJbpXDx5efC71BVBvmn7opbiFM6aLNEBvxL3ZtnZSc+iusZxz+Siix4aacEt4bH7EZW6NC8arNNDyFuVtxYccMFvt608TleqKHgxlCc+k0f/O+3/S/OSHP7a3xY9+9j/NpT/8i47PT96fl2bPvemCXbvmQgywB/UQ6YRldFO92dRIlpcQPDYrX60s/6m9fPvvP9lq/ubL32h7bFTCY8NAnQXGv9RRcJmrccWFHDBb7etP5oEbejCUkak+eD/4r59ZY//uf/60+fcf/1vzW598397/6ee/bP7WG3+05/mhBFuXZOJgV7dciAFaxKUjtibyNtNwjQcheGwWvuqT7d3PHbXw2HCwgyzrdrn5Teq7i0kI/pRUqXNAX7tztLaSuvGo5YP3y1/9ak9L5hvXvmUf+/Dq3+15fijBlnRpRjHVyF8XZgBfPrKlS7LuLhgDQvDYQX31S19Za/73//6fPdmd/YM/az0vL+GxYeHm9d6kJK54kANmr47+pDunFp9P3SgP7Re8tMdCDPb0wy/HLZyTS+ddmGHMcZdfN+gFGi80cCYEjx3EV5Vs/+uPfpJ6AsxLeGx4uKR7g/K44hCKPyU1iFcln5unOvqT7lSRd9pGeagMwZ557KINtmk5XnJhhjFGSbZ6f1hGefyYPLl0NgSP7ddXNdXWP3//P4JKtiU8NkyMz91kBpPiEIo/JdWvVxUiB9SdIc29WIZgz557ywW7dsWFGcaYePGIBjMqjCEaqR6Cx/brq6qjFHnXbe8WHhsmWpjLfD8svV8QQvGnpPr1qkLkgLrzyBNvpG6Uh8oQ7Lln3rfBZnEGEOaYuK15bN1NGCP8ghJ5e+wgvur/z3Nmkt3CY8PErSew4W5C4ITiT0kN4lXJ5+apjv6kO+eeejd1ozxUhmD7UaqTC1WMZ8yxC0bUV5lNYUzR1FAheOygvuoHK4WwfLKEx4aLEu5j0epZdxMCJhR/SmpQrwpBHf2JYGcvTgbgcUu0r7mbMGYYH7BTbhU94Zb+5juf2Pv+8V++17ovL+Gx4eLHrDDtafiE4k9JZeFVeWvfhFsPpm2Uh8oQbCkOdq3pwgxjiDkO1jWIiFH748tEpXo7BI/Nwld//YXftwMod9+fl/DYcFGybb4jpkANnFD8KaksvCoEpfoTwR6OUoMNY4HKSObrjWtKtlmBbbxRD0cIHpuVryaT7uRcuHkIjw0bV899U2KGpjAJxZ+Sysqr8laqP4UW7LIoNdhQatSTfTRqrOhyqtEaPdtgTmibeOxwhMcWA83QZL6vLa1IqXITdzcEQBn8iYQbcTIYI+JEO15pTT3brLYGnhB7kMoiPLY46ErfTmdE4zpzdYdBGfypcAn33NPvpW6A+tN8ddkFu7rpwgwlRIm1OYFcNt+5em84icAejA/Eg5Lw2EyFxxYTdU6ortv45oakJJwOivwosj/99rt/3Pzm3367+YvPPg9uYa6O/mSDHdAI1TJIrUUXbEbQlwydMOJl2hvX496a1TVOGNAJ4wPX8djshccWHzebyWXnozeViGv8i3sYRkCR/cn3bCvZ/r2//ofU5+Sljv6kO7UqTtpGqD/NL30QB7tSveXCDAUmvhy6WndT/G2rbES3qdGGgzA+cAWPzV54bLnQvN3yV/PdbhmPvWVXrKTee+jgT8NRR3/SnUcefy11I9SfZp982wZbk8q7MEPBUK91fOnTzjaybU8GJslm1hHohcmF6iU8NnvhseXlWLR83HzH60a3Xe/3ZV1VpPc7e/Cn4aijP+nO6YdfTt0I9acjX349DnalxoInBUEJdjzwsXHFGLytL7T/G6OnJxv6ZeLk0nk8NnvhseOBHSdjZzmxVxc3zXdvknDNdrJap5RvcPCn4aijP+nOw/e/mLoR6k8zj7xig21aj0z6HyixkasW2w56tD0pvhcbI4esOHQqugePzV547HiS7Bgxx4HrAVeJX2NFg9bpHOkN/Gk46uhP9s7T9aZpRaZuiHrX4ftesMGeWoiOuzBDjsiEZcbxtFTxYEfzPdmeEpWNsCgDDIvpE9EMHpu98FgQ8fiajxa9t5tjY8vIert6xknC9wd/Go46+pOKuvUAo+gzUm3Ft2y27zgR8UMfMTJgl1xfsqarAThu2j6ZssyZOmwYJXhsxsJjYR8SVy/XzPFyI+4FX93Q/zYxj+vBSz8gU3HoZqpa/Clj7edPk5Xauh6ceexi+saoJ/lieaMbLsQwJNQzbUe37/Rcq/ZavdctY6X3GvIGj81WeCz0SkpHzE0dS+avOmTc+SLuES/L4Ez7WexnVMlN5wYG/pSt9vWnyZNLZ/Xg4QcupG6MetPM2a/bYE9UqisuxDAgGrUe90rYxFqzhiTMUnXXjUsyF3quIUTw2GyFx0JW+F5gJdvmfGJ7xI1u6zjTeWbnymh8jtG5yG0aPLbUJvG7UUMjbXwS/pSt9vUnX8MzdSqihicDTS0+74IdsepgD6gFvtv4zF/1WG/H/2tkelwSQq81FAk8NlvhsTAKdJ7x5yTf2WOOP1ui4o5FJee2d9w+bq+ofnSv5F4iVzS41O3nbq0ne/Hxp2x1oD+ZB+1qQ0eeeCP1BVB30vKoiuMkyw3vwZtXvJqYMah4kQMZlhY68Em17U2IBzLSYw3lAY/NRngshMKec5o9r8VJuDqLdLy6v3FiLvnnGSmR9wl6rGw7kvZJuLVf29oHf47Fn7JRV/7UuqTA1DADyU8FM25zw/rLcr6e2mrHZDRqXPFpMxxvMu4lAEoNHpuNxtVjobioDMWf71rnx/gcqcV9Wsm4T9ITUmlL63Gj9eT2/jU7yb1H8vXStGWed2n6VP0J/GlwdedPJ6I7lZHriXPPvJ/6Qmh/6VLM5On6F4rh9Jmo0PM4+2n0pF1JdJtBGLUn0y1DWK3HP3iW5gWw4LEDq0weC3AQvgfdS4mxPxeb5NzXm3eUeY4vfTlQ5rf146nF53+KP/WvnvypNVL1ka+lvhjaX35lIaPrLqRBkPzR+vlKW9op69CP0w5ElOzlptb9rUEjbZfASKYBegOPHUyheixAiOh8nfY7Skrnej+YEn8aTD3506ET0V2TC9VtbUALpzfNV5ebU2eetS2bbgby7G65diOT8LZat60EWMmwS4y9XLKc3L/WZalk8my3TwzyKNLoa4Aigsf2r149FmDcsef5lN+S5PKEtsGT+FP/6sufVHeiDZgeZujaXZt1oMwPZC2ZLMfSjB3tiTmragGECx7bn1pTbS3UrrlQAsA+dEi4VbPdGiy5G/ypP/XnT4k6Q03enfbCqF3zSx9oOh3TsqluHzoVUWYBAJ3BY3sWHgvQO8mEe16rbUaNiwd2yOFPPWsgf5pYqF60LZz7XmBOxi40/dBLcd1OpbbuQggA0BE8tjfhsQC9o4TbJNobmsSglyvf+FNvGtif/Nr6KgJPewMUKzHn4rbqn1z4AAD2BY/tTngsQH+krSrZLfhTd8rEn/ycsSoCP1pbSX0jtGpbgIqTWoQudAAAB4LHdic8FmD04E/dKTN/Mi9iVx6afvCrqW807vJF8qp3Ut2TCxsAQFfgsfsLjwXID/xpf2XqT5Ono7tN1v5zvaBWz0l7w3GVlj+NA11rHqosLbqQAQB0DR7bWXgsQL7gT501FH/SC01Wqp/qRanliTV7/h03IpXLnAAwGHjsXuGxAGGAP+3VUP1pcqF6QS8s6Y3SdmBcpOlf/NKdjJgHgCzAY3eExwKEBf60o5H4k58M3WT147sCUW2leXjxOX8ZgaWFASAz8FgjPBYgSPAno1H6k1bQ0RvpDbWMZeoOlVSai/Lw/S/Gga5Ub02fiFJXaQIA6Bc8Fo8FCBX8aZT+pBWI3NyMdkL06oepO1Y6mVaNRunaQC9UN6fPRH3PbQkA0BE8Fo8FCBX8abT+pIm9JyrV2/aNT9e/mHvq3fQdLInskp2Lz9tATyxUt1hWGACGCR6LxwKECv40Yn9SV7q/tCCVdeTq7JNvJ4rjq7fodQGAUYDHAkCo4E85YFo5Kz7gWkte3e5pO11E7UxobnWVRRcAYNTgsQAQKvjTiJmoRPeqm107pW53db+n7XxhZA6Yww9ccEGubms6HPdRAQBGDh4LAKGCP40YdbP7QnpNGaOWQdFaOhqBqssiU2ee9YHenFqIjruPCACQG3gsAIQK/jRqTkR3TlRql+MdNTpdb848drEQQZ8992YiyFY3NDDAfTIAgPzBYwEgVPCn0aMRnNpZv+P6EGo1qPWQ9kHz1Oy5t5KTmNui+MmTS2fdRwEACA48FgBCBX/KAVvXU6neTAZdrYi0Dz1qaeSp5pBsBXmhujFxcum823UAgODBYwEgVPCnHFBrwdf2WOkywyOvNOeefi81EMOSCvlnHn21vTWzUN00YsAOABQWPBYAQgV/yoGpU0t109qJJ0t30gdXAGbPvzOUOh9NyK4aovaWTBzkiYXqRaahAoCygMcCQKjgTzmg+p64sF4ti2QA4qVC1fJRgBSobpcN1Zr+er7qhDQ6trXefZs0vUvtyqHK0qLbFQCA0oHHAkCo4E85oQ9uWjyaOL1VYJ+lbP1QpbZui+DpaQGAMQOPBYBQwZ9yRHMemlbIBf8FmL9tlx86q7ph/prn19Z0mUDF+gQXAKAdPBYAQgV/AgAAAAAAAAAAAAAIkzvu+H90XSAeEoVWfgAAAABJRU5ErkJggg== 1.5x&quot; style=&quot;-webkit-tap-highlight-color: transparent; -webkit-user-drag: none; border: none; height: auto; margin: 0px; padding: 0px; text-wrap: nowrap !important; user-select: text; vertical-align: baseline; width: auto;&quot; unselectable=&quot;on&quot; /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;TextRun EmptyTextRun SCXW243703675 BCX0&quot; data-contrast=&quot;auto&quot; lang=&quot;EN-US&quot; style=&quot;-webkit-tap-highlight-color: transparent; -webkit-user-drag: none; background-color: white; font-family: Aptos, Aptos_EmbeddedFont, Aptos_MSFontService, sans-serif; font-size: 12pt; font-variant-ligatures: none !important; line-height: 20.925px; margin: 0px; padding: 0px; user-select: text; white-space-collapse: preserve;&quot; xml:lang=&quot;EN-US&quot;&gt;&lt;/span&gt;&lt;span class=&quot;EOP SCXW243703675 BCX0&quot; data-ccp-props=&quot;{&amp;quot;201341983&amp;quot;:0,&amp;quot;335559739&amp;quot;:160,&amp;quot;335559740&amp;quot;:279}&quot; style=&quot;-webkit-tap-highlight-color: transparent; -webkit-user-drag: none; background-color: white; font-family: Aptos, Aptos_EmbeddedFont, Aptos_MSFontService, sans-serif; font-size: 12pt; line-height: 20.925px; margin: 0px; padding: 0px; user-select: text; white-space-collapse: preserve;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;That means, we can say for every intermediate node k:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style=&quot;text-align: center;&quot;&gt;&lt;i&gt;shortestPathMatrix[i][j] = MIN (shortestPathMatrix[i][k] + shortestPathMatrix[k][j], shortestPathMatrix[i][j]&lt;/i&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;So the steps are now simple:&lt;/div&gt;&lt;div&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;Initialize shortestPathMatrix to Graph.&lt;/li&gt;&lt;li&gt;FOR k = 0 TO n:&lt;/li&gt;&lt;ul&gt;&lt;li&gt;FOR i = 0 TO n:&lt;/li&gt;&lt;ul&gt;&lt;li&gt;FOR j = 0 TO n:&lt;/li&gt;&lt;ul&gt;&lt;li&gt;shortestPathMatrix[i][j] = MIN (shortestPathMatrix[i][k] + shortestPathMatrix[k][j], shortestPathMatrix[i][j])&lt;/li&gt;&lt;/ul&gt;&lt;/ul&gt;&lt;/ul&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div&gt;&amp;nbsp;&lt;/div&gt;&lt;div&gt;That&#39;s all!&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;Implementation in C#:&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;class Graph&lt;/div&gt;&lt;div&gt;{&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; public Graph(int[,] adjMat)&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; {&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; this.adjacencyMatrix = adjMat;&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; }&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; public int[,] FloydWarshall()&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; {&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; int n = this.adjacencyMatrix?.GetLength(0) ?? 0;&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; if (n == 0)&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; {&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; return null;&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; int[,] dist = this.InitDistance();&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; for (int k = 0; k &amp;lt; n; ++k)&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; {&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; for (int i = 0; i &amp;lt; n; ++i)&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; {&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; for (int j = 0; j &amp;lt; n; ++j)&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; {&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; if (dist[i, k] + dist[k, j] &amp;lt; dist[i, j])&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; {&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; dist[i, j] = dist[i, k] + dist[k, j];&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; return dist;&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; }&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; private int[,] InitDistance()&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; {&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; int n = this.adjacencyMatrix.GetLength(0);&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; int[,] dist = new int[n, n];&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; Console.WriteLine(n);&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; for (int i = 0; i &amp;lt; n; ++i)&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; {&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; for (int j = 0; j &amp;lt; n; ++j)&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; {&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; dist[i, j] = this.adjacencyMatrix[i, j] &amp;gt;= 0 ?&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;this.adjacencyMatrix[i, j] :&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;Graph.INF;&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; return dist;&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; }&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; private int[,] adjacencyMatrix;&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; private const int INF = 9999;&lt;/div&gt;&lt;div&gt;}&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;Complexity:&lt;/b&gt; O(n^3)&lt;/div&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://algods-cracker.blogspot.com/feeds/6170480625353416711/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://algods-cracker.blogspot.com/2024/07/floyd-warshall-algorithm.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7496974970329409400/posts/default/6170480625353416711'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7496974970329409400/posts/default/6170480625353416711'/><link rel='alternate' type='text/html' href='http://algods-cracker.blogspot.com/2024/07/floyd-warshall-algorithm.html' title='Floyd Warshall Algorithm'/><author><name>Nishant Saxena</name><uri>http://www.blogger.com/profile/17860524009847591950</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjOdjS62BAEI1iMG_zd6lew4qyFGpfJhWHp0AJWQhiJvxQpSGg0AFZ5euJG7tK0D-EGQFno32hF-i1x4E2A49re_8-b9r0QHwXQ-9X_EvlAcekIjUYMaA1v6dWzDqzkBg/s220/2d230a1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7496974970329409400.post-5005854932970688321</id><published>2024-07-26T20:16:00.004+05:30</published><updated>2024-07-26T20:16:52.361+05:30</updated><category scheme="http://www.blogger.com/atom/ns#" term="Binary Tree"/><category scheme="http://www.blogger.com/atom/ns#" term="GeeksForGeeks"/><category scheme="http://www.blogger.com/atom/ns#" term="Microsoft"/><title type='text'>[Microsoft][GFG] Tree Boundary Traversal in anticlockwise direction</title><content type='html'>&lt;p&gt;&lt;b&gt;Problem:&lt;/b&gt; Given a Binary Tree, find its Boundary Traversal. The traversal should be in the following order:&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;&lt;b&gt;Left boundary nodes:&lt;/b&gt; defined as the path from the root to the left-most node ie- the leaf node you could reach when you always travel preferring the left subtree over the right subtree.&amp;nbsp;&lt;/li&gt;&lt;li&gt;&lt;b&gt;Leaf nodes:&lt;/b&gt; All the leaf nodes except for the ones that are part of left or right boundary.&lt;/li&gt;&lt;li&gt;&lt;b&gt;Reverse right boundary nodes:&lt;/b&gt; defined as the path from the right-most node to the root. The right-most node is the leaf node you could reach when you always travel preferring the right subtree over the left subtree. Exclude the root from this as it was already included in the traversal of left boundary nodes.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;Note:&lt;/b&gt; If the root doesn&#39;t have a left subtree or right subtree, then the root itself is the left or right boundary.&amp;nbsp;&lt;/p&gt;&lt;p&gt;Example:&lt;/p&gt;&lt;pre style=&quot;background-color: rgb(245, 245, 245) !important; border-radius: 4px; border: 1px solid var(--card-border); box-sizing: border-box; color: #1e2229; font-family: var(--gfg-font-primary) !important; font-size: 15px !important; line-height: 1.7em; padding: 10px; white-space: break-spaces; word-spacing: 4px;&quot;&gt;&lt;span style=&quot;background-color: unset !important; box-sizing: border-box; color: var(--text-color) !important; font-family: var(--gfg-font-secondary) !important; font-weight: bolder; line-height: 1.7em;&quot;&gt;&lt;span style=&quot;background-color: unset !important; box-sizing: border-box; color: var(--text-color) !important; font-family: var(--gfg-font-primary) !important; font-size: 18px; line-height: 1.7em;&quot;&gt;Input:
        &lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;background-color: unset !important; box-sizing: border-box; color: var(--text-color) !important; font-family: var(--gfg-font-primary) !important; font-size: 18px; line-height: 1.7em;&quot;&gt;1 
&amp;nbsp;     /   \
&amp;nbsp;    2     3&lt;/span&gt;&lt;span style=&quot;background-color: unset !important; box-sizing: border-box; color: var(--text-color) !important; font-family: var(--gfg-font-secondary) !important; font-weight: bolder; line-height: 1.7em;&quot;&gt;&lt;span style=&quot;background-color: unset !important; box-sizing: border-box; color: var(--text-color) !important; font-family: var(--gfg-font-primary) !important; font-size: 18px; line-height: 1.7em;&quot;&gt;&amp;nbsp; 
&amp;nbsp;   &lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;background-color: unset !important; box-sizing: border-box; color: var(--text-color) !important; font-family: var(--gfg-font-primary) !important; font-size: 18px; line-height: 1.7em;&quot;&gt;/ \   / \ 
&amp;nbsp;  4   5 6   7
&amp;nbsp;     / \
&amp;nbsp;    8   9&lt;/span&gt;&lt;span style=&quot;background-color: unset !important; box-sizing: border-box; color: var(--text-color) !important; font-family: var(--gfg-font-secondary) !important; font-weight: bolder; line-height: 1.7em;&quot;&gt;&lt;span style=&quot;background-color: unset !important; box-sizing: border-box; color: var(--text-color) !important; font-family: var(--gfg-font-primary) !important; font-size: 18px; line-height: 1.7em;&quot;&gt;
   
Output: &lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;background-color: unset !important; box-sizing: border-box; color: var(--text-color) !important; font-family: var(--gfg-font-primary) !important; font-size: 18px; line-height: 1.7em;&quot;&gt;1 2 4 8 9 6 7 3&lt;/span&gt;&lt;span style=&quot;background-color: unset !important; box-sizing: border-box; color: var(--text-color) !important; font-family: var(--gfg-font-secondary) !important; font-weight: bolder; line-height: 1.7em;&quot;&gt;&lt;span style=&quot;background-color: unset !important; box-sizing: border-box; color: var(--text-color) !important; font-family: var(--gfg-font-primary) !important; font-size: 18px; line-height: 1.7em;&quot;&gt;
Explanation:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;background-color: unset !important; box-sizing: border-box; color: var(--text-color) !important; font-family: var(--gfg-font-primary) !important; font-size: 18px; line-height: 1.7em;&quot;&gt;&lt;span style=&quot;background-color: unset !important; box-sizing: border-box; color: var(--text-color) !important; font-family: var(--gfg-font-secondary) !important; font-size: 15px !important; font-weight: bolder; line-height: 1.7em;&quot;&gt;&lt;img alt=&quot;&quot; src=&quot;https://media.geeksforgeeks.org/wp-content/uploads/20211103204119/graph4-300x300.png&quot; style=&quot;background-color: unset !important; border-style: none; box-sizing: border-box; color: var(--text-color) !important; font-family: var(--gfg-font-primary) !important; height: 300px; line-height: 1.7em; max-width: 100%; width: 300px;&quot; /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre style=&quot;background-color: rgb(245, 245, 245) !important; border-radius: 4px; border: 1px solid var(--card-border); box-sizing: border-box; color: #1e2229; font-family: var(--gfg-font-primary) !important; font-size: 15px !important; line-height: 1.7em; padding: 10px; white-space: break-spaces; word-spacing: 4px;&quot;&gt;&lt;span style=&quot;background-color: unset !important; box-sizing: border-box; color: var(--text-color) !important; font-family: var(--gfg-font-secondary) !important; font-weight: bolder; line-height: 1.7em;&quot;&gt;&lt;span style=&quot;background-color: unset !important; box-sizing: border-box; color: var(--text-color) !important; font-family: var(--gfg-font-primary) !important; font-size: 18px; line-height: 1.7em;&quot;&gt;Input:&lt;/span&gt;&lt;/span&gt;
&lt;span style=&quot;background-color: unset !important; box-sizing: border-box; color: var(--text-color) !important; font-family: var(--gfg-font-primary) !important; font-size: 18px; line-height: 1.7em;&quot;&gt;            1
           /
          2
        /  \
       4    9
     /  \    \
    6    5    3
             /  \
            7     8
&lt;/span&gt;&lt;span style=&quot;background-color: unset !important; box-sizing: border-box; color: var(--text-color) !important; font-family: var(--gfg-font-secondary) !important; font-weight: bolder; line-height: 1.7em;&quot;&gt;&lt;span style=&quot;background-color: unset !important; box-sizing: border-box; color: var(--text-color) !important; font-family: var(--gfg-font-primary) !important; font-size: 18px; line-height: 1.7em;&quot;&gt;
Output: &lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;background-color: unset !important; box-sizing: border-box; color: var(--text-color) !important; font-family: var(--gfg-font-primary) !important; font-size: 18px; line-height: 1.7em;&quot;&gt;1 2 4 6 5 7 8
&lt;span style=&quot;background-color: unset !important; box-sizing: border-box; color: var(--text-color) !important; font-family: var(--gfg-font-secondary) !important; font-size: 15px !important; font-weight: bolder; line-height: 1.7em;&quot;&gt;Explanation:
&lt;/span&gt;&lt;a href=&quot;https://contribute.geeksforgeeks.org/wp-content/uploads/boundary.png&quot; style=&quot;background-color: unset !important; box-sizing: border-box; color: rgb(65, 131, 196) !important; font-family: var(--gfg-font-primary) !important; font-size: 15px !important; line-height: 1.7em;&quot;&gt;&lt;img alt=&quot;&quot; src=&quot;https://media.geeksforgeeks.org/wp-content/uploads/20211103204646/graph1-300x300.png&quot; style=&quot;background-color: unset !important; border-style: none; box-sizing: border-box; color: var(--text-color) !important; float: left; font-family: var(--gfg-font-primary) !important; height: 300px; line-height: 1.7em; max-width: 100%; width: 300px;&quot; /&gt;&lt;/a&gt;
&lt;/span&gt;











&lt;span style=&quot;background-color: unset !important; box-sizing: border-box; color: var(--text-color) !important; font-family: var(--gfg-font-primary) !important; font-size: 18px; line-height: 1.7em;&quot;&gt;As you can see we have not taken the right subtree.&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;Approach:&lt;/b&gt; We can solve this problem in four steps given the nature of the problem:&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;ol style=&quot;text-align: left;&quot;&gt;&lt;li&gt;Add root to result.&lt;/li&gt;&lt;li&gt;Preorder traversal of left subtree. If left child is available then do not go for right child. Ignore the leaves.&lt;/li&gt;&lt;li&gt;Inorder traversal of leaves if root is not leaf.&lt;/li&gt;&lt;li&gt;Postorder traversal of right subtre. If right child is available then do not go for left child. Ignore the leaves.&lt;/li&gt;&lt;/ol&gt;&lt;div&gt;That&#39;s all!&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;Implementation in C#:&lt;/b&gt;&lt;/p&gt;&lt;p&gt;class BinaryTreeNode&lt;/p&gt;&lt;p&gt;{&lt;/p&gt;&lt;p&gt;&amp;nbsp; &amp;nbsp; public BinaryTreeNode Left {get; set;}&lt;/p&gt;&lt;p&gt;&amp;nbsp; &amp;nbsp; public BinaryTreeNode Right {get; set;}&lt;/p&gt;&lt;p&gt;&amp;nbsp; &amp;nbsp; public int Value {get; set;}&lt;/p&gt;&lt;p&gt;&amp;nbsp; &amp;nbsp; public BinaryTreeNode(int val,&lt;/p&gt;&lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;BinaryTreeNode left = null,&lt;/p&gt;&lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;BinaryTreeNode right = null)&lt;/p&gt;&lt;p&gt;&amp;nbsp; &amp;nbsp; {&lt;/p&gt;&lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; this.Left = left;&lt;/p&gt;&lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; this.Right = right;&lt;/p&gt;&lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; this.Value = val;&lt;/p&gt;&lt;p&gt;&amp;nbsp; &amp;nbsp; }&lt;/p&gt;&lt;p&gt;}&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;class BinaryTree&lt;/p&gt;&lt;p&gt;{&lt;/p&gt;&lt;p&gt;&amp;nbsp; &amp;nbsp; public List&amp;lt;int&amp;gt; BoundaryTraversal()&lt;/p&gt;&lt;p&gt;&amp;nbsp; &amp;nbsp; {&lt;/p&gt;&lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; List&amp;lt;int&amp;gt; result = new List&amp;lt;int&amp;gt;();&lt;/p&gt;&lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; if (this.Root == null)&lt;/p&gt;&lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; {&lt;/p&gt;&lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; return result;&lt;/p&gt;&lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;/p&gt;&lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; result.Add(this.Root.Value);&lt;/p&gt;&lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; this.TraverseLeftBoundary(this.Root.Left, result);&lt;/p&gt;&lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; // Avoid leaf traversing if root itself is leaf&lt;/p&gt;&lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; if (this.Root.Left != null || this.Root.Right != null)&lt;/p&gt;&lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; {&lt;/p&gt;&lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; this.TraverseLeaves(this.Root, result);&lt;/p&gt;&lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;/p&gt;&lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; this.TraverseRightBoundary(this.Root.Right, result);&lt;/p&gt;&lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; return result;&lt;/p&gt;&lt;p&gt;&amp;nbsp; &amp;nbsp; }&lt;/p&gt;&lt;p&gt;&amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&amp;nbsp; &amp;nbsp; private void TraverseLeftBoundary(BinaryTreeNode node,&lt;/p&gt;&lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; List&amp;lt;int&amp;gt; result)&lt;/p&gt;&lt;p&gt;&amp;nbsp; &amp;nbsp; {&lt;/p&gt;&lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; if (node == null ||&lt;/p&gt;&lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; (node.Left == null &amp;amp;&amp;amp; node.Right == null))&lt;/p&gt;&lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; {&lt;/p&gt;&lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; return;&lt;/p&gt;&lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;/p&gt;&lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; if (node.Left != null)&lt;/p&gt;&lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; {&lt;/p&gt;&lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; result.Add(node.Value);&lt;/p&gt;&lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; this.TraverseLeftBoundary(node.Left, result);&lt;/p&gt;&lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;/p&gt;&lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; else&lt;/p&gt;&lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; {&lt;/p&gt;&lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; result.Add(node.Value);&lt;/p&gt;&lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; this.TraverseLeftBoundary(node.Right, result);&lt;/p&gt;&lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;/p&gt;&lt;p&gt;&amp;nbsp; &amp;nbsp; }&lt;/p&gt;&lt;p&gt;&amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&amp;nbsp; &amp;nbsp; private void TraverseLeaves(BinaryTreeNode node,&lt;/p&gt;&lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;List&amp;lt;int&amp;gt; result)&lt;/p&gt;&lt;p&gt;&amp;nbsp; &amp;nbsp; {&lt;/p&gt;&lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; if (node == null)&lt;/p&gt;&lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; {&lt;/p&gt;&lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; return;&lt;/p&gt;&lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;/p&gt;&lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; this.TraverseLeaves(node.Left, result);&lt;/p&gt;&lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; if (node.Left == null &amp;amp;&amp;amp; node.Right == null)&lt;/p&gt;&lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; {&lt;/p&gt;&lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; result.Add(node.Value);&lt;/p&gt;&lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;/p&gt;&lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; this.TraverseLeaves(node.Right, result);&lt;/p&gt;&lt;p&gt;&amp;nbsp; &amp;nbsp; }&lt;/p&gt;&lt;p&gt;&amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&amp;nbsp; &amp;nbsp; private void TraverseRightBoundary(BinaryTreeNode node,&lt;/p&gt;&lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; List&amp;lt;int&amp;gt; result)&lt;/p&gt;&lt;p&gt;&amp;nbsp; &amp;nbsp; {&lt;/p&gt;&lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; if (node == null ||&lt;/p&gt;&lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; (node.Left == null &amp;amp;&amp;amp; node.Right == null))&lt;/p&gt;&lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; {&lt;/p&gt;&lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; return;&lt;/p&gt;&lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;/p&gt;&lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; if (node.Right != null)&lt;/p&gt;&lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; {&lt;/p&gt;&lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; this.TraverseRightBoundary(node.Right, result);&lt;/p&gt;&lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; result.Add(node.Value);&lt;/p&gt;&lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;/p&gt;&lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; else&lt;/p&gt;&lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; {&lt;/p&gt;&lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; this.TraverseRightBoundary(node.Left, result);&lt;/p&gt;&lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; result.Add(node.Value);&lt;/p&gt;&lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;/p&gt;&lt;p&gt;&amp;nbsp; &amp;nbsp; }&lt;/p&gt;&lt;p&gt;&amp;nbsp; &amp;nbsp; public BinaryTreeNode Root {get; set;}&lt;/p&gt;&lt;p&gt;}&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;Complexity:&lt;/b&gt; O(n)&lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='http://algods-cracker.blogspot.com/feeds/5005854932970688321/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://algods-cracker.blogspot.com/2024/07/microsoftgfg-tree-boundary-traversal-in.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7496974970329409400/posts/default/5005854932970688321'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7496974970329409400/posts/default/5005854932970688321'/><link rel='alternate' type='text/html' href='http://algods-cracker.blogspot.com/2024/07/microsoftgfg-tree-boundary-traversal-in.html' title='[Microsoft][GFG] Tree Boundary Traversal in anticlockwise direction'/><author><name>Nishant Saxena</name><uri>http://www.blogger.com/profile/17860524009847591950</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjOdjS62BAEI1iMG_zd6lew4qyFGpfJhWHp0AJWQhiJvxQpSGg0AFZ5euJG7tK0D-EGQFno32hF-i1x4E2A49re_8-b9r0QHwXQ-9X_EvlAcekIjUYMaA1v6dWzDqzkBg/s220/2d230a1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7496974970329409400.post-5736157442965441708</id><published>2024-07-26T18:33:00.003+05:30</published><updated>2024-07-26T18:33:14.643+05:30</updated><category scheme="http://www.blogger.com/atom/ns#" term="LeetCode"/><title type='text'>[LeetCode] Longest Continuous Increasing Subsequence</title><content type='html'>&lt;p&gt;&lt;b&gt;Problem:&lt;/b&gt; Given an unsorted array of integers nums, return the length of the longest continuous increasing subsequence (i.e. subarray). The subsequence must be strictly increasing.&lt;/p&gt;&lt;p&gt;A continuous increasing subsequence is defined by two indices l and r (l &amp;lt; r) such that it is [nums[l], nums[l + 1], ..., nums[r - 1], nums[r]] and for each l &amp;lt;= i &amp;lt; r, nums[i] &amp;lt; nums[i + 1].&lt;/p&gt;&lt;p&gt;Example:&lt;/p&gt;&lt;pre style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-translate-x: 0; --tw-translate-y: 0; background-color: #f0f0f0; border-color: var(--border-tertiary); border-image: initial; border-style: solid; border-width: 0px 0px 0px 2px; box-sizing: border-box; color: var(--text-secondary); font-family: Menlo, sans-serif; font-size: 14px; line-height: 1.25rem; margin-bottom: 1rem; margin-top: 1rem; overflow-wrap: break-word; overflow: visible; padding-left: 1rem; text-wrap: wrap;&quot;&gt;&lt;span style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-text-opacity: 1; --tw-translate-x: 0; --tw-translate-y: 0; border-color: hsl(var(--sd-border)); border-image: initial; border-style: solid; border-width: 0px; box-sizing: border-box; color: rgb(38 38 38/var(--tw-text-opacity)); font-weight: 700; overflow-wrap: break-word;&quot;&gt;Input:&lt;/span&gt; nums = [1,3,5,4,7]
&lt;span style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-text-opacity: 1; --tw-translate-x: 0; --tw-translate-y: 0; border-color: hsl(var(--sd-border)); border-image: initial; border-style: solid; border-width: 0px; box-sizing: border-box; color: rgb(38 38 38/var(--tw-text-opacity)); font-weight: 700; overflow-wrap: break-word;&quot;&gt;Output:&lt;/span&gt; 3
&lt;span style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-text-opacity: 1; --tw-translate-x: 0; --tw-translate-y: 0; border-color: hsl(var(--sd-border)); border-image: initial; border-style: solid; border-width: 0px; box-sizing: border-box; color: rgb(38 38 38/var(--tw-text-opacity)); font-weight: 700; overflow-wrap: break-word;&quot;&gt;Explanation:&lt;/span&gt; The longest continuous increasing subsequence is [1,3,5] with length 3.
Even though [1,3,5,7] is an increasing subsequence, it is not continuous as elements 5 and 7 are separated by element 4.&lt;/pre&gt;&lt;pre style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-translate-x: 0; --tw-translate-y: 0; background-color: #f0f0f0; border-color: var(--border-tertiary); border-image: initial; border-style: solid; border-width: 0px 0px 0px 2px; box-sizing: border-box; color: var(--text-secondary); font-family: Menlo, sans-serif; font-size: 14px; line-height: 1.25rem; margin-bottom: 1rem; margin-top: 1rem; overflow-wrap: break-word; overflow: visible; padding-left: 1rem; text-wrap: wrap;&quot;&gt;&lt;span style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-text-opacity: 1; --tw-translate-x: 0; --tw-translate-y: 0; border-color: hsl(var(--sd-border)); border-image: initial; border-style: solid; border-width: 0px; box-sizing: border-box; color: rgb(38 38 38/var(--tw-text-opacity)); font-weight: 700; overflow-wrap: break-word;&quot;&gt;Input:&lt;/span&gt; nums = [2,2,2,2,2]
&lt;span style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-text-opacity: 1; --tw-translate-x: 0; --tw-translate-y: 0; border-color: hsl(var(--sd-border)); border-image: initial; border-style: solid; border-width: 0px; box-sizing: border-box; color: rgb(38 38 38/var(--tw-text-opacity)); font-weight: 700; overflow-wrap: break-word;&quot;&gt;Output:&lt;/span&gt; 1
&lt;span style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-text-opacity: 1; --tw-translate-x: 0; --tw-translate-y: 0; border-color: hsl(var(--sd-border)); border-image: initial; border-style: solid; border-width: 0px; box-sizing: border-box; color: rgb(38 38 38/var(--tw-text-opacity)); font-weight: 700; overflow-wrap: break-word;&quot;&gt;Explanation:&lt;/span&gt; The longest continuous increasing subsequence is [2] with length 1. Note that it must be strictly increasing.&lt;/pre&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;Approach:&lt;/b&gt; It&#39;s a simple implementation problem. You can directly look at the implementation to understand the approach.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;Implementation in C#:&lt;/b&gt;&lt;/p&gt;&lt;div style=&quot;background-color: white; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 13px; line-height: 18px; white-space: pre;&quot;&gt;&lt;div&gt;&lt;span style=&quot;color: blue;&quot;&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;/span&gt;public&lt;/span&gt; &lt;span style=&quot;color: blue;&quot;&gt;int&lt;/span&gt; &lt;span style=&quot;color: #795e26;&quot;&gt;FindLengthOfLCIS&lt;/span&gt;(&lt;span style=&quot;color: blue;&quot;&gt;int&lt;/span&gt;[] &lt;span style=&quot;color: #001080;&quot;&gt;nums&lt;/span&gt;)&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; {&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: blue;&quot;&gt;int&lt;/span&gt; &lt;span style=&quot;color: #001080;&quot;&gt;length&lt;/span&gt; = &lt;span style=&quot;color: #001080;&quot;&gt;nums&lt;/span&gt;?.&lt;span style=&quot;color: #001080;&quot;&gt;Length&lt;/span&gt; ?? &lt;span style=&quot;color: #098658;&quot;&gt;0&lt;/span&gt;;&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #af00db;&quot;&gt;if&lt;/span&gt; (&lt;span style=&quot;color: #001080;&quot;&gt;length&lt;/span&gt; &amp;lt;= &lt;span style=&quot;color: #098658;&quot;&gt;1&lt;/span&gt;)&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; {&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #af00db;&quot;&gt;return&lt;/span&gt; &lt;span style=&quot;color: #001080;&quot;&gt;length&lt;/span&gt;;&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: blue;&quot;&gt;int&lt;/span&gt; &lt;span style=&quot;color: #001080;&quot;&gt;maxCISLength&lt;/span&gt; = &lt;span style=&quot;color: #098658;&quot;&gt;1&lt;/span&gt;;&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: blue;&quot;&gt;int&lt;/span&gt; &lt;span style=&quot;color: #001080;&quot;&gt;currCISLength&lt;/span&gt; = &lt;span style=&quot;color: #098658;&quot;&gt;1&lt;/span&gt;;&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: blue;&quot;&gt;int&lt;/span&gt; &lt;span style=&quot;color: #001080;&quot;&gt;prevIndex&lt;/span&gt; = &lt;span style=&quot;color: #098658;&quot;&gt;0&lt;/span&gt;;&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #af00db;&quot;&gt;for&lt;/span&gt; (&lt;span style=&quot;color: blue;&quot;&gt;int&lt;/span&gt; &lt;span style=&quot;color: #001080;&quot;&gt;i&lt;/span&gt; = &lt;span style=&quot;color: #098658;&quot;&gt;1&lt;/span&gt;; &lt;span style=&quot;color: #001080;&quot;&gt;i&lt;/span&gt; &amp;lt; &lt;span style=&quot;color: #001080;&quot;&gt;length&lt;/span&gt;; ++&lt;span style=&quot;color: #001080;&quot;&gt;i&lt;/span&gt;)&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; {&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #af00db;&quot;&gt;if&lt;/span&gt; (&lt;span style=&quot;color: #001080;&quot;&gt;nums&lt;/span&gt;[&lt;span style=&quot;color: #001080;&quot;&gt;i&lt;/span&gt;] &amp;gt; &lt;span style=&quot;color: #001080;&quot;&gt;nums&lt;/span&gt;[&lt;span style=&quot;color: #001080;&quot;&gt;prevIndex&lt;/span&gt;])&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; {&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ++&lt;span style=&quot;color: #001080;&quot;&gt;currCISLength&lt;/span&gt;;&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #af00db;&quot;&gt;if&lt;/span&gt; (&lt;span style=&quot;color: #001080;&quot;&gt;currCISLength&lt;/span&gt; &amp;gt; &lt;span style=&quot;color: #001080;&quot;&gt;maxCISLength&lt;/span&gt;)&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; {&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #001080;&quot;&gt;maxCISLength&lt;/span&gt; = &lt;span style=&quot;color: #001080;&quot;&gt;currCISLength&lt;/span&gt;;&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #af00db;&quot;&gt;else&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; {&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #001080;&quot;&gt;currCISLength&lt;/span&gt; = &lt;span style=&quot;color: #098658;&quot;&gt;1&lt;/span&gt;;&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #001080;&quot;&gt;prevIndex&lt;/span&gt; = &lt;span style=&quot;color: #001080;&quot;&gt;i&lt;/span&gt;;&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #af00db;&quot;&gt;return&lt;/span&gt; &lt;span style=&quot;color: #001080;&quot;&gt;maxCISLength&lt;/span&gt;;&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; }&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&lt;b&gt;Complexity:&lt;/b&gt; O(n)&lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='http://algods-cracker.blogspot.com/feeds/5736157442965441708/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://algods-cracker.blogspot.com/2024/07/leetcode-longest-continuous-increasing.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7496974970329409400/posts/default/5736157442965441708'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7496974970329409400/posts/default/5736157442965441708'/><link rel='alternate' type='text/html' href='http://algods-cracker.blogspot.com/2024/07/leetcode-longest-continuous-increasing.html' title='[LeetCode] Longest Continuous Increasing Subsequence'/><author><name>Nishant Saxena</name><uri>http://www.blogger.com/profile/17860524009847591950</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjOdjS62BAEI1iMG_zd6lew4qyFGpfJhWHp0AJWQhiJvxQpSGg0AFZ5euJG7tK0D-EGQFno32hF-i1x4E2A49re_8-b9r0QHwXQ-9X_EvlAcekIjUYMaA1v6dWzDqzkBg/s220/2d230a1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7496974970329409400.post-1917508681562853507</id><published>2024-07-24T21:22:00.006+05:30</published><updated>2024-07-24T21:22:46.318+05:30</updated><category scheme="http://www.blogger.com/atom/ns#" term="LeetCode"/><title type='text'>[LeetCode] Shortest Completing Word</title><content type='html'>&lt;p&gt;&lt;b&gt;Problem:&lt;/b&gt; Given a string licensePlate and an array of strings words, find the shortest completing word in words.&lt;/p&gt;&lt;p&gt;A completing word is a word that contains all the letters in licensePlate. Ignore numbers and spaces in licensePlate, and treat letters as case insensitive. If a letter appears more than once in licensePlate, then it must appear in the word the same number of times or more.&lt;/p&gt;&lt;p&gt;For example, if licensePlate = &quot;aBc 12c&quot;, then it contains letters &#39;a&#39;, &#39;b&#39; (ignoring case), and &#39;c&#39; twice. Possible completing words are &quot;abccdef&quot;, &quot;caaacab&quot;, and &quot;cbca&quot;.&lt;/p&gt;&lt;p&gt;Return the shortest completing word in words. It is guaranteed an answer exists. If there are multiple shortest completing words, return the first one that occurs in words.&lt;/p&gt;&lt;p&gt;Example:&lt;/p&gt;&lt;pre style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-translate-x: 0; --tw-translate-y: 0; background-color: #f0f0f0; border-color: var(--border-tertiary); border-image: initial; border-style: solid; border-width: 0px 0px 0px 2px; box-sizing: border-box; color: var(--text-secondary); font-family: Menlo, sans-serif; font-size: 14px; line-height: 1.25rem; margin-bottom: 1rem; margin-top: 1rem; overflow-wrap: break-word; overflow: visible; padding-left: 1rem; text-wrap: wrap;&quot;&gt;&lt;span style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-text-opacity: 1; --tw-translate-x: 0; --tw-translate-y: 0; border-color: hsl(var(--sd-border)); border-image: initial; border-style: solid; border-width: 0px; box-sizing: border-box; color: rgb(38 38 38/var(--tw-text-opacity)); font-weight: 700; overflow-wrap: break-word;&quot;&gt;Input:&lt;/span&gt; licensePlate = &quot;1s3 PSt&quot;, words = [&quot;step&quot;,&quot;steps&quot;,&quot;stripe&quot;,&quot;stepple&quot;]
&lt;span style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-text-opacity: 1; --tw-translate-x: 0; --tw-translate-y: 0; border-color: hsl(var(--sd-border)); border-image: initial; border-style: solid; border-width: 0px; box-sizing: border-box; color: rgb(38 38 38/var(--tw-text-opacity)); font-weight: 700; overflow-wrap: break-word;&quot;&gt;Output:&lt;/span&gt; &quot;steps&quot;
&lt;span style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-text-opacity: 1; --tw-translate-x: 0; --tw-translate-y: 0; border-color: hsl(var(--sd-border)); border-image: initial; border-style: solid; border-width: 0px; box-sizing: border-box; color: rgb(38 38 38/var(--tw-text-opacity)); font-weight: 700; overflow-wrap: break-word;&quot;&gt;Explanation:&lt;/span&gt; licensePlate contains letters &#39;s&#39;, &#39;p&#39;, &#39;s&#39; (ignoring case), and &#39;t&#39;.
&quot;step&quot; contains &#39;t&#39; and &#39;p&#39;, but only contains 1 &#39;s&#39;.
&quot;steps&quot; contains &#39;t&#39;, &#39;p&#39;, and both &#39;s&#39; characters.
&quot;stripe&quot; is missing an &#39;s&#39;.
&quot;stepple&quot; is missing an &#39;s&#39;.
Since &quot;steps&quot; is the only word containing all the letters, that is the answer.&lt;/pre&gt;&lt;pre style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-translate-x: 0; --tw-translate-y: 0; background-color: #f0f0f0; border-color: var(--border-tertiary); border-image: initial; border-style: solid; border-width: 0px 0px 0px 2px; box-sizing: border-box; color: var(--text-secondary); font-family: Menlo, sans-serif; font-size: 14px; line-height: 1.25rem; margin-bottom: 1rem; margin-top: 1rem; overflow-wrap: break-word; overflow: visible; padding-left: 1rem; text-wrap: wrap;&quot;&gt;&lt;span style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-text-opacity: 1; --tw-translate-x: 0; --tw-translate-y: 0; border-color: hsl(var(--sd-border)); border-image: initial; border-style: solid; border-width: 0px; box-sizing: border-box; color: rgb(38 38 38/var(--tw-text-opacity)); font-weight: 700; overflow-wrap: break-word;&quot;&gt;Input:&lt;/span&gt; licensePlate = &quot;1s3 456&quot;, words = [&quot;looks&quot;,&quot;pest&quot;,&quot;stew&quot;,&quot;show&quot;]
&lt;span style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-text-opacity: 1; --tw-translate-x: 0; --tw-translate-y: 0; border-color: hsl(var(--sd-border)); border-image: initial; border-style: solid; border-width: 0px; box-sizing: border-box; color: rgb(38 38 38/var(--tw-text-opacity)); font-weight: 700; overflow-wrap: break-word;&quot;&gt;Output:&lt;/span&gt; &quot;pest&quot;
&lt;span style=&quot;--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: #3b82f680; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 #0000; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-skew-x: 0; --tw-skew-y: 0; --tw-text-opacity: 1; --tw-translate-x: 0; --tw-translate-y: 0; border-color: hsl(var(--sd-border)); border-image: initial; border-style: solid; border-width: 0px; box-sizing: border-box; color: rgb(38 38 38/var(--tw-text-opacity)); font-weight: 700; overflow-wrap: break-word;&quot;&gt;Explanation:&lt;/span&gt; licensePlate only contains the letter &#39;s&#39;. All the words contain &#39;s&#39;, but among these &quot;pest&quot;, &quot;stew&quot;, and &quot;show&quot; are shortest. The answer is &quot;pest&quot; because it is the word that appears earliest of the 3.&lt;/pre&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;Approach:&lt;/b&gt; This is a simple problem to solve. We can easily solve it using using two hash maps. Directly look at the implementation to understand the approach.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;Implementation in C#:&lt;/b&gt;&lt;/p&gt;&lt;div style=&quot;background-color: white; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 13px; line-height: 18px; white-space: pre;&quot;&gt;&lt;div&gt;&lt;span style=&quot;color: blue;&quot;&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;/span&gt;public&lt;/span&gt; &lt;span style=&quot;color: blue;&quot;&gt;string&lt;/span&gt; &lt;span style=&quot;color: #795e26;&quot;&gt;ShortestCompletingWord&lt;/span&gt;(&lt;span style=&quot;color: blue;&quot;&gt;string&lt;/span&gt; &lt;span style=&quot;color: #001080;&quot;&gt;licensePlate&lt;/span&gt;, &lt;span style=&quot;color: blue;&quot;&gt;string&lt;/span&gt;[] &lt;span style=&quot;color: #001080;&quot;&gt;words&lt;/span&gt;)&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; {&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: blue;&quot;&gt;var&lt;/span&gt; &lt;span style=&quot;color: #001080;&quot;&gt;plateCharsMap&lt;/span&gt; = &lt;span style=&quot;color: blue;&quot;&gt;new&lt;/span&gt; &lt;span style=&quot;color: blue;&quot;&gt;int&lt;/span&gt;[&lt;span style=&quot;color: #098658;&quot;&gt;26&lt;/span&gt;];&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #af00db;&quot;&gt;foreach&lt;/span&gt;(&lt;span style=&quot;color: blue;&quot;&gt;char&lt;/span&gt; &lt;span style=&quot;color: #001080;&quot;&gt;ch&lt;/span&gt; &lt;span style=&quot;color: #af00db;&quot;&gt;in&lt;/span&gt; &lt;span style=&quot;color: #001080;&quot;&gt;licensePlate&lt;/span&gt;)&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; {&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #af00db;&quot;&gt;if&lt;/span&gt; (&lt;span style=&quot;color: #001080;&quot;&gt;Char&lt;/span&gt;.&lt;span style=&quot;color: #795e26;&quot;&gt;IsLetter&lt;/span&gt;(&lt;span style=&quot;color: #001080;&quot;&gt;ch&lt;/span&gt;))&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; {&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ++&lt;span style=&quot;color: #001080;&quot;&gt;plateCharsMap&lt;/span&gt;[&lt;span style=&quot;color: #001080;&quot;&gt;Char&lt;/span&gt;.&lt;span style=&quot;color: #795e26;&quot;&gt;ToLower&lt;/span&gt;(&lt;span style=&quot;color: #001080;&quot;&gt;ch&lt;/span&gt;) - &lt;span style=&quot;color: #a31515;&quot;&gt;&#39;a&#39;&lt;/span&gt;];&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: blue;&quot;&gt;string&lt;/span&gt; &lt;span style=&quot;color: #001080;&quot;&gt;result&lt;/span&gt; = &lt;span style=&quot;color: blue;&quot;&gt;null&lt;/span&gt;;&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #af00db;&quot;&gt;foreach&lt;/span&gt; (&lt;span style=&quot;color: blue;&quot;&gt;string&lt;/span&gt; &lt;span style=&quot;color: #001080;&quot;&gt;word&lt;/span&gt; &lt;span style=&quot;color: #af00db;&quot;&gt;in&lt;/span&gt; &lt;span style=&quot;color: #001080;&quot;&gt;words&lt;/span&gt;)&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; {&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: blue;&quot;&gt;int&lt;/span&gt; &lt;span style=&quot;color: #001080;&quot;&gt;length&lt;/span&gt; = &lt;span style=&quot;color: #001080;&quot;&gt;word&lt;/span&gt;.&lt;span style=&quot;color: #001080;&quot;&gt;Length&lt;/span&gt;;&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: blue;&quot;&gt;var&lt;/span&gt; &lt;span style=&quot;color: #001080;&quot;&gt;wordCharMap&lt;/span&gt; = &lt;span style=&quot;color: blue;&quot;&gt;new&lt;/span&gt; &lt;span style=&quot;color: blue;&quot;&gt;int&lt;/span&gt;[&lt;span style=&quot;color: #098658;&quot;&gt;26&lt;/span&gt;];&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #af00db;&quot;&gt;foreach&lt;/span&gt; (&lt;span style=&quot;color: blue;&quot;&gt;char&lt;/span&gt; &lt;span style=&quot;color: #001080;&quot;&gt;ch&lt;/span&gt; &lt;span style=&quot;color: #af00db;&quot;&gt;in&lt;/span&gt; &lt;span style=&quot;color: #001080;&quot;&gt;word&lt;/span&gt;)&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; {&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ++&lt;span style=&quot;color: #001080;&quot;&gt;wordCharMap&lt;/span&gt;[&lt;span style=&quot;color: #001080;&quot;&gt;ch&lt;/span&gt; - &lt;span style=&quot;color: #a31515;&quot;&gt;&#39;a&#39;&lt;/span&gt;];&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #af00db;&quot;&gt;if&lt;/span&gt; (&lt;span style=&quot;color: blue;&quot;&gt;this&lt;/span&gt;.&lt;span style=&quot;color: #795e26;&quot;&gt;IsCompleteWord&lt;/span&gt;(&lt;span style=&quot;color: #001080;&quot;&gt;plateCharsMap&lt;/span&gt;, &lt;span style=&quot;color: #001080;&quot;&gt;wordCharMap&lt;/span&gt;))&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; {&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #af00db;&quot;&gt;if&lt;/span&gt; (&lt;span style=&quot;color: #001080;&quot;&gt;result&lt;/span&gt; == &lt;span style=&quot;color: blue;&quot;&gt;null&lt;/span&gt; || &lt;span style=&quot;color: #001080;&quot;&gt;length&lt;/span&gt; &amp;lt; &lt;span style=&quot;color: #001080;&quot;&gt;result&lt;/span&gt;.&lt;span style=&quot;color: #001080;&quot;&gt;Length&lt;/span&gt;)&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; {&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #001080;&quot;&gt;result&lt;/span&gt; = &lt;span style=&quot;color: #001080;&quot;&gt;word&lt;/span&gt;;&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #af00db;&quot;&gt;return&lt;/span&gt; &lt;span style=&quot;color: #001080;&quot;&gt;result&lt;/span&gt;;&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; }&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: blue;&quot;&gt;private&lt;/span&gt; &lt;span style=&quot;color: blue;&quot;&gt;bool&lt;/span&gt; &lt;span style=&quot;color: #795e26;&quot;&gt;IsCompleteWord&lt;/span&gt;(&lt;span style=&quot;color: blue;&quot;&gt;int&lt;/span&gt;[] &lt;span style=&quot;color: #001080;&quot;&gt;plateCharsMap&lt;/span&gt;, &lt;span style=&quot;color: blue;&quot;&gt;int&lt;/span&gt;[] &lt;span style=&quot;color: #001080;&quot;&gt;wordCharMap&lt;/span&gt;)&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; {&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #af00db;&quot;&gt;for&lt;/span&gt; (&lt;span style=&quot;color: blue;&quot;&gt;int&lt;/span&gt; &lt;span style=&quot;color: #001080;&quot;&gt;i&lt;/span&gt; = &lt;span style=&quot;color: #098658;&quot;&gt;0&lt;/span&gt;; &lt;span style=&quot;color: #001080;&quot;&gt;i&lt;/span&gt; &amp;lt; &lt;span style=&quot;color: #098658;&quot;&gt;26&lt;/span&gt;; ++&lt;span style=&quot;color: #001080;&quot;&gt;i&lt;/span&gt;)&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; {&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #af00db;&quot;&gt;if&lt;/span&gt; (&lt;span style=&quot;color: #001080;&quot;&gt;plateCharsMap&lt;/span&gt;[&lt;span style=&quot;color: #001080;&quot;&gt;i&lt;/span&gt;] &amp;gt; &lt;span style=&quot;color: #001080;&quot;&gt;wordCharMap&lt;/span&gt;[&lt;span style=&quot;color: #001080;&quot;&gt;i&lt;/span&gt;])&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; {&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #af00db;&quot;&gt;return&lt;/span&gt; &lt;span style=&quot;color: blue;&quot;&gt;false&lt;/span&gt;;&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #af00db;&quot;&gt;return&lt;/span&gt; &lt;span style=&quot;color: blue;&quot;&gt;true&lt;/span&gt;;&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; }&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;Complexity:&lt;/b&gt; O(m*n) where m is number of words and n is length of largest word.&lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='http://algods-cracker.blogspot.com/feeds/1917508681562853507/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://algods-cracker.blogspot.com/2024/07/leetcode-shortest-completing-word.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7496974970329409400/posts/default/1917508681562853507'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7496974970329409400/posts/default/1917508681562853507'/><link rel='alternate' type='text/html' href='http://algods-cracker.blogspot.com/2024/07/leetcode-shortest-completing-word.html' title='[LeetCode] Shortest Completing Word'/><author><name>Nishant Saxena</name><uri>http://www.blogger.com/profile/17860524009847591950</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjOdjS62BAEI1iMG_zd6lew4qyFGpfJhWHp0AJWQhiJvxQpSGg0AFZ5euJG7tK0D-EGQFno32hF-i1x4E2A49re_8-b9r0QHwXQ-9X_EvlAcekIjUYMaA1v6dWzDqzkBg/s220/2d230a1.jpg'/></author><thr:total>0</thr:total></entry></feed>