<?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>ancestor Archives - Huahua&#039;s Tech Road</title>
	<atom:link href="https://zxi.mytechroad.com/blog/tag/ancestor/feed/" rel="self" type="application/rss+xml" />
	<link>https://zxi.mytechroad.com/blog/tag/ancestor/</link>
	<description></description>
	<lastBuildDate>Sun, 21 Feb 2021 06:34:48 +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>ancestor Archives - Huahua&#039;s Tech Road</title>
	<link>https://zxi.mytechroad.com/blog/tag/ancestor/</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>花花酱 LeetCode 1766. Tree of Coprimes</title>
		<link>https://zxi.mytechroad.com/blog/searching/leetcode-1766-tree-of-coprimes/</link>
					<comments>https://zxi.mytechroad.com/blog/searching/leetcode-1766-tree-of-coprimes/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Sun, 21 Feb 2021 06:16:18 +0000</pubDate>
				<category><![CDATA[Search]]></category>
		<category><![CDATA[ancestor]]></category>
		<category><![CDATA[DFS]]></category>
		<category><![CDATA[hard]]></category>
		<category><![CDATA[tree]]></category>
		<guid isPermaLink="false">https://zxi.mytechroad.com/blog/?p=8139</guid>

					<description><![CDATA[<p>There is a tree (i.e.,&#160;a connected, undirected graph that has no cycles) consisting of&#160;n&#160;nodes numbered from&#160;0&#160;to&#160;n - 1&#160;and exactly&#160;n - 1&#160;edges. Each node has a&#8230;</p>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/searching/leetcode-1766-tree-of-coprimes/">花花酱 LeetCode 1766. Tree of Coprimes</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>There is a tree (i.e.,&nbsp;a connected, undirected graph that has no cycles) consisting of&nbsp;<code>n</code>&nbsp;nodes numbered from&nbsp;<code>0</code>&nbsp;to&nbsp;<code>n - 1</code>&nbsp;and exactly&nbsp;<code>n - 1</code>&nbsp;edges. Each node has a value associated with it, and the&nbsp;<strong>root</strong>&nbsp;of the tree is node&nbsp;<code>0</code>.</p>



<p>To represent this tree, you are given an integer array&nbsp;<code>nums</code>&nbsp;and a 2D array&nbsp;<code>edges</code>. Each&nbsp;<code>nums[i]</code>&nbsp;represents the&nbsp;<code>i<sup>th</sup></code>&nbsp;node&#8217;s value, and each&nbsp;<code>edges[j] = [u<sub>j</sub>, v<sub>j</sub>]</code>&nbsp;represents an edge between nodes&nbsp;<code>u<sub>j</sub></code>&nbsp;and&nbsp;<code>v<sub>j</sub></code>&nbsp;in the tree.</p>



<p>Two values&nbsp;<code>x</code>&nbsp;and&nbsp;<code>y</code>&nbsp;are&nbsp;<strong>coprime</strong>&nbsp;if&nbsp;<code>gcd(x, y) == 1</code>&nbsp;where&nbsp;<code>gcd(x, y)</code>&nbsp;is the&nbsp;<strong>greatest common divisor</strong>&nbsp;of&nbsp;<code>x</code>&nbsp;and&nbsp;<code>y</code>.</p>



<p>An ancestor of a node&nbsp;<code>i</code>&nbsp;is any other node on the shortest path from node&nbsp;<code>i</code>&nbsp;to the&nbsp;<strong>root</strong>. A node is&nbsp;<strong>not&nbsp;</strong>considered an ancestor of itself.</p>



<p>Return&nbsp;<em>an array&nbsp;</em><code>ans</code><em>&nbsp;of size&nbsp;</em><code>n</code>,&nbsp;<em>where&nbsp;</em><code>ans[i]</code><em>&nbsp;is the closest ancestor to node&nbsp;</em><code>i</code><em>&nbsp;such that&nbsp;</em><code>nums[i]</code>&nbsp;<em>and&nbsp;</em><code>nums[ans[i]]</code>&nbsp;are&nbsp;<strong>coprime</strong>, or&nbsp;<code>-1</code><em>&nbsp;if there is no such ancestor</em>.</p>



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



<figure class="wp-block-image"><img src="https://assets.leetcode.com/uploads/2021/01/06/untitled-diagram.png" alt=""/></figure>



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> nums = [2,3,3,2], edges = [[0,1],[1,2],[1,3]]
<strong>Output:</strong> [-1,0,0,1]
<strong>Explanation:</strong> In the above figure, each node's value is in parentheses.
- Node 0 has no coprime ancestors.
- Node 1 has only one ancestor, node 0. Their values are coprime (gcd(2,3) == 1).
- Node 2 has two ancestors, nodes 1 and 0. Node 1's value is not coprime (gcd(3,3) == 3), but node 0's
  value is (gcd(2,3) == 1), so node 0 is the closest valid ancestor.
- Node 3 has two ancestors, nodes 1 and 0. It is coprime with node 1 (gcd(3,2) == 1), so node 1 is its
  closest valid ancestor.
</pre>



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



<figure class="wp-block-image"><img src="https://assets.leetcode.com/uploads/2021/01/06/untitled-diagram1.png" alt=""/></figure>



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



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



<ul><li><code>nums.length == n</code></li><li><code>1 &lt;= nums[i] &lt;= 50</code></li><li><code>1 &lt;= n &lt;= 10<sup>5</sup></code></li><li><code>edges.length == n - 1</code></li><li><code>edges[j].length == 2</code></li><li><code>0 &lt;= u<sub>j</sub>, v<sub>j</sub>&nbsp;&lt; n</code></li><li><code>u<sub>j</sub>&nbsp;!= v<sub>j</sub></code></li></ul>



<h2><strong>Solution: DFS + Stack</strong></h2>



<p>Pre-compute for coprimes for each number.</p>



<p>For each node, enumerate all it&#8217;s coprime numbers, find the deepest occurrence. </p>



<p>Time complexity: O(n * max(nums))<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:
  vector&lt;int&gt; getCoprimes(vector&lt;int&gt;&amp; nums, vector&lt;vector&lt;int&gt;&gt;&amp; edges) {
    constexpr int kMax = 50;
    const int n = nums.size();
    vector&lt;vector&lt;int&gt;&gt; g(n);
    for (const auto&amp; e : edges) {
      g[e[0]].push_back(e[1]);
      g[e[1]].push_back(e[0]);
    }    
        
    vector&lt;vector&lt;int&gt;&gt; coprime(kMax + 1);
    for (int i = 1; i &lt;= kMax; ++i)
      for (int j = 1; j &lt;= kMax; ++j)
        if (gcd(i, j) == 1) coprime[i].push_back(j);
    
    vector&lt;int&gt; ans(n, INT_MAX);
    vector&lt;vector&lt;pair&lt;int, int&gt;&gt;&gt; p(kMax + 1);
    function&lt;void(int, int)&gt; dfs = [&amp;](int cur, int d) {    
      int max_d = -1;
      int ancestor = -1;
      for (int co : coprime[nums[cur]])
        if (!p[co].empty() &amp;&amp; p[co].back().first &gt; max_d) {
          max_d = p[co].back().first;
          ancestor = p[co].back().second;          
        }
      ans[cur] = ancestor;
      p[nums[cur]].emplace_back(d, cur);
      for (int nxt : g[cur])
        if (ans[nxt] == INT_MAX) dfs(nxt, d + 1);
      p[nums[cur]].pop_back();
    };
    
    dfs(0, 0);
    return ans;
  }
};</pre>
</div></div>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/searching/leetcode-1766-tree-of-coprimes/">花花酱 LeetCode 1766. Tree of Coprimes</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/searching/leetcode-1766-tree-of-coprimes/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 1530. Number of Good Leaf Nodes Pairs</title>
		<link>https://zxi.mytechroad.com/blog/tree/leetcode-1530-number-of-good-leaf-nodes-pairs/</link>
					<comments>https://zxi.mytechroad.com/blog/tree/leetcode-1530-number-of-good-leaf-nodes-pairs/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Sun, 26 Jul 2020 06:32:13 +0000</pubDate>
				<category><![CDATA[Tree]]></category>
		<category><![CDATA[ancestor]]></category>
		<category><![CDATA[graph]]></category>
		<category><![CDATA[medium]]></category>
		<category><![CDATA[tree]]></category>
		<guid isPermaLink="false">https://zxi.mytechroad.com/blog/?p=7154</guid>

					<description><![CDATA[<p>Given the&#160;root&#160;of a binary tree and an integer&#160;distance. A pair of two different&#160;leaf&#160;nodes of a binary tree is said to be good if the length&#8230;</p>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/tree/leetcode-1530-number-of-good-leaf-nodes-pairs/">花花酱 LeetCode 1530. Number of Good Leaf Nodes Pairs</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-youtube wp-block-embed is-type-video is-provider-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio"><div class="wp-block-embed__wrapper">
<iframe title="花花酱 LeetCode 1530. Number of Good Leaf Nodes Pairs - 刷题找工作 EP346" width="500" height="281" src="https://www.youtube.com/embed/g8AVmVhNTkM?feature=oembed" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
</div></figure>



<p>Given the&nbsp;<code>root</code>&nbsp;of a binary tree and an integer&nbsp;<code>distance</code>. A pair of two different&nbsp;<strong>leaf</strong>&nbsp;nodes of a binary tree is said to be good if the length of&nbsp;<strong>the shortest path</strong>&nbsp;between them is less than or equal to&nbsp;<code>distance</code>.</p>



<p>Return&nbsp;<em>the number of good leaf node pairs</em>&nbsp;in the tree.</p>



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



<figure class="wp-block-image"><img src="https://assets.leetcode.com/uploads/2020/07/09/e1.jpg" alt=""/></figure>



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> root = [1,2,3,null,4], distance = 3
<strong>Output:</strong> 1
<strong>Explanation:</strong> The leaf nodes of the tree are 3 and 4 and the length of the shortest path between them is 3. This is the only good pair.
</pre>



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



<figure class="wp-block-image"><img src="https://assets.leetcode.com/uploads/2020/07/09/e2.jpg" alt=""/></figure>



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> root = [1,2,3,4,5,6,7], distance = 3
<strong>Output:</strong> 2
<strong>Explanation:</strong> The good pairs are [4,5] and [6,7] with shortest path = 2. The pair [4,6] is not good because the length of ther shortest path between them is 4.
</pre>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> root = [7,1,4,6,null,5,3,null,null,null,null,null,2], distance = 3
<strong>Output:</strong> 1
<strong>Explanation:</strong> The only good pair is [2,5].
</pre>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> root = [100], distance = 1
<strong>Output:</strong> 0
</pre>



<p><strong>Example 5:</strong></p>



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



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



<ul><li>The number of nodes in the&nbsp;<code>tree</code>&nbsp;is in the range&nbsp;<code>[1, 2^10].</code></li><li>Each node&#8217;s value is between&nbsp;<code>[1, 100]</code>.</li><li><code>1 &lt;= distance &lt;= 10</code></li></ul>



<h2><strong>Solution: Brute Force</strong></h2>



<figure class="wp-block-image size-large"><img width="960" height="540" src="https://zxi.mytechroad.com/blog/wp-content/uploads/2020/07/1530-ep346.png" alt="" class="wp-image-7162" srcset="https://zxi.mytechroad.com/blog/wp-content/uploads/2020/07/1530-ep346.png 960w, https://zxi.mytechroad.com/blog/wp-content/uploads/2020/07/1530-ep346-300x169.png 300w, https://zxi.mytechroad.com/blog/wp-content/uploads/2020/07/1530-ep346-768x432.png 768w" sizes="(max-width: 960px) 100vw, 960px" /></figure>



<p>Since n &lt;= 1024, and distance &lt;= 10, we can collect all leaf nodes and try all pairs.</p>



<p>Time complexity: O(|leaves|^2)<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 countPairs(TreeNode* root, int distance) {
    unordered_map&lt;TreeNode*, TreeNode*&gt; parents;
    vector&lt;TreeNode*&gt; leaves;
    function&lt;void(TreeNode*, TreeNode*)&gt; dfs = [&amp;](TreeNode* c, TreeNode* p) {
      if (!c) return;
      parents[c] = p;      
      dfs(c-&gt;left, c);
      dfs(c-&gt;right, c);
      if (!c-&gt;left &amp;&amp; !c-&gt;right) leaves.push_back(c);
    };
    dfs(root, nullptr);
    unordered_map&lt;TreeNode*, int&gt; a;
    auto isGood = [&amp;](TreeNode* n) -&gt; int {
      for (int i = 0; i &lt; distance &amp;&amp; n; ++i, n = parents[n])
        if (a.count(n) &amp;&amp; a[n] + i &lt;= distance) return 1;
      return 0;
    };
    int ans = 0;
    for (int i = 0; i &lt; leaves.size(); ++i) {
      TreeNode* n1 = leaves[i];
      a.clear();
      for (int k = 0; k &lt; distance &amp;&amp; n1; ++k, n1 = parents[n1])
        a[n1] = k;
      for (int j = i + 1; j &lt; leaves.size(); ++j)
        ans += isGood(leaves[j]);
    }
    return ans;
  }
};</pre>
</div></div>



<h2><strong>Solution 2: Post order traversal</strong></h2>



<figure class="wp-block-image size-large"><img width="960" height="540" src="https://zxi.mytechroad.com/blog/wp-content/uploads/2020/07/1530-ep346-2.png" alt="" class="wp-image-7163" srcset="https://zxi.mytechroad.com/blog/wp-content/uploads/2020/07/1530-ep346-2.png 960w, https://zxi.mytechroad.com/blog/wp-content/uploads/2020/07/1530-ep346-2-300x169.png 300w, https://zxi.mytechroad.com/blog/wp-content/uploads/2020/07/1530-ep346-2-768x432.png 768w" sizes="(max-width: 960px) 100vw, 960px" /></figure>



<p>For each node, compute the # of good leaf pair under itself.<br>1. count the frequency of leaf node at distance 1, 2, &#8230;, d for both left and right child.<br>2. ans += l[i] * r[j] (i + j &lt;= distance) cartesian product<br>3. increase the distance by 1 for each leaf node when pop<br>Time complexity: O(n*D^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 countPairs(TreeNode* root, int distance) {
    int ans = 0;
    function&lt;vector&lt;int&gt;(TreeNode*)&gt; dfs 
      = [&amp;](TreeNode* c) -&gt; vector&lt;int&gt; {
      // f[i] = number of leaves node at distance i.
      vector&lt;int&gt; f(distance + 1);
      if (!c) return f;      
      if (!c-&gt;left &amp;&amp; !c-&gt;right) {        
        f[0] = 1; // a single leaf node
        return f;
      }
      const vector&lt;int&gt;&amp; l = dfs(c-&gt;left);
      const vector&lt;int&gt;&amp; r = dfs(c-&gt;right);
      for (int i = 0; i + 1 &lt;= distance; ++i)
        for (int j = 0; i + j + 2 &lt;= distance; ++j)
          ans += l[i] * r[j];
      for (int i = 0; i &lt; distance; ++i)
        f[i + 1] = l[i] + r[i];
      return f;
    };
    dfs(root);
    return ans;
  }
};</pre>

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

<pre class="crayon-plain-tag">class Solution {
  private int D;
  private int ans;
  
  public int countPairs(TreeNode root, int distance) {
    this.D = distance;
    this.ans = 0;
    dfs(root);
    return ans;
  }
  
  private int[] dfs(TreeNode root) {
    int[] f = new int[D + 1];
    if (root == null) return f;
    if (root.left == null &amp;&amp; root.right == null) {
      f[0] = 1;
      return f;
    }
    int[] fl = dfs(root.left);
    int[] fr = dfs(root.right);
    for (int i = 0; i + 1 &lt;= D; ++i)
      for (int j = 0; i + j + 2 &lt;= D; ++j)
        this.ans += fl[i] * fr[j];
    for (int i = 0; i &lt; D; ++i)
      f[i + 1] = fl[i] + fr[i];
    return f;
  }
}</pre>

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

<pre class="crayon-plain-tag"># Author: Huahua
class Solution:
  def countPairs(self, root: TreeNode, D: int) -&gt; int:        
    def dfs(node):
      f = [0] * (D + 1)
      if not node: return f, 0
      if not node.left and not node.right:
        f[0] = 1
        return f, 0      
      fl, pl = dfs(node.left)
      fr, pr = dfs(node.right)
      pairs = 0      
      for dl, cl in enumerate(fl):
        for dr, cr in enumerate(fr):          
          if dl + dr + 2 &lt;= D: pairs += cl * cr
      for i in range(D):
        f[i + 1] = fl[i] + fr[i]
      return f, pl + pr + pairs
    return dfs(root)[1]</pre>
</div></div>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/tree/leetcode-1530-number-of-good-leaf-nodes-pairs/">花花酱 LeetCode 1530. Number of Good Leaf Nodes Pairs</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/tree/leetcode-1530-number-of-good-leaf-nodes-pairs/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>
