LeetCode 1273. 刪除樹節點(拓撲排序/DFS)

1. 題目

給你一棵以節點 0 爲根節點的樹,定義如下:

節點的總數爲 nodes 個;
第 i 個節點的值爲 value[i] ;
第 i 個節點的父節點是 parent[i] 。
請你刪除節點值之和爲 0 的每一棵子樹。

在完成所有刪除之後,返回樹中剩餘節點的數目。

示例:
在這裏插入圖片描述

輸入:nodes = 7, 
parent = [-1,0,0,1,2,2,2], 
value = [1,-2,4,0,-2,-1,-1]
輸出:2
 
提示:
1 <= nodes <= 10^4
-10^5 <= value[i] <= 10^5
parent.length == nodes
parent[0] == -1 表示節點 0 是樹的根。

來源:力扣(LeetCode) 鏈接:https://leetcode-cn.com/problems/delete-tree-nodes
著作權歸領釦網絡所有。商業轉載請聯繫官方授權,非商業轉載請註明出處。

2. 解題

2.1 取巧解

  • 數據很特殊,數據尾部爲更深的節點,逆序遍歷即是自底向上
  • 該解法不通用
class Solution {
public:
    int deleteTreeNodes(int nodes, vector<int>& parent, vector<int>& value) {
    	int i, n = parent.size();
    	vector<int> count(n,1);
    	for(i = n-1; i >= 0; --i)
    	{
    		if(value[i]==0)
    			count[i] = 0;//自己子樹和爲0,刪除節點
    		if(parent[i] != -1)
    		{
    			value[parent[i]] += value[i];//值加給父節點
    			count[parent[i]] += count[i];//父節點底下不爲0的節點個數
    		}
    	}
    	return count[0];
    }
};

60 ms 21.1 MB

2.2 拓撲排序

class Solution {
public:
    int deleteTreeNodes(int nodes, vector<int>& parent, vector<int>& value) {
    	int i, n = parent.size();
    	vector<int> indegree(n,0);
    	for(i = 0; i < n; ++i)
    		if(parent[i] != -1)
    			indegree[parent[i]]++;
		queue<int> q;
		for(i = 0; i < n; ++i)
			if(indegree[i] == 0)
				q.push(i);
		vector<int> count(n,1);
		while(!q.empty())
		{
			int tp = q.front();
			q.pop();
			if(value[tp]==0)
				count[tp] = 0;
			if(parent[tp] == -1)
				continue;
			if(--indegree[parent[tp]]==0)
				q.push(parent[tp]);
			value[parent[tp]] += value[tp];
			count[parent[tp]] += count[tp];
		}
		return count[0];
    }
};

88 ms 22.2 MB

2.3 建圖+DFS

class Solution {
    vector<vector<int>> edges;
    vector<int> count;
public:
    int deleteTreeNodes(int nodes, vector<int>& parent, vector<int>& value) {
    	int i, n = parent.size();
    	edges.resize(n);
        count = vector<int>(n,1);
        for(i = 0; i < n; ++i)
            if(parent[i] != -1)
                edges[parent[i]].push_back(i);
        dfs(0, parent, value);
        return count[0];
    }
    void dfs(int id, vector<int>& parent, vector<int>& value)
    {
        for(int next : edges[id])
        {
            dfs(next, parent, value);
        }
        if(value[id]==0)
            count[id] = 0;
        if(parent[id] != -1)
        {
            value[parent[id]] += value[id];
            count[parent[id]] += count[id];
        }
    }
};

96 ms 29.4 MB


我的CSDN博客地址 https://michael.blog.csdn.net/

長按或掃碼關注我的公衆號(Michael阿明),一起加油、一起學習進步!
Michael阿明

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章