<?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>head &#8211; Huahua&#8217;s Tech Road</title>
	<atom:link href="https://zxi.mytechroad.com/blog/tag/head/feed/" rel="self" type="application/rss+xml" />
	<link>https://zxi.mytechroad.com/blog</link>
	<description></description>
	<lastBuildDate>Mon, 07 Apr 2025 02:28:58 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.7.2</generator>

<image>
	<url>https://zxi.mytechroad.com/blog/wp-content/uploads/2017/09/cropped-photo-32x32.jpg</url>
	<title>head &#8211; Huahua&#8217;s Tech Road</title>
	<link>https://zxi.mytechroad.com/blog</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>花花酱 LeetCode 514. Freedom Trail</title>
		<link>https://zxi.mytechroad.com/blog/dynamic-programming/leetcode-514-freedom-trail/</link>
					<comments>https://zxi.mytechroad.com/blog/dynamic-programming/leetcode-514-freedom-trail/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Mon, 07 Apr 2025 02:11:53 +0000</pubDate>
				<category><![CDATA[Dynamic Programming]]></category>
		<category><![CDATA[dp]]></category>
		<category><![CDATA[head]]></category>
		<category><![CDATA[ring]]></category>
		<guid isPermaLink="false">https://zxi.mytechroad.com/blog/?p=10292</guid>

					<description><![CDATA[一眼DP，看数据规模标程应该是O(1003)。 阶段肯定就是吟唱完一个字符，状态和哪个字符在12:00点有关。 所以我们定义 dp[i][j] := 吟唱完keys[0~i]后，rings[j]停在12:00点所需要的最少步数。 转移方程：dp[i][j] = min(dp[i-1][k] + steps(k, j) + 1) if keys[i] == rings[j] else +inf. 第i-1字符吟唱完ring停留在k，第i个字符吟唱完ring停留在j (rings[j] 必须和 keys[i] 相同)，steps(k,&#8230;]]></description>
										<content:encoded><![CDATA[
<p>一眼DP，看数据规模标程应该是O(100<sup>3</sup>)。</p>



<p>阶段肯定就是吟唱完一个字符，状态和哪个字符在12:00点有关。</p>



<p>所以我们定义 dp[i][j] := 吟唱完keys[0~i]后，rings[j]停在12:00点所需要的最少步数。</p>



<p>转移方程：dp[i][j] = min(dp[i-1][k] + steps(k, j) + 1)  if keys[i] == rings[j] else +inf.</p>



<p>第i-1字符吟唱完ring停留在k，第i个字符吟唱完ring停留在j (rings[j] 必须和 keys[i] 相同)，steps(k, j)表示ring从k转到j所需要的最少步数，最后还要+1，表示吟唱当前字符所需要的额外步骤。</p>



<p>边界条件：对于第0个字符，ring一开始停留在第0个字符，最小步数就是1 + steps(0, key[0])。</p>



<p>时间复杂度：O(mn<sup>2</sup>)<br>空间复杂度：O(mn) 可以降维到 O(n)</p>



<pre class="urvanov-syntax-highlighter-plain-tag">class Solution {
public:
  int findRotateSteps(string ring, string key) {
    const int n = ring.size();
    const int m = key.size();
    auto steps = [n](int i, int j) {
      return min(abs(i - j), n - abs(i - j));
    };
    // dp[i][j] min steps to spell key[0~i] and ring[j] is at 12:00.
    vector&lt;vector&lt;int&gt;&gt; dp(m, vector&lt;int&gt;(n, INT_MAX/2));
    for (int i = 0; i &lt; m; ++i)
      for (int j = 0; j &lt; n; ++j) {
        if (ring[j] != key[i]) continue;
        for (int k = 0; k &lt; n; ++k)
          dp[i][j] = min(dp[i][j], 1 + (i == 0 ? steps(0, j) : (dp[i - 1][k] + steps(j, k))));
      }
    return *min_element(begin(dp.back()), end(dp.back()));
  }
};</pre>
]]></content:encoded>
					
					<wfw:commentRss>https://zxi.mytechroad.com/blog/dynamic-programming/leetcode-514-freedom-trail/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 778. Swim in Rising Water</title>
		<link>https://zxi.mytechroad.com/blog/heap/leetcode-778-swim-in-rising-water/</link>
					<comments>https://zxi.mytechroad.com/blog/heap/leetcode-778-swim-in-rising-water/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Fri, 01 Feb 2019 04:46:57 +0000</pubDate>
				<category><![CDATA[Heap]]></category>
		<category><![CDATA[head]]></category>
		<category><![CDATA[path]]></category>
		<category><![CDATA[priority queue]]></category>
		<guid isPermaLink="false">https://zxi.mytechroad.com/blog/?p=4750</guid>

					<description><![CDATA[On an N x N&#160;grid, each square&#160;grid[i][j]&#160;represents the elevation at that point&#160;(i,j). Now rain starts to fall. At time&#160;t, the depth of the water everywhere&#8230;]]></description>
										<content:encoded><![CDATA[
<figure class="wp-block-embed-youtube wp-block-embed is-type-video is-provider-youtube wp-embed-aspect-4-3 wp-has-aspect-ratio"><div class="wp-block-embed__wrapper">
<iframe title="花花酱 LeetCode 778. Swim in Rising Water - 刷题找工作 EP244" width="500" height="375" src="https://www.youtube.com/embed/umdk98ynLSY?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
</div></figure>



<p>On an N x N&nbsp;<code>grid</code>, each square&nbsp;<code>grid[i][j]</code>&nbsp;represents the elevation at that point&nbsp;<code>(i,j)</code>.</p>



<p>Now rain starts to fall. At time&nbsp;<code>t</code>, the depth of the water everywhere is&nbsp;<code>t</code>. You can swim from a square to another 4-directionally adjacent square if and only if the elevation of both squares individually are&nbsp;at most&nbsp;<code>t</code>. You can swim infinite distance in zero time. Of course, you must stay within the boundaries of the grid during your swim.</p>



<p>You start at the top left square&nbsp;<code>(0, 0)</code>. What is the least time until you can reach the bottom right square&nbsp;<code>(N-1, N-1)</code>?</p>



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



<pre class="wp-block-preformatted crayon:false"><strong>Input:</strong> [[0,2],[1,3]]
<strong>Output:</strong> 3
<strong>Explanation:</strong>
At time <code>0</code>, you are in grid location <code>(0, 0)</code>.
You cannot go anywhere else because 4-directionally adjacent neighbors have a higher elevation than t = 0.

You cannot reach point <code>(1, 1)</code> until time <code>3</code>.
When the depth of water is <code>3</code>, we can swim anywhere inside the grid.
</pre>



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



<pre class="wp-block-preformatted crayon:false"><strong>Input:</strong> [[0,1,2,3,4],[24,23,22,21,5],[12,13,14,15,16],[11,17,18,19,20],[10,9,8,7,6]]
<strong>Output:</strong> 16
<strong>Explanation:</strong>
<strong> 0  1  2  3  4</strong>
24 23 22 21  <strong>5</strong>
<strong>12 13 14 15 16</strong>
<strong>11</strong> 17 18 19 20
<strong>10  9  8  7  6</strong>

The final route is marked in bold.
We need to wait until time 16 so that (0, 0) and (4, 4) are connected.
</pre>



<p><strong>Note:</strong></p>



<ol class="wp-block-list"><li><code>2 &lt;= N &lt;= 50</code>.</li><li>grid[i][j] is a permutation of [0, &#8230;, N*N &#8211; 1].</li></ol>



<h2 class="wp-block-heading"><strong>Solution 1: Dijkstra&#8217;s Algorithm</strong></h2>



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



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

<pre class="urvanov-syntax-highlighter-plain-tag">// Author: Huahua, running time: 8 ms
class Solution {
public:
  int swimInWater(vector&lt;vector&lt;int&gt;&gt;&amp; grid) {
    const int n = grid.size();
    priority_queue&lt;pair&lt;int, int&gt;&gt; q; // {-time, y * N + x}
    q.push({-grid[0][0], 0 * n + 0});
    vector&lt;int&gt; seen(n * n);
    vector&lt;int&gt; dirs{-1, 0, 1, 0, -1};
    seen[0 * n + 0] = 1;
    while (!q.empty()) {
      auto node = q.top(); q.pop();
      int t = -node.first;
      int x = node.second % n;
      int y = node.second / n;      
      if (x == n - 1 &amp;&amp; y == n - 1) return t;
      for (int i = 0; i &lt; 4; ++i) {
        int tx = x + dirs[i];
        int ty = y + dirs[i + 1];
        if (tx &lt; 0 || ty &lt; 0 || tx &gt;= n || ty &gt;= n) continue;
        if (seen[ty * n + tx]) continue;
        seen[ty * n + tx] = 1;
        q.push({-max(t, grid[ty][tx]), ty * n + tx});
      }
    }
    return -1;
  }
};</pre>
</div></div>



<h2 class="wp-block-heading"><strong>Solution 2: Binary Search + BFS</strong></h2>



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



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

<pre class="urvanov-syntax-highlighter-plain-tag">// Author: Huahua, running time: 8 ms
class Solution {
public:
  int swimInWater(vector&lt;vector&lt;int&gt;&gt;&amp; grid) {
    const int n = grid.size();
    auto hasPath = [&amp;grid, n](int t) {
      if (grid[0][0] &gt; t) return false;      
      queue&lt;int&gt; q;
      vector&lt;int&gt; seen(n * n);
      vector&lt;int&gt; dirs{1, 0, -1, 0, 1};
      q.push(0);
      
      while (!q.empty()) {
        const int x = q.front() % n;
        const int y = q.front() / n;
        q.pop();
        if (x == n - 1 &amp;&amp; y == n - 1) return true;
        for (int i = 0; i &lt; 4; ++i) {
          const int tx = x + dirs[i];
          const int ty = y + dirs[i + 1];
          if (tx &lt; 0 || ty &lt; 0 || tx &gt;= n || ty &gt;= n || grid[ty][tx] &gt; t) continue;
          const int key = ty * n + tx;
          if (seen[key]) continue;
          seen[key] = 1;
          q.push(key);
        }
      }
      return false;
    };
    int l = 0;
    int r = n * n;
    while (l &lt; r) {
      int m = l + (r - l) / 2;
      if (hasPath(m)) {
        r = m;
      } else {
        l = m + 1;
      }
    }
    return l;
  }
};</pre>
</div></div>
]]></content:encoded>
					
					<wfw:commentRss>https://zxi.mytechroad.com/blog/heap/leetcode-778-swim-in-rising-water/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 725. Split Linked List in Parts</title>
		<link>https://zxi.mytechroad.com/blog/list/leetcode-725-split-linked-list-in-parts/</link>
					<comments>https://zxi.mytechroad.com/blog/list/leetcode-725-split-linked-list-in-parts/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Tue, 14 Nov 2017 03:34:58 +0000</pubDate>
				<category><![CDATA[List]]></category>
		<category><![CDATA[Medium]]></category>
		<category><![CDATA[head]]></category>
		<category><![CDATA[list]]></category>
		<category><![CDATA[partition]]></category>
		<guid isPermaLink="false">http://zxi.mytechroad.com/blog/?p=784</guid>

					<description><![CDATA[Problem: Given a (singly) linked list with head node root, write a function to split the linked list into k consecutive linked list &#8220;parts&#8221;. The length of each&#8230;]]></description>
										<content:encoded><![CDATA[<p><iframe title="花花酱 LeetCode 725. Split Linked List in Parts - 刷题找工作 EP106" width="500" height="375" src="https://www.youtube.com/embed/fk8JTWhM-4U?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe></p>
<p><strong>Problem:</strong></p>
<div class="question-description">
<p>Given a (singly) linked list with head node <code>root</code>, write a function to split the linked list into <code>k</code> consecutive linked list &#8220;parts&#8221;.</p>
<p>The length of each part should be as equal as possible: no two parts should have a size differing by more than 1. This may lead to some parts being null.</p>
<p>The parts should be in order of occurrence in the input list, and parts occurring earlier should always have a size greater than or equal parts occurring later.</p>
<p>Return a List of ListNode&#8217;s representing the linked list parts that are formed.</p>
<p>Examples 1-&gt;2-&gt;3-&gt;4, k = 5 // 5 equal parts [ [1], [2], [3], [4], null ]</p>
<p><b>Example 1:</b></p><pre class="urvanov-syntax-highlighter-plain-tag">Input: 
root = [1, 2, 3], k = 5
Output: [[1],[2],[3],[],[]]
Explanation:
The input and each element of the output are ListNodes, not arrays.
For example, the input root has root.val = 1, root.next.val = 2, \root.next.next.val = 3, and root.next.next.next = null.
The first element output[0] has output[0].val = 1, output[0].next = null.
The last element output[4] is null, but it's string representation as a ListNode is [].</pre><p><b>Example 2:</b></p><pre class="urvanov-syntax-highlighter-plain-tag">Input: 
root = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], k = 3
Output: [[1, 2, 3, 4], [5, 6, 7], [8, 9, 10]]
Explanation:
The input has been split into consecutive parts with size difference at most 1, and earlier parts are a larger size than the later parts.</pre><p><b>Note:</b></p>
<ul>
<li>The length of <code>root</code> will be in the range <code>[0, 1000]</code>.</li>
<li>Each value of a node in the input will be an integer in the range <code>[0, 999]</code>.</li>
<li><code>k</code> will be an integer in the range <code>[1, 50]</code>.</li>
</ul>
</div>
<p><script async src="//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script><br />
<ins class="adsbygoogle" style="display: block; text-align: center;" data-ad-layout="in-article" data-ad-format="fluid" data-ad-client="ca-pub-2404451723245401" data-ad-slot="7983117522"></ins><br />
<script>
     (adsbygoogle = window.adsbygoogle || []).push({});
</script></p>
<div><strong>Idea:</strong></div>
<div></div>
<div>List + Simulation</div>
<div></div>
<div><a href="http://zxi.mytechroad.com/blog/wp-content/uploads/2017/11/725-ep106-1.png"><img fetchpriority="high" decoding="async" class="alignnone size-full wp-image-792" src="http://zxi.mytechroad.com/blog/wp-content/uploads/2017/11/725-ep106-1.png" alt="" width="960" height="540" srcset="https://zxi.mytechroad.com/blog/wp-content/uploads/2017/11/725-ep106-1.png 960w, https://zxi.mytechroad.com/blog/wp-content/uploads/2017/11/725-ep106-1-300x169.png 300w, https://zxi.mytechroad.com/blog/wp-content/uploads/2017/11/725-ep106-1-768x432.png 768w, https://zxi.mytechroad.com/blog/wp-content/uploads/2017/11/725-ep106-1-624x351.png 624w" sizes="(max-width: 960px) 100vw, 960px" /></a></div>
<div id="interviewed-div"></div>
<div><strong>Solution:</strong></div>
<div></div>
<div>C++</div>
<div>
<pre class="urvanov-syntax-highlighter-plain-tag">// Author: Huahua
// Runtime: 9 ms
class Solution {
public:
    vector&lt;ListNode*&gt; splitListToParts(ListNode* root, int k) {
        int len = 0;
        for (ListNode* head = root; head; head = head-&gt;next) ++len;
        vector&lt;ListNode*&gt; ans(k, nullptr);
        int l = len / k;
        int r = len % k;        
        ListNode* head = root;
        ListNode* prev = nullptr;
        for (int i = 0; i &lt; k; ++i, --r) {
            ans[i] = head;
            for (int j = 0; j &lt; l + (r &gt; 0); ++j) {
                prev = head;
                head = head-&gt;next;
            }
            if (prev) prev-&gt;next = nullptr;
        }
        return ans;
    }
};</pre>
</div>
<p>Java</p><pre class="urvanov-syntax-highlighter-plain-tag">// Author: Huahua
// Runtime: 4 ms
class Solution {
    public ListNode[] splitListToParts(ListNode root, int k) {
        ListNode[] ans = new ListNode[k];
        int len = 0;
        for (ListNode head = root; head != null; head = head.next) ++len;
        int l = len / k;
        int r = len % k;
        ListNode prev = null;   
        ListNode head = root;
        for (int i = 0; i &lt; k; ++i, --r) {
            ans[i] = head;
            int part_len = l + ((r &gt; 0) ? 1 : 0);
            for (int j = 0; j &lt; part_len; ++j) {
                prev = head;
                head = head.next;
            }            
            if (prev != null) prev.next = null;
        }
        return ans;
    }
}</pre><p>Python</p><pre class="urvanov-syntax-highlighter-plain-tag">"""
Author: Huahua
Runtime: 79 ms
"""
class Solution:
    def splitListToParts(self, root, k):
        total_len = 0
        head = root
        while head:
            total_len += 1
            head = head.next
        
        ans = [None for _ in range(k)]
        
        l, r = total_len // k, total_len % k
        
        prev, head = None, root
        
        for i in range(k):
            ans[i] = head
            for j in range(l + (1 if r &gt; 0 else 0)):
                prev, head = head, head.next
            if prev: prev.next = None
            r -= 1
        
        return ans</pre><p>&nbsp;</p>
]]></content:encoded>
					
					<wfw:commentRss>https://zxi.mytechroad.com/blog/list/leetcode-725-split-linked-list-in-parts/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>
