<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>LIS Archives - Huahua&#039;s Tech Road</title>
	<atom:link href="https://zxi.mytechroad.com/blog/tag/lis/feed/" rel="self" type="application/rss+xml" />
	<link>https://zxi.mytechroad.com/blog/tag/lis/</link>
	<description></description>
	<lastBuildDate>Wed, 22 Dec 2021 20:04:42 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.0.8</generator>

<image>
	<url>https://zxi.mytechroad.com/blog/wp-content/uploads/2017/09/cropped-photo-32x32.jpg</url>
	<title>LIS Archives - Huahua&#039;s Tech Road</title>
	<link>https://zxi.mytechroad.com/blog/tag/lis/</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>花花酱 LeetCode 2111. Minimum Operations to Make the Array K-Increasing</title>
		<link>https://zxi.mytechroad.com/blog/algorithms/binary-search/leetcode-2111-minimum-operations-to-make-the-array-k-increasing/</link>
					<comments>https://zxi.mytechroad.com/blog/algorithms/binary-search/leetcode-2111-minimum-operations-to-make-the-array-k-increasing/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Wed, 22 Dec 2021 19:55:14 +0000</pubDate>
				<category><![CDATA[Binary Search]]></category>
		<category><![CDATA[array]]></category>
		<category><![CDATA[binary search]]></category>
		<category><![CDATA[hard]]></category>
		<category><![CDATA[LIS]]></category>
		<guid isPermaLink="false">https://zxi.mytechroad.com/blog/?p=9193</guid>

					<description><![CDATA[<p>You are given a&#160;0-indexed&#160;array&#160;arr&#160;consisting of&#160;n&#160;positive integers, and a positive integer&#160;k. The array&#160;arr&#160;is called&#160;K-increasing&#160;if&#160;arr[i-k] &#60;= arr[i]&#160;holds for every index&#160;i, where&#160;k &#60;= i &#60;= n-1. For example,&#160;arr&#8230;</p>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/algorithms/binary-search/leetcode-2111-minimum-operations-to-make-the-array-k-increasing/">花花酱 LeetCode 2111. Minimum Operations to Make the Array K-Increasing</a> appeared first on <a rel="nofollow" href="https://zxi.mytechroad.com/blog">Huahua&#039;s Tech Road</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>You are given a&nbsp;<strong>0-indexed</strong>&nbsp;array&nbsp;<code>arr</code>&nbsp;consisting of&nbsp;<code>n</code>&nbsp;positive integers, and a positive integer&nbsp;<code>k</code>.</p>



<p>The array&nbsp;<code>arr</code>&nbsp;is called&nbsp;<strong>K-increasing</strong>&nbsp;if&nbsp;<code>arr[i-k] &lt;= arr[i]</code>&nbsp;holds for every index&nbsp;<code>i</code>, where&nbsp;<code>k &lt;= i &lt;= n-1</code>.</p>



<ul><li>For example,&nbsp;<code>arr = [4, 1, 5, 2, 6, 2]</code>&nbsp;is K-increasing for&nbsp;<code>k = 2</code>&nbsp;because:<ul><li><code>arr[0] &lt;= arr[2] (4 &lt;= 5)</code></li><li><code>arr[1] &lt;= arr[3] (1 &lt;= 2)</code></li><li><code>arr[2] &lt;= arr[4] (5 &lt;= 6)</code></li><li><code>arr[3] &lt;= arr[5] (2 &lt;= 2)</code></li></ul></li><li>However, the same&nbsp;<code>arr</code>&nbsp;is not K-increasing for&nbsp;<code>k = 1</code>&nbsp;(because&nbsp;<code>arr[0] &gt; arr[1]</code>) or&nbsp;<code>k = 3</code>&nbsp;(because&nbsp;<code>arr[0] &gt; arr[3]</code>).</li></ul>



<p>In one&nbsp;<strong>operation</strong>, you can choose an index&nbsp;<code>i</code>&nbsp;and&nbsp;<strong>change</strong>&nbsp;<code>arr[i]</code>&nbsp;into&nbsp;<strong>any</strong>&nbsp;positive integer.</p>



<p>Return&nbsp;<em>the&nbsp;<strong>minimum number of operations</strong>&nbsp;required to make the array K-increasing for the given&nbsp;</em><code>k</code>.</p>



<p><strong>Example 1:</strong></p>



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> arr = [5,4,3,2,1], k = 1
<strong>Output:</strong> 4
<strong>Explanation:
</strong>For k = 1, the resultant array has to be non-decreasing.
Some of the K-increasing arrays that can be formed are [5,<strong>6</strong>,<strong>7</strong>,<strong>8</strong>,<strong>9</strong>], [<strong>1</strong>,<strong>1</strong>,<strong>1</strong>,<strong>1</strong>,1], [<strong>2</strong>,<strong>2</strong>,3,<strong>4</strong>,<strong>4</strong>]. All of them require 4 operations.
It is suboptimal to change the array to, for example, [<strong>6</strong>,<strong>7</strong>,<strong>8</strong>,<strong>9</strong>,<strong>10</strong>] because it would take 5 operations.
It can be shown that we cannot make the array K-increasing in less than 4 operations.
</pre>



<p><strong>Example 2:</strong></p>



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> arr = [4,1,5,2,6,2], k = 2
<strong>Output:</strong> 0
<strong>Explanation:</strong>
This is the same example as the one in the problem description.
Here, for every index i where 2 &lt;= i &lt;= 5, arr[i-2] &lt;=arr[i].
Since the given array is already K-increasing, we do not need to perform any operations.</pre>



<p><strong>Example 3:</strong></p>



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> arr = [4,1,5,2,6,2], k = 3
<strong>Output:</strong> 2
<strong>Explanation:</strong>
Indices 3 and 5 are the only ones not satisfying arr[i-3] &lt;= arr[i] for 3 &lt;= i &lt;= 5.
One of the ways we can make the array K-increasing is by changing arr[3] to 4 and arr[5] to 5.
The array will now be [4,1,5,<strong>4</strong>,6,<strong>5</strong>].
Note that there can be other ways to make the array K-increasing, but none of them require less than 2 operations.
</pre>



<p><strong>Constraints:</strong></p>



<ul><li><code>1 &lt;= arr.length &lt;= 10<sup>5</sup></code></li><li><code>1 &lt;= arr[i], k &lt;= arr.length</code></li></ul>



<h2><strong>Solution: Longest increasing subsequence</strong></h2>



<p>if k = 1, <meta charset="utf-8">we need to modify the following arrays<br>1. [a[0], a[1], a[2], &#8230;]<br>if k = 2, <meta charset="utf-8">we need to modify the following arrays<br>1. <meta charset="utf-8">[a[0], a[2], a[4], &#8230;]<br>2. [a[1], a[3], a[5], &#8230;]<br>if k = 3, we need to modify the following arrays<br><meta charset="utf-8">1. <meta charset="utf-8">[a[0], a[3], a[6], &#8230;]<br>2. [a[1], a[4], a[7], &#8230;]<br>3. <meta charset="utf-8">[a[2], a[5], a[8], &#8230;]<br>&#8230;</p>



<p>These arrays are independent of each other, we just need to find LIS of it, # ops = len(arr) &#8211; LIS(arr).<br>Ans = sum(len(arr<sub>i</sub>) &#8211; LIS(arr<sub>i</sub>))  1 &lt;= i &lt;= k</p>



<p>Reference: <a href="https://zxi.mytechroad.com/blog/dynamic-programming/leetcode-300-longest-increasing-subsequence/" data-type="post" data-id="206">花花酱 LeetCode 300. Longest Increasing Subsequence</a></p>



<p>Time complexity: O(k * (n/k)* log(n/k)) = O(n * log(n/k))<br>Space complexity: O(n/k)</p>



<div class="responsive-tabs">
<h2 class="tabtitle">C++</h2>
<div class="tabcontent">

<pre class="crayon-plain-tag">// Author: Huahua
class Solution {
public:
  int kIncreasing(vector&lt;int&gt;&amp; arr, int k) {
    auto LIS = [](const vector&lt;int&gt;&amp; nums) {
      vector&lt;int&gt; lis;
      for (int x : nums)
        if (lis.empty() || lis.back() &lt;= x)
          lis.push_back(x);
        else
          *upper_bound(begin(lis), end(lis), x) = x;
      return lis.size();
    };
    const int n = arr.size();
    int ans = 0;
    for (int i = 0; i &lt; k; ++i) {
      vector&lt;int&gt; cur;
      for (int j = i; j &lt; n; j += k)
        cur.push_back(arr[j]);
      ans += cur.size() - LIS(cur);
    }
    return ans;
  }
};</pre>

</div><h2 class="tabtitle">Python3</h2>
<div class="tabcontent">

<pre class="crayon-plain-tag"># Author: Huahua
class Solution:
  def kIncreasing(self, arr: List[int], k: int) -&gt; int:
    def LIS(arr: List[int]) -&gt; int:
      lis = []
      for x in arr:
        if not lis or lis[-1] &lt;= x:
          lis.append(x)
        else:
          lis[bisect_right(lis, x)] = x
      return len(lis)
    
    return sum(len(arr[i::k]) - LIS(arr[i::k]) for i in range(k))</pre>
</div></div>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/algorithms/binary-search/leetcode-2111-minimum-operations-to-make-the-array-k-increasing/">花花酱 LeetCode 2111. Minimum Operations to Make the Array K-Increasing</a> appeared first on <a rel="nofollow" href="https://zxi.mytechroad.com/blog">Huahua&#039;s Tech Road</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://zxi.mytechroad.com/blog/algorithms/binary-search/leetcode-2111-minimum-operations-to-make-the-array-k-increasing/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 1713. Minimum Operations to Make a Subsequence</title>
		<link>https://zxi.mytechroad.com/blog/dynamic-programming/leetcode-1713-minimum-operations-to-make-a-subsequence/</link>
					<comments>https://zxi.mytechroad.com/blog/dynamic-programming/leetcode-1713-minimum-operations-to-make-a-subsequence/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Sun, 03 Jan 2021 19:57:02 +0000</pubDate>
				<category><![CDATA[Dynamic Programming]]></category>
		<category><![CDATA[dp]]></category>
		<category><![CDATA[hard]]></category>
		<category><![CDATA[LCS]]></category>
		<category><![CDATA[LIS]]></category>
		<guid isPermaLink="false">https://zxi.mytechroad.com/blog/?p=7901</guid>

					<description><![CDATA[<p>You are given an array&#160;target&#160;that consists of&#160;distinct&#160;integers and another integer array&#160;arr&#160;that&#160;can&#160;have duplicates. In one operation, you can insert any integer at any position in&#160;arr. For&#8230;</p>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/dynamic-programming/leetcode-1713-minimum-operations-to-make-a-subsequence/">花花酱 LeetCode 1713. Minimum Operations to Make a Subsequence</a> appeared first on <a rel="nofollow" href="https://zxi.mytechroad.com/blog">Huahua&#039;s Tech Road</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<figure class="wp-block-embed is-type-video is-provider-youtube wp-block-embed-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio"><div class="wp-block-embed__wrapper">
<iframe title="【LCS/LIS】花花酱 LeetCode 1713. Minimum Operations to Make a Subsequence - 刷题找工作 EP379" width="500" height="281" src="https://www.youtube.com/embed/5vBPESNPEu4?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
</div></figure>



<p>You are given an array&nbsp;<code>target</code>&nbsp;that consists of&nbsp;<strong>distinct</strong>&nbsp;integers and another integer array&nbsp;<code>arr</code>&nbsp;that&nbsp;<strong>can</strong>&nbsp;have duplicates.</p>



<p>In one operation, you can insert any integer at any position in&nbsp;<code>arr</code>. For example, if&nbsp;<code>arr = [1,4,1,2]</code>, you can add&nbsp;<code>3</code>&nbsp;in the middle and make it&nbsp;<code>[1,4,<u>3</u>,1,2]</code>. Note that you can insert the integer at the very beginning or end of the array.</p>



<p>Return&nbsp;<em>the&nbsp;<strong>minimum</strong>&nbsp;number of operations needed to make&nbsp;</em><code>target</code><em>&nbsp;a&nbsp;<strong>subsequence</strong>&nbsp;of&nbsp;</em><code>arr</code><em>.</em></p>



<p>A&nbsp;<strong>subsequence</strong>&nbsp;of an array is a new array generated from the original array by deleting some elements (possibly none) without changing the remaining elements&#8217; relative order. For example,&nbsp;<code>[2,7,4]</code>&nbsp;is a subsequence of&nbsp;<code>[4,<u>2</u>,3,<u>7</u>,2,1,<u>4</u>]</code>&nbsp;(the underlined elements), while&nbsp;<code>[2,4,2]</code>&nbsp;is not.</p>



<p><strong>Example 1:</strong></p>



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> target = [5,1,3], <code>arr</code> = [9,4,2,3,4]
<strong>Output:</strong> 2
<strong>Explanation:</strong> You can add 5 and 1 in such a way that makes <code>arr</code> = [5,9,4,1,2,3,4], then target will be a subsequence of <code>arr</code>.
</pre>



<p><strong>Example 2:</strong></p>



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> target = [6,4,8,1,3,2], <code>arr</code> = [4,7,6,2,3,8,6,1]
<strong>Output:</strong> 3
</pre>



<p><strong>Constraints:</strong></p>



<ul><li><code>1 &lt;= target.length, arr.length &lt;= 10<sup>5</sup></code></li><li><code>1 &lt;= target[i], arr[i] &lt;= 10<sup>9</sup></code></li><li><code>target</code>&nbsp;contains no duplicates.</li></ul>



<h2><strong>Solution: Reduce to LIS</strong></h2>



<figure class="wp-block-image size-large"><a href="https://zxi.mytechroad.com/blog/wp-content/uploads/2021/01/1713-ep379-1.png"><img width="960" height="540" src="https://zxi.mytechroad.com/blog/wp-content/uploads/2021/01/1713-ep379-1.png" alt="" class="wp-image-7942" srcset="https://zxi.mytechroad.com/blog/wp-content/uploads/2021/01/1713-ep379-1.png 960w, https://zxi.mytechroad.com/blog/wp-content/uploads/2021/01/1713-ep379-1-300x169.png 300w, https://zxi.mytechroad.com/blog/wp-content/uploads/2021/01/1713-ep379-1-768x432.png 768w" sizes="(max-width: 960px) 100vw, 960px" /></a></figure>



<figure class="wp-block-image size-large"><a href="https://zxi.mytechroad.com/blog/wp-content/uploads/2021/01/1713-ep379-2.png"><img width="960" height="540" src="https://zxi.mytechroad.com/blog/wp-content/uploads/2021/01/1713-ep379-2.png" alt="" class="wp-image-7943" srcset="https://zxi.mytechroad.com/blog/wp-content/uploads/2021/01/1713-ep379-2.png 960w, https://zxi.mytechroad.com/blog/wp-content/uploads/2021/01/1713-ep379-2-300x169.png 300w, https://zxi.mytechroad.com/blog/wp-content/uploads/2021/01/1713-ep379-2-768x432.png 768w" sizes="(max-width: 960px) 100vw, 960px" /></a></figure>



<p>The original problem is a LCS (Longest common subsequence) problem that can be solved in O(n*m) time.<br>Since the elements in the target array is unique, we can convert the numbers into indices that helps to reduce the problem to LIS (Longest increasing subsequence) that can be solved in O(mlogn) time.</p>



<p>e.g. <br>target: [6,4,8,1,3,2] =&gt; [0, 1, 2, 3, 4, 5]<br>array: [4,7,6,2,3,8,6,1] =&gt; [1,-1, 0, 5, 4, 2, 0, 3] =&gt; [1, 0, 5, 4, 2, 3]<br>and the LIS is [0, 2, 3] =&gt; [6, 8, 1], we need to insert the rest of the numbers.<br>Ans = len(target) &#8211; len(LIS)</p>



<p>Time complexity: O(nlogm)<br>Space complexity: O(m)</p>



<div class="responsive-tabs">
<h2 class="tabtitle">C++</h2>
<div class="tabcontent">

<pre class="crayon-plain-tag">// Author: Huahua
class Solution {
public:
  int minOperations(vector&lt;int&gt;&amp; A, vector&lt;int&gt;&amp; B) {
    unordered_map&lt;int, int&gt; m;
    for (int i = 0; i &lt; A.size(); ++i)
      m[A[i]] = i;
    vector&lt;int&gt; dp;
    for (int x : B) {
      auto mit = m.find(x);
      if (mit == end(m)) continue;
      const int idx = mit-&gt;second;
      if (dp.empty() || idx &gt; dp.back())
        dp.push_back(idx);
      else
        *lower_bound(begin(dp), end(dp), idx) = idx;
    }
    return A.size() - dp.size();
  }
};</pre>

</div><h2 class="tabtitle">Python3</h2>
<div class="tabcontent">

<pre class="crayon-plain-tag"># Author: Huahua
class Solution:  
  def minOperations(self, A: List[int], B: List[int]) -&gt; int:
    m = {x: i for i, x in enumerate(A)}
    dp = []
    for x in B:
      if x not in m: continue
      if not dp or m[x] &gt; dp[-1]: dp.append(m[x])
      else: dp[bisect_left(dp, m[x])] = m[x]
    return len(A) - len(dp)</pre>
</div></div>



<p><br></p>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/dynamic-programming/leetcode-1713-minimum-operations-to-make-a-subsequence/">花花酱 LeetCode 1713. Minimum Operations to Make a Subsequence</a> appeared first on <a rel="nofollow" href="https://zxi.mytechroad.com/blog">Huahua&#039;s Tech Road</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://zxi.mytechroad.com/blog/dynamic-programming/leetcode-1713-minimum-operations-to-make-a-subsequence/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 1671. Minimum Number of Removals to Make Mountain Array</title>
		<link>https://zxi.mytechroad.com/blog/dynamic-programming/leetcode-1671-minimum-number-of-removals-to-make-mountain-array/</link>
					<comments>https://zxi.mytechroad.com/blog/dynamic-programming/leetcode-1671-minimum-number-of-removals-to-make-mountain-array/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Sat, 28 Nov 2020 21:08:42 +0000</pubDate>
				<category><![CDATA[Dynamic Programming]]></category>
		<category><![CDATA[dp]]></category>
		<category><![CDATA[hard]]></category>
		<category><![CDATA[LIS]]></category>
		<category><![CDATA[mountain array]]></category>
		<guid isPermaLink="false">https://zxi.mytechroad.com/blog/?p=7729</guid>

					<description><![CDATA[<p>You may recall that an array&#160;arr&#160;is a&#160;mountain array&#160;if and only if: arr.length &#62;= 3 There exists some index&#160;i&#160;(0-indexed) with&#160;0 &#60; i &#60; arr.length - 1&#160;such&#8230;</p>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/dynamic-programming/leetcode-1671-minimum-number-of-removals-to-make-mountain-array/">花花酱 LeetCode 1671. Minimum Number of Removals to Make Mountain Array</a> appeared first on <a rel="nofollow" href="https://zxi.mytechroad.com/blog">Huahua&#039;s Tech Road</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>You may recall that an array&nbsp;<code>arr</code>&nbsp;is a&nbsp;<strong>mountain array</strong>&nbsp;if and only if:</p>



<ul><li><code>arr.length &gt;= 3</code></li><li>There exists some index&nbsp;<code>i</code>&nbsp;(<strong>0-indexed</strong>) with&nbsp;<code>0 &lt; i &lt; arr.length - 1</code>&nbsp;such that:<ul><li><code>arr[0] &lt; arr[1] &lt; ... &lt; arr[i - 1] &lt; arr[i]</code></li><li><code>arr[i] &gt; arr[i + 1] &gt; ... &gt; arr[arr.length - 1]</code></li></ul></li></ul>



<p>Given an integer array&nbsp;<code>nums</code>​​​, return&nbsp;<em>the&nbsp;<strong>minimum</strong>&nbsp;number of elements to remove to make&nbsp;</em><code>nums<em>​​​</em></code><em>a&nbsp;<strong>mountain array</strong>.</em></p>



<p><strong>Example 1:</strong></p>



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> nums = [1,3,1]
<strong>Output:</strong> 0
<strong>Explanation:</strong> The array itself is a mountain array so we do not need to remove any elements.
</pre>



<p><strong>Example 2:</strong></p>



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> nums = [2,1,1,5,6,2,3,1]
<strong>Output:</strong> 3
<strong>Explanation:</strong> One solution is to remove the elements at indices 0, 1, and 5, making the array nums = [1,5,6,3,1].
</pre>



<p><strong>Example 3:</strong></p>



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> nums = [4,3,2,1,1,2,3,1]
<strong>Output:</strong> 4
</pre>



<p><strong>Example 4:</strong></p>



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> nums = [1,2,3,4,4,3,2,1]
<strong>Output:</strong> 1
</pre>



<p><strong>Constraints:</strong></p>



<ul><li><code>3 &lt;= nums.length &lt;= 1000</code></li><li><code>1 &lt;= nums[i] &lt;= 10<sup>9</sup></code></li><li>It is guaranteed that you can make a mountain array out of&nbsp;<code>nums</code>.</li></ul>



<h2><strong>Solution: DP / LIS</strong></h2>



<p>LIS[i] := longest increasing subsequence ends with nums[i]<br>LDS[i] := longest decreasing subsequence starts with nums[i]<br>Let nums[i] be the peak, the length of the mountain array is LIS[i] + LDS[i] &#8211; 1<br>Note: LIS[i] and LDS[i] must be &gt; 1 to form a valid mountain array.<br>ans = min(n &#8211; (LIS[i] + LDS[i] &#8211; 1)) 0 &lt;= i &lt; n</p>



<p>Time complexity: O(n^2)<br>Space complexity: O(n)</p>



<div class="responsive-tabs">
<h2 class="tabtitle">C++</h2>
<div class="tabcontent">

<pre class="crayon-plain-tag">// Author: Huahua
class Solution {
public:
  int minimumMountainRemovals(vector&lt;int&gt;&amp; nums) {
    const int n = nums.size();
    vector&lt;int&gt; LIS(n, 1); // LIS[i] := Longest increasing subseq ends with nums[i]
    vector&lt;int&gt; LDS(n, 1); // LDS[i] := Longest decreasing subseq starts with nums[i]
    for (int i = 0; i &lt; n; ++i)      
      for (int j = 0; j &lt; i; ++j)
        if (nums[i] &gt; nums[j]) LIS[i] = max(LIS[i], LIS[j] + 1);
    for (int i = n - 1; i &gt;= 0; --i)
      for (int j = n - 1; j &gt; i; --j)
        if (nums[i] &gt; nums[j]) LDS[i] = max(LDS[i], LDS[j] + 1);
    int ans = INT_MAX;
    for (int i = 0; i &lt; n; ++i) {
      if (LIS[i] &lt; 2 || LDS[i] &lt; 2) continue;
      ans = min(ans, n - (LIS[i] + LDS[i] - 1));
    }
    return ans;
  }
};</pre>
</div></div>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/dynamic-programming/leetcode-1671-minimum-number-of-removals-to-make-mountain-array/">花花酱 LeetCode 1671. Minimum Number of Removals to Make Mountain Array</a> appeared first on <a rel="nofollow" href="https://zxi.mytechroad.com/blog">Huahua&#039;s Tech Road</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://zxi.mytechroad.com/blog/dynamic-programming/leetcode-1671-minimum-number-of-removals-to-make-mountain-array/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 673. Number of Longest Increasing Subsequence</title>
		<link>https://zxi.mytechroad.com/blog/dynamic-programming/leetcode-673-number-of-longest-increasing-subsequence/</link>
					<comments>https://zxi.mytechroad.com/blog/dynamic-programming/leetcode-673-number-of-longest-increasing-subsequence/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Sat, 16 Sep 2017 04:55:26 +0000</pubDate>
				<category><![CDATA[Dynamic Programming]]></category>
		<category><![CDATA[counting]]></category>
		<category><![CDATA[dp]]></category>
		<category><![CDATA[LIS]]></category>
		<guid isPermaLink="false">http://zxi.mytechroad.com/blog/?p=285</guid>

					<description><![CDATA[<p>https://leetcode.com/problems/number-of-longest-increasing-subsequence Problem: Given an unsorted array of integers, find the number of longest increasing subsequence. Example 1: [crayon-663babe82228d249983011/] Example 2: [crayon-663babe82228f153145149/] Note: Length of the given&#8230;</p>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/dynamic-programming/leetcode-673-number-of-longest-increasing-subsequence/">花花酱 LeetCode 673. Number of Longest Increasing Subsequence</a> appeared first on <a rel="nofollow" href="https://zxi.mytechroad.com/blog">Huahua&#039;s Tech Road</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p><iframe width="500" height="375" src="https://www.youtube.com/embed/SFCiuIJu17Y?feature=oembed" frameborder="0" allow="autoplay; encrypted-media" allowfullscreen></iframe></p>
<p><a href="https://leetcode.com/problems/number-of-longest-increasing-subsequence">https://leetcode.com/problems/number-of-longest-increasing-subsequence</a></p>
<p><strong>Problem:</strong></p>
<p>Given an unsorted array of integers, find the number of longest increasing subsequence.</p>
<p><b>Example 1:</b></p><pre class="crayon-plain-tag">Input: [1,3,5,4,7]
Output: 2
Explanation: The two longest increasing subsequence are [1, 3, 4, 7] and [1, 3, 5, 7].</pre><p><b>Example 2:</b></p><pre class="crayon-plain-tag">Input: [2,2,2,2,2]
Output: 5
Explanation: The length of longest continuous increasing subsequence is 1, and there are 5 subsequences' length is 1, so output 5.</pre><p><b>Note:</b> Length of the given array will be not exceed 2000 and the answer is guaranteed to be fit in 32-bit signed int.</p>
<p><strong>Idea:</strong></p>
<p>Dynamic programming</p>
<p><a href="http://zxi.mytechroad.com/blog/wp-content/uploads/2017/09/673-ep56.png"><img class="alignnone size-full wp-image-290" src="http://zxi.mytechroad.com/blog/wp-content/uploads/2017/09/673-ep56.png" alt="" width="960" height="540" srcset="https://zxi.mytechroad.com/blog/wp-content/uploads/2017/09/673-ep56.png 960w, https://zxi.mytechroad.com/blog/wp-content/uploads/2017/09/673-ep56-300x169.png 300w, https://zxi.mytechroad.com/blog/wp-content/uploads/2017/09/673-ep56-768x432.png 768w, https://zxi.mytechroad.com/blog/wp-content/uploads/2017/09/673-ep56-624x351.png 624w" sizes="(max-width: 960px) 100vw, 960px" /></a></p>
<p><img class="alignnone size-full wp-image-289" style="font-size: 1rem;" src="http://zxi.mytechroad.com/blog/wp-content/uploads/2017/09/673-ep56-2.png" alt="" width="960" height="540" srcset="https://zxi.mytechroad.com/blog/wp-content/uploads/2017/09/673-ep56-2.png 960w, https://zxi.mytechroad.com/blog/wp-content/uploads/2017/09/673-ep56-2-300x169.png 300w, https://zxi.mytechroad.com/blog/wp-content/uploads/2017/09/673-ep56-2-768x432.png 768w, https://zxi.mytechroad.com/blog/wp-content/uploads/2017/09/673-ep56-2-624x351.png 624w" sizes="(max-width: 960px) 100vw, 960px" /></p>
<p><strong>Solution1:</strong></p><pre class="crayon-plain-tag">// Author: Huahua
// Running time: 82 ms
class Solution {
public:
    int findNumberOfLIS(vector&lt;int&gt;&amp; nums) {
        int n = nums.size();
        if (n == 0) return 0;
        
        c_ = vector&lt;int&gt;(n, 0);
        l_ = vector&lt;int&gt;(n, 0);
        
        // Find the length LIS.
        int max_len = 0;
        for (int i = 0; i &lt; n; ++i)
            max_len = max(max_len, len(nums, i));
        
        // Checking all endings.
        int ans = 0;
        for (int i = 0; i &lt; n; ++i)
            if (len(nums, i) == max_len) 
                ans += count(nums, i);
        
        return ans;
    }
private:
    vector&lt;int&gt; c_; // c[i]: number of LIS ends with nums[i] / NLIS'
    vector&lt;int&gt; l_; // l[i]: lengeh of LIS ends with nums[i] / LIS'
    
    // Number of LIS ends with nums[n]
    int count(const vector&lt;int&gt;&amp; nums, int n) {
        if (n == 0) return 1;
        if (c_[n] &gt; 0) return c_[n];
        
        int total_count = 0;
        int l = len(nums, n);
        for (int i = 0; i &lt; n; ++i)
            if (nums[n] &gt; nums[i] &amp;&amp; len(nums, i) == l-1)
                total_count += count(nums, i);
        
        if (total_count == 0)
            total_count = 1;
        
        return c_[n] = total_count;
    }
    
    // Length of LIS ends with nums[n]
    int len(const vector&lt;int&gt;&amp; nums, int n) {
        if (n == 0) return 1;
        if (l_[n] &gt; 0) return l_[n];
        
        int max_len = 1;
        
        // Check every subarray
        for (int i = 0; i &lt; n; ++i)
            if (nums[n] &gt; nums[i])
                max_len = max(max_len, len(nums, i) + 1);
        
        return l_[n] = max_len;
    }
};</pre><p><strong>Solution2:</strong></p><pre class="crayon-plain-tag">// Author: Huahua
// Running time: 33 ms
class Solution {
public:
    int findNumberOfLIS(vector&lt;int&gt;&amp; nums) {
        int n = nums.size();
        if (n == 0) return 0;
        
        vector&lt;int&gt; c(n, 1);
        vector&lt;int&gt; l(n, 1);
        
        for (int i = 1; i &lt; n; ++i)
            for(int j = 0; j &lt; i; ++j)
                if (nums[i] &gt; nums[j]) {
                    if (l[j] + 1 &gt; l[i]) {
                        l[i] = l[j] + 1;
                        c[i] = c[j];
                    } else if (l[j] + 1 == l[i]) {
                        c[i] += c[j];
                    }
                }
        
        int max_len = *max_element(l.begin(), l.end());
        
        int ans = 0;
        for (int i = 0; i &lt; n; ++i)
            if (l[i] == max_len)
                ans += c[i];
        
        return ans;
    }
};</pre><p><strong>Related Problems:</strong></p>
<ul>
<li><a href="http://zxi.mytechroad.com/blog/dynamic-programming/leetcode-300-longest-increasing-subsequence/">[解题报告] LeetCode 300. Longest Increasing Subsequence</a></li>
<li><a href="http://zxi.mytechroad.com/blog/dynamic-programming/leetcode-674-longest-continuous-increasing-subsequence/">[解题报告] LeetCode 674. Longest Continuous Increasing Subsequence</a></li>
<li><a href="http://zxi.mytechroad.com/blog/zoj/leetcode-longest-consecutive-sequence/">[LeetCode] Longest Consecutive Sequence</a></li>
</ul>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/dynamic-programming/leetcode-673-number-of-longest-increasing-subsequence/">花花酱 LeetCode 673. Number of Longest Increasing Subsequence</a> appeared first on <a rel="nofollow" href="https://zxi.mytechroad.com/blog">Huahua&#039;s Tech Road</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://zxi.mytechroad.com/blog/dynamic-programming/leetcode-673-number-of-longest-increasing-subsequence/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 300. Longest Increasing Subsequence</title>
		<link>https://zxi.mytechroad.com/blog/dynamic-programming/leetcode-300-longest-increasing-subsequence/</link>
					<comments>https://zxi.mytechroad.com/blog/dynamic-programming/leetcode-300-longest-increasing-subsequence/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Sun, 10 Sep 2017 18:22:10 +0000</pubDate>
				<category><![CDATA[Dynamic Programming]]></category>
		<category><![CDATA[dp]]></category>
		<category><![CDATA[LIS]]></category>
		<category><![CDATA[medium]]></category>
		<guid isPermaLink="false">http://zxi.mytechroad.com/blog/?p=206</guid>

					<description><![CDATA[<p>Problem: Given an unsorted array of integers, find the length of longest increasing subsequence. For example,Given [10, 9, 2, 5, 3, 7, 101, 18],The longest increasing&#8230;</p>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/dynamic-programming/leetcode-300-longest-increasing-subsequence/">花花酱 LeetCode 300. Longest Increasing Subsequence</a> appeared first on <a rel="nofollow" href="https://zxi.mytechroad.com/blog">Huahua&#039;s Tech Road</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<figure class="wp-block-embed alignleft is-type-video is-provider-youtube wp-block-embed-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio"><div class="wp-block-embed__wrapper">
<iframe title="花花酱 LeetCode 300 Longest Increasing Subsequence O(nlogn) - 刷题找工作 EP378" width="500" height="281" src="https://www.youtube.com/embed/l2rCz7skAlk?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
</div></figure>


<p><iframe title="花花酱 LeetCode 300. Longest Increasing Subsequence (Dynamic Programming O(n^2)) -  刷题找工作 EP48" width="500" height="375" src="https://www.youtube.com/embed/7DKFpWnaxLI?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe></p>
<p><strong>Problem:</strong></p>
<p>Given an unsorted array of integers, find the length of longest increasing subsequence.</p>
<p>For example,<br />Given <code>[10, 9, 2, 5, 3, 7, 101, 18]</code>,<br />The longest increasing subsequence is <code>[2, 3, 7, 101]</code>, therefore the length is <code>4</code>. Note that there may be more than one LIS combination, it is only necessary for you to return the length.</p>
<p>Your algorithm should run in O(<i>n<sup>2</sup></i>) complexity.</p>
<p><b>Follow up:</b> Could you improve it to O(<i>n</i> log <i>n</i>) time complexity?</p>
<p><strong>Idea:</strong></p>
<p>Dynamic Programming</p>
<p><a href="http://zxi.mytechroad.com/blog/wp-content/uploads/2017/09/300-ep48-1.png"><img class="alignnone size-full wp-image-211" src="http://zxi.mytechroad.com/blog/wp-content/uploads/2017/09/300-ep48-1.png" alt="" width="960" height="540" srcset="https://zxi.mytechroad.com/blog/wp-content/uploads/2017/09/300-ep48-1.png 960w, https://zxi.mytechroad.com/blog/wp-content/uploads/2017/09/300-ep48-1-300x169.png 300w, https://zxi.mytechroad.com/blog/wp-content/uploads/2017/09/300-ep48-1-768x432.png 768w, https://zxi.mytechroad.com/blog/wp-content/uploads/2017/09/300-ep48-1-624x351.png 624w" sizes="(max-width: 960px) 100vw, 960px" /></a></p>
<p><a href="http://zxi.mytechroad.com/blog/wp-content/uploads/2017/09/300-ep48-2.png"><img class="alignnone size-full wp-image-210" src="http://zxi.mytechroad.com/blog/wp-content/uploads/2017/09/300-ep48-2.png" alt="" width="960" height="540" srcset="https://zxi.mytechroad.com/blog/wp-content/uploads/2017/09/300-ep48-2.png 960w, https://zxi.mytechroad.com/blog/wp-content/uploads/2017/09/300-ep48-2-300x169.png 300w, https://zxi.mytechroad.com/blog/wp-content/uploads/2017/09/300-ep48-2-768x432.png 768w, https://zxi.mytechroad.com/blog/wp-content/uploads/2017/09/300-ep48-2-624x351.png 624w" sizes="(max-width: 960px) 100vw, 960px" /></a></p>
<p><a href="http://zxi.mytechroad.com/blog/wp-content/uploads/2017/09/300-ep48-3-1.png"><img class="alignnone wp-image-213 size-full" src="http://zxi.mytechroad.com/blog/wp-content/uploads/2017/09/300-ep48-3-1.png" alt="" width="960" height="540" srcset="https://zxi.mytechroad.com/blog/wp-content/uploads/2017/09/300-ep48-3-1.png 960w, https://zxi.mytechroad.com/blog/wp-content/uploads/2017/09/300-ep48-3-1-300x169.png 300w, https://zxi.mytechroad.com/blog/wp-content/uploads/2017/09/300-ep48-3-1-768x432.png 768w, https://zxi.mytechroad.com/blog/wp-content/uploads/2017/09/300-ep48-3-1-624x351.png 624w" sizes="(max-width: 960px) 100vw, 960px" /></a></p>
<p><strong>Time Complexity:</strong></p>
<p>O(n^2)</p>
<p><strong>Solution 1:</strong></p>
<pre class="crayon-plain-tag">// Author: Huahua
// Running time: 29 ms
class Solution {
public:
    int lengthOfLIS(vector&lt;int&gt;&amp; nums) {
        if (nums.empty()) return 0;
        int n = nums.size();
        auto f = vector&lt;int&gt;(n, 1);
        for (int i = 1; i &lt; n; ++i)
            for (int j = 0; j &lt; i; ++j)
                if (nums[i] &gt; nums[j])
                    f[i] = max(f[i], f[j] + 1);
        return *max_element(f.begin(), f.end());
    }
};</pre>
<pre class="crayon-plain-tag"></pre>
<p><strong>Solution 2: DP + Binary Search / Patience Sort</strong></p>
<p>dp[i] := smallest tailing number of a increasing subsequence of length i + 1.</p>
<p>dp is an increasing array, we can use binary search to find the index to insert/update the array.</p>
<p>ans = len(dp)</p>
<p>Time complexity: O(nlogn)<br />Space complexity: O(n)</p>


<div class="responsive-tabs">
<h2 class="tabtitle">C++</h2>
<div class="tabcontent">

<pre class="crayon-plain-tag">class Solution {
public:  
  int lengthOfLIS(vector&lt;int&gt;&amp; nums) {
    const int n = nums.size();
    if (n == 0) return 0;    
    vector&lt;int&gt; dp;
    for (int i = 0; i &lt; n; ++i) {
      auto it = lower_bound(begin(dp), end(dp), nums[i]);
      if (it == end(dp))
        dp.push_back(nums[i]);
      else
        *it = nums[i];
    }
    return dp.size();
  }
};</pre>

</div><h2 class="tabtitle">Python3</h2>
<div class="tabcontent">

<pre class="crayon-plain-tag">class Solution:
  def lengthOfLIS(self, nums: List[int]) -&gt; int:
    d = []
    for x in nums:
      i = bisect_left(d, x)
      if i == len(d): 
        d.append(x)
      else:
        d[i] = x
    return len(d)</pre>
</div></div>



<p><strong>Related Problems:</strong></p>



<ul><li><a href="http://zxi.mytechroad.com/blog/dynamic-programming/leetcode-674-longest-continuous-increasing-subsequence/">[解题报告] LeetCode 674. Longest Continuous Increasing Subsequence</a></li><li><a href="http://zxi.mytechroad.com/blog/zoj/leetcode-longest-consecutive-sequence/">[LeetCode] Longest Consecutive Sequence</a></li></ul>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/dynamic-programming/leetcode-300-longest-increasing-subsequence/">花花酱 LeetCode 300. Longest Increasing Subsequence</a> appeared first on <a rel="nofollow" href="https://zxi.mytechroad.com/blog">Huahua&#039;s Tech Road</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://zxi.mytechroad.com/blog/dynamic-programming/leetcode-300-longest-increasing-subsequence/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>
