bfs_leetcode 310 最小高度树

由于遍历每一个节点为根节点树的高度,再去求最小时间复杂度为O(n^2),超时

class Solution:

    def findMinHeightTrees(self, n: int, edges: List[List[int]]) -> List[int]:
        def find_height(node,result):
            queue=collections.deque()
            visit=[0 for _ in range(n)]
            queue.append(node)
            visit[node]=1
            step=-1

            while queue:
                size=len(queue)
                for _ in range(size):
                    x=queue.popleft()
                    for item in edges:
                        if item[0]==x and visit[item[1]]!=1:
                            queue.append(item[1])
                            visit[item[1]]=1
                        elif item[1]==x and visit[item[0]]!=1:
                            queue.append(item[0])
                            visit[item[0]]=1
                step+=1
            if step not in result:
                result[step]=[node]
            else:
                result[step].append(node)
            return result

        minvalue=float('inf')
        result={}
        for i in range(n):
           result=find_height(i,result)

        for i in range(n):
            if i in result.keys():
                return result[i]

所以反过来思考,从最外层向最里层遍历,也就是从叶子节点向根节点进行bfs,将出度为1的节点都入列,然后排除。最后当所有节点都在同一层,证明他们的高度都是一样的,所以均为答案。也就是当queue的长度等于当前没有遍历的剩余元素。

找到数的最小高度,那么就像层序遍历一样,从最外层一层一层往里数,当剩下的元素均在同一层时,这些元素就是最小层的元素了。而且是只剩下1,2个点,因为如果有多的点就会形成新的层。

具体实现方式和按层分组的层序遍历类似,先把最外层入队,然后每次循环队中全部元素。
找到这个元素未遍历过的相邻元素并入队。
直至一轮开始时剩余元素数量等于队中元素数量就不再遍历,因为这些就是全部能作为答案的元素了(也就是最中间层的元素);

很显然,如果剩余元素比队中的多,那么说明还有元素没有遍历到,需要继续遍历;
剩余元素不会比队中的少,因为入队的元素是唯一且为剩余元素的。

作者:meng-li-ye-tian-xing
链接:https://leetcode-cn.com/problems/minimum-height-trees/solution/c-you-wai-zhi-nei-de-ceng-xu-bian-li-by-dnu8g/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

认识defaultdict:
from collections import defaultdict
当我使用普通的字典时,用法一般是dict={},添加元素的只需要dict[element] =value即,调用的时候也是如此,dict[element] = xxx,但前提是element字典里,如果不在字典里就会报错,如:

这时defaultdict就能排上用场了,defaultdict的作用是在于,当字典里的key不存在但被查找时,返回的不是keyError而是一个默认值。

defaultdict接受一个工厂函数作为参数

dict =defaultdict( factory_function)
这个factory_function可以是list、set、str等等,作用是当key不存在时,返回的是工厂函数的默认值,比如list对应[ ],str对应的是空字符串,set对应set( ),int对应0。

注意:在这里使用了defaultdict,以及它的remove方法。
这个做法就是先将题目中的条件转为邻接矩阵,然后根据出度入队,然后在队列中和邻接矩阵中将遍历过的点进行删除,接着遍历当剩余未遍历的元素等于当前队列的元素,或者剩下的元素只有1-2个时返回结果,这其中deque()类型的结果需要转换成list。

class Solution:

    def findMinHeightTrees(self, n: int, edges: List[List[int]]) -> List[int]:
        neighbors=defaultdict(list)
        queue=collections.deque()
        visit=[0]*n
        if n==1:
            return [0]

        for item in edges:

            neighbors[item[0]].append(item[1])
            neighbors[item[1]].append(item[0])

        for key,value in neighbors.items():
            if len(value)==1:
                queue.append(key)
                visit[key]=1


        while queue:
            size=len(queue)
            if n==len(queue):

                return list(queue)

            for _ in range(size):
                item=queue.popleft()
                n-=1
                nei=neighbors[item].pop()
                neighbors[nei].remove(item)
                if len(neighbors[nei])==1  and visit[nei]!=1:
                    queue.append(nei)
                    visit[nei]=1

递归方法,每次在一个点的邻接点中递归,通过记忆化减少时间复杂度,然后判断长度大小,将答案放入。

class Solution:

    def findMinHeightTrees(self, n: int, edges: List[List[int]]) -> List[int]:
        neighbors=defaultdict(list)
        memo=defaultdict(list)
        visit=[0]*n
        ans=[]

        for item in edges:

            neighbors[item[0]].append(item[1])
            neighbors[item[1]].append(item[0])



        def dfs(start,visit,root):
            key=start*1e5+root

            if key in memo:
                return memo[key]

            visit[start]=1
            ret=0

            for i in neighbors[start]:
                if visit[i]==1:
                    continue

                ret=max(ret,dfs(i,visit,start))


            memo[key]=ret+1
            return ret+1



        minvalue=float('inf')
        for i in range(n):
            visit=[0]*n
            depth=dfs(i,visit,-1)-1
            print(depth)


            if depth<minvalue:
                ans.clear()
                ans.append(i)
                minvalue=depth
            elif depth==minvalue:
                ans.append(i)


        return ans

动态规划想法

全部评论

相关推荐

和蔼:在竞争中脱颖而出,厉害! 但是有一个小问题:谁问你了?😡我的意思是,谁在意?我告诉你,根本没人问你,在我们之中0人问了你,我把所有问你的人都请来 party 了,到场人数是0个人,誰问你了?WHO ASKED?谁问汝矣?誰があなたに聞きましたか?누가 물어봤어?我爬上了珠穆朗玛峰也没找到谁问你了,我刚刚潜入了世界上最大的射电望远镜也没开到那个问你的人的盒,在找到谁问你之前我连癌症的解药都发明了出来,我开了最大距离渲染也没找到谁问你了我活在这个被辐射蹂躏了多年的破碎世界的坟墓里目睹全球核战争把人类文明毁灭也没见到谁问你了
点赞 评论 收藏
分享
11-04 14:10
东南大学 Java
_可乐多加冰_:去市公司包卖卡的
点赞 评论 收藏
分享
点赞 收藏 评论
分享
牛客网
牛客企业服务