冉宝的每日一题--8月6日、8月7日--今天想学会拓扑排序

本文通过分析802找到最终的安全状态、457环形数组是否存在循环等题目,探讨了拓扑排序在解决图论问题中的方法。讲解了如何构建反图、进行拓扑排序,并介绍了快慢指针等技巧。同时,拓扑排序在解决210课程表2和310最小高度树问题中的应用也进行了讨论。
摘要由CSDN通过智能技术生成

昨天的leetcode的每日一题是是一题graph,还是困难题,果断放弃。从压缩状态我就看不懂了。

我觉得每日一题我能够一够的也就是 dfs,bfs + dijstra ,做人还是不要太难为自己。

然后昨天就把前天的题目看了一下,因为感觉我的dfs写法还是不对。

先继续前天的题目,几种解法都要学会!

今天继续图的题目吧!加油,

802 找到最终的安全状态

https://leetcode-cn.com/problems/find-eventual-sacfe-states/solution/zhao-dao-zui-zhong-de-an-quan-zhuang-tai-yzfz/

方法二:拓扑排序:

1- 构建反图 rg 以及 入度数组 inDeg
2- 将所有入度为0的点加入队列 – 这里就是最开始的点,不是反图的点。没有前驱的点就是入度为0 的点。
3- 不断取出队首元素,出边相连的点入度减1,如果该点入度-1后为0,该点加入队列,如此直到队列为空。
循环结束后,所有入度为0的恶点都是安全的,遍历入度数组,将入度为0的点加入答案列表。

from collections import deque
from typing import List
class Solution:
    def eventualSafeNodes(self, graph: List[List[int]]) -> List[int]:
        n = len(graph)
        rg = [[] for i in range(n)]
        inGraph = [len(ys) for ys in graph]
        for start,dsts in enumerate(graph):
            for dst in dsts:
                rg[dst].append(start)


        # 把入度为0 的加入队列
        dq = deque([node for node,ing in enumerate(inGraph) if ing == 0])
        while dq:
            node = dq.popleft()
            dsts = rg[node]
            for dst in dsts:
                inGraph[dst] -= 1
                if inGraph[dst] == 0:
                    dq.append(dst)
        return [node for node,ing in enumerate(inGraph) if ing == 0]

感觉根据模版写还是很快的,希望自己能够记住这个模版。

今天就一直拓扑排序吧!

457、 环形数组是否存在循环

存在一个不含0的环形数组nums,每个nums[i]都表示位于下表i的角色应该向前或者向后移动的下标个数:

  • 如果 nums[i] 是正数,向前 移动 nums[i] 步
  • 如果 nums[i] 是负数,向后 移动 nums[i] 步
    因为数组是 环形 的,所以可以假设从最后一个元素向前移动一步会到达第一个元素,而第一个元素向后移动一步会到达最后一个元素。

数组中的 循环 由长度为 k 的下标序列 seq :

遵循上述移动规则将导致重复下标序列 seq[0] -> seq[1] -> … -> seq[k - 1] -> seq[0] -> …
所有 nums[seq[j]] 应当不是 全正 就是 全负
k > 1

如果 nums 中存在循环,返回 true ;否则,返回 false 。

请添加图片描述
用时: 2:15 -
思路: 这道题是个链路题? 即每个节点到达的下一个节点唯一,可能存在多个路径,但是一个点的下面的路径就是很固定的模式了。

所以可以把节点分成三个状态

  • 0 : 没有访问过的
  • 1 : 正在访问的节点
  • 2 : 访问过的节点,

dfs找到环之后还要判断环的长度和环里面的数字是正还是负,所以需要记录环。
node_dict : 到node能不能形成过程环

dfs(node,pre_path): #
if node in node_dict: return node_dict[node]
if node in pre_path: # 形成环了,
# 环的长度:len(pre_path)- pre_path.index(node)
1- 如果环的长度 < 1 : return False
2- 环里面有正有负不行:
for nn in pre_path:
if nums[node] * node[nn] < 0:
return False
return True

next_node = (nums[node] + node ) % len(nums)
return dfs(next_node,pre_path)
class Solution:
    def circularArrayLoop(self, nums: List[int]) -> bool:
        len_num = len(nums)
        node_dict = {
   }
        def dfs(node,pre_path):
            if node in node_dict:
                return node_dict[node]
            
            if node in pre_path:
                # 判断环的长度
                len_circular = len(pre_path)- pre_path.index(node)
                if len_circular<=1: 
                    node_dict[node] = False
                    return False
                
                for nn in pre_path[pre_path.index(node):]:# 只判断环
                    if nums[node] * nums[
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值