跟踪从图的节点到树的最小高度

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了跟踪从图的节点到树的最小高度相关的知识,希望对你有一定的参考价值。

我正在尝试解决Leetcode中的算法问题;称为“ Minimum Height Trees”。

我尝试使用2色(已访问,尚未访问),然后递归调用辅助函数以增加高度。但是我几乎在最后一步中停留在评论上。我无法想到一种指定在哪种情况下应该检查身高的方法。

下面是我的代码。如果有人可以帮助我,我将不胜感激。谢谢。

class Solution 
    enum Color
        White,Grey;
    
    public List<Integer> findMinHeightTrees(int n, int[][] edges) 
        int minHeight = Integer.MAX_VALUE;
        List<List<Integer>> adjLists = buildGraph(n, edges);
        List<Integer> ret = new ArrayList<>();
        Color[] visited = new Color[n];
        Arrays.fill(visited, Color.White);

        for(int i = 0; i < n; i++)
            calculateHeight(adjLists, i, edges, visited, 0, ret);
        

        return ret;

    
        private List<List<Integer>> buildGraph(int n, int[][] edges)
            List<List<Integer>> adjLists = new ArrayList<>();
            for(int i = 0; i < n; i++)
                adjLists.add(new ArrayList<>());
            
            for(int[] node : edges)
                int v = node[0], u = node[1];
                adjLists.get(u).add(v);
                adjLists.get(v).add(u); 
            
            return adjLists;
        
        private void calculateHeight(List<List<Integer>> adjLists, int start, int[][] edges, Color[] visited, int height, List<Integer> ret)
            /* I feel like I miss some conditions here but any idea is not top on my head for a week */
            if(visited[start] == Color.Grey)
                return;
            visited[start] = Color.Grey;
            for(int v : adjLists.get(start))
                calculateHeight(adjLists, v, edges, visited, height+1, ret);
            
            visited[start] = Color.White;
            return;
        
    

答案

查找最小高度树是找到树的中心(由一或两个顶点组成)

一种可能的实现方式(来自tutorialspoint)是在每个步骤中都删除“叶”。

希望结尾处只有中心。

下面是js中的示例

// https://www.tutorialspoint.com/centers-of-a-tree
function buildAdjencyList (edges) 
  return edges.reduce((dic, [from, to]) => 
    dic.set(from, (dic.get(from) || new Set()).add(to))
    dic.set(to, (dic.get(to) || new Set()).add(from))
    return dic
  , new Map())

function simplify (G) 
  const verticesToDelete = []
  for (let [k,v] of G) 
    if (v.size == 1) 
      G.delete(k)
      verticesToDelete.push(k)
    
  
  for (let [k,v] of G) 
    verticesToDelete.forEach(del => 
      if (v.has(del)) 
        v.delete(del)
      
    )
  

function dump(G)
  for(let [k,v] of G)
    console.log(k, '->', JSON.stringify([...v]))
  

function run(edges)
  const G = buildAdjencyList(edges)
  while(true)
    const keys = [...G.keys()]
    simplify(G)
    // handles bicentral tree
    if(G.size === 0) 
      return keys
    
    // handles central tree
    if(G.size === 1) 
      return [...G.keys()]
    
    console.log('iter')
    dump(G)
  


console.log('bicentral', run([[0, 1], [1, 2], [3, 2], [2, 4], [2, 5],[5,6],[6,7]]))
console.log('central', run([[0, 1], [1, 2]]))

以上是关于跟踪从图的节点到树的最小高度的主要内容,如果未能解决你的问题,请参考以下文章

BFS解决二叉树的最小高度(2021-7-10)

和群友聊HashTable转到树和图的数据结构

树面试题 04.02. 最小高度树

Leetcode二叉树的最小深度

leetcode 310 最小高度树(拓扑排序变形)

什么样的图最小生成树唯一?