Welcome to Subscribe On Youtube

1719. Number Of Ways To Reconstruct A Tree

Description

You are given an array pairs, where pairs[i] = [xi, yi], and:

  • There are no duplicates.
  • xi < yi

Let ways be the number of rooted trees that satisfy the following conditions:

  • The tree consists of nodes whose values appeared in pairs.
  • A pair [xi, yi] exists in pairs if and only if xi is an ancestor of yi or yi is an ancestor of xi.
  • Note: the tree does not have to be a binary tree.

Two ways are considered to be different if there is at least one node that has different parents in both ways.

Return:

  • 0 if ways == 0
  • 1 if ways == 1
  • 2 if ways > 1

A rooted tree is a tree that has a single root node, and all edges are oriented to be outgoing from the root.

An ancestor of a node is any node on the path from the root to that node (excluding the node itself). The root has no ancestors.

 

Example 1:

Input: pairs = [[1,2],[2,3]]
Output: 1
Explanation: There is exactly one valid rooted tree, which is shown in the above figure.

Example 2:

Input: pairs = [[1,2],[2,3],[1,3]]
Output: 2
Explanation: There are multiple valid rooted trees. Three of them are shown in the above figures.

Example 3:

Input: pairs = [[1,2],[2,3],[2,4],[1,5]]
Output: 0
Explanation: There are no valid rooted trees.

 

Constraints:

  • 1 <= pairs.length <= 105
  • 1 <= xi < yi <= 500
  • The elements in pairs are unique.

Solutions

  • class Solution {
        public int checkWays(int[][] pairs) {
            boolean[][] g = new boolean[510][510];
            List<Integer>[] v = new List[510];
            Arrays.setAll(v, k -> new ArrayList<>());
            for (int[] p : pairs) {
                int x = p[0], y = p[1];
                g[x][y] = true;
                g[y][x] = true;
                v[x].add(y);
                v[y].add(x);
            }
            List<Integer> nodes = new ArrayList<>();
            for (int i = 0; i < 510; ++i) {
                if (!v[i].isEmpty()) {
                    nodes.add(i);
                    g[i][i] = true;
                }
            }
            nodes.sort(Comparator.comparingInt(a -> v[a].size()));
            boolean equal = false;
            int root = 0;
            for (int i = 0; i < nodes.size(); ++i) {
                int x = nodes.get(i);
                int j = i + 1;
                for (; j < nodes.size() && !g[x][nodes.get(j)]; ++j)
                    ;
                if (j < nodes.size()) {
                    int y = nodes.get(j);
                    if (v[x].size() == v[y].size()) {
                        equal = true;
                    }
                    for (int z : v[x]) {
                        if (!g[y][z]) {
                            return 0;
                        }
                    }
                } else {
                    ++root;
                }
            }
            if (root > 1) {
                return 0;
            }
            return equal ? 2 : 1;
        }
    }
    
  • class Solution {
    public:
        int checkWays(vector<vector<int>>& pairs) {
            vector<vector<bool>> g(510, vector<bool>(510));
            vector<vector<int>> v(510);
            for (auto& p : pairs) {
                int x = p[0], y = p[1];
                g[x][y] = g[y][x] = 1;
                v[x].push_back(y);
                v[y].push_back(x);
            }
            vector<int> nodes;
            for (int i = 1; i <= 500; ++i) {
                if (v[i].size()) {
                    nodes.push_back(i);
                    g[i][i] = 1;
                }
            }
            sort(nodes.begin(), nodes.end(), [&](int x, int y) -> bool { return v[x].size() < v[y].size(); });
            bool equal = 0;
            int root = 0;
            for (int i = 0; i < nodes.size(); ++i) {
                int x = nodes[i];
                int j = i + 1;
                for (; j < nodes.size() && !g[x][nodes[j]]; ++j)
                    ;
                if (j < nodes.size()) {
                    int y = nodes[j];
                    if (v[x].size() == v[y].size()) equal = 1;
                    for (int z : v[x])
                        if (!g[y][z])
                            return 0;
                } else
                    ++root;
            }
            if (root > 1) return 0;
            if (equal) return 2;
            return 1;
        }
    };
    
  • class Solution:
        def checkWays(self, pairs: List[List[int]]) -> int:
            g = [[False] * 510 for _ in range(510)]
            v = defaultdict(list)
            for x, y in pairs:
                g[x][y] = g[y][x] = True
                v[x].append(y)
                v[y].append(x)
            nodes = []
            for i in range(510):
                if v[i]:
                    nodes.append(i)
                    g[i][i] = True
            nodes.sort(key=lambda x: len(v[x]))
            equal = False
            root = 0
            for i, x in enumerate(nodes):
                j = i + 1
                while j < len(nodes) and not g[x][nodes[j]]:
                    j += 1
                if j < len(nodes):
                    y = nodes[j]
                    if len(v[x]) == len(v[y]):
                        equal = True
                    for z in v[x]:
                        if not g[y][z]:
                            return 0
                else:
                    root += 1
            if root > 1:
                return 0
            return 2 if equal else 1
    
    
  • func checkWays(pairs [][]int) int {
    	g := make([][]bool, 510)
    	v := make([][]int, 510)
    	for i := range g {
    		g[i] = make([]bool, 510)
    	}
    	for _, p := range pairs {
    		x, y := p[0], p[1]
    		g[x][y] = true
    		g[y][x] = true
    		v[x] = append(v[x], y)
    		v[y] = append(v[y], x)
    	}
    	var nodes []int
    	for i := 1; i <= 500; i++ {
    		if len(v[i]) > 0 {
    			nodes = append(nodes, i)
    			g[i][i] = true
    		}
    	}
    	sort.Slice(nodes, func(i, j int) bool {
    		return len(v[nodes[i]]) < len(v[nodes[j]])
    	})
    	equal := false
    	root := 0
    	for i, x := range nodes {
    		j := i + 1
    		for ; j < len(nodes) && !g[x][nodes[j]]; j++ {
    		}
    		if j < len(nodes) {
    			y := nodes[j]
    			if len(v[x]) == len(v[y]) {
    				equal = true
    			}
    			for _, z := range v[x] {
    				if !g[y][z] {
    					return 0
    				}
    			}
    		} else {
    			root++
    		}
    	}
    	if root > 1 {
    		return 0
    	}
    	if equal {
    		return 2
    	}
    	return 1
    }
    

All Problems

All Solutions