Code Interview Note
  • 0. Introduction
  • 1. Basic
    • Python Basic
    • Java Basic
    • Primitive Type
    • Basic Question
    • Number
  • 2. Array and Numbers
    • General
    • TwoSum
    • Buy and Sell Stock
    • SubArray
      • SubArray + HashMap
    • Sliding Window
      • Sliding Window At Most Problem
    • Word Break
    • Passes Problem
    • Majority Element
    • Partition Array
    • Sort Colors
    • Anagram
    • Ugly Number
    • TwoPointer
    • Swipe Line
    • Calculator
    • Sudoku
  • 2.1 String
    • String
    • Palindrome
    • Parentheses
    • Decode String
    • Calculator
    • Abbreviation
  • 3. Linkedlist
    • Dummy Node
    • Double Pointers
  • 4. Stack and Queue
    • General
    • Increase/Decrease Stack
  • 5. Binary Search
    • General
    • BS on result
    • Save the half which has result
    • Rotated Sorted Array
    • Split Array Largest Sum
  • 6. Binary Tree
    • General
    • Path Sum
    • Lowest Common Ancestor
    • BST
    • Convert
    • Traverse
    • Valid Ordered Tree
    • Construct Binary Tree
    • Tree depth and width
    • Vertical Order Traverse
  • 7. Heap
    • Geneal
    • TopK
  • 8. Simulation
    • General
    • Read4
    • Encode Decode
    • LRU/LFU
    • Robot
    • GetRandom O(1)
    • Probability
  • 9. DFS
    • Backtrack
    • General
    • Subset
    • Permutation
    • Combination
  • 10. HashTable
    • General
  • 11. Sort
    • General
  • 12. Recursion
    • General
  • 13. Dynamic Programming
    • Graph
    • General
    • Coordinate
    • Double Sequence
    • Longest Common Subsequence
    • Rolling Array
    • House Robber
    • Backpack
    • Memorization
    • Diagonal
  • 14. BFS
    • General
    • Number of Islands
    • The Maze
  • 15. Graph
    • Shortest Path
    • Undirected Graph
    • Topology Sort
    • Word Ladder
    • Tarjan's Algo
  • 16. Divide & Conquer
    • General
  • 17. UnionFind
    • General
    • Grouping
  • 18. Trie
    • General
    • Word Square
  • 19. Company Summary
    • Oracle
    • Amazon
      • DP
    • Google
    • Hackerrank
    • LinkedIn
  • 20. Design
  • 21. Math
  • Behavior Question
  • Internet
  • OS
Powered by GitBook
On this page
  • Tarjan's Algorithm to find Articulate point
  • 1192 Critical Connections in a Network (find edge)

Was this helpful?

  1. 15. Graph

Tarjan's Algo

PreviousWord LadderNext16. Divide & Conquer

Last updated 5 years ago

Was this helpful?

Tarjan's Algorithm to find Articulate point

Traverse node, 紀錄每個node是第幾步(step), dfs 之後update其可以接觸的最小node以判斷是否cycle

Articulate point 發生在

  1. Node u 沒有parent(起始點)且有大於兩個subtree時

  2. Node u有parent, 且有一個child v及其subtree not chaining back to on of ancestors of u

from collections import defaultdict
class Solution:
    def criticalConnections(self, n: int, connections: List[List[int]]) -> List[List[int]]:
        # build graph
        self.graph = defaultdict(list)
        for conn in connections:
            self.graph[conn[0]].append(conn[1])
            self.graph[conn[1]].append(conn[0])
            
        # init [], low[]
        self.count = [-1] * n
        self.low = [-1] * n
        self.parent = [-1] * n
        self.critical = [False] * n
        
        for i in range(n):
            if self.count[i] == -1:
                self.dfs(i, 0)
        
        ans = [i for i, x in enumerate(self.critical) if x is True]
        print(ans)
        return ans
    
    
    # Tarjan algo
    def dfs(self, u, step):
        self.count[u] = self.low[u] = step
        step+=1
        tree = 0
        for v in self.graph[u]:
            self.parent[v] = u
            if self.count[v] == -1:
                self.dfs(v, step)
                tree+= 1
                # 此時low已經被後面的node更新過,若找到circle則更新smallest visit count
                self.low[u] = min(self.low[u], self.low[v])
                
                # (1) u is root of DFS tree and has two or more distict subtree
                if self.parent[u] == -1 and tree >= 2:
                    self.critical[u] = True
                #(2) If u is not root and low value of one of its child is more 
                # than discovery value of u. 
                if self.parent[u] != -1 and self.count[u] < self.low[v]:
                    self.critical[u] = True
            
            
            elif self.parent[u] != v:
                # 找到circle的連結點,更新low[u]
                self.low[u] = min(self.low[u], self.count[v])

1192 Critical Connections in a Network (find edge)

from collections import defaultdict
class Solution:
    def criticalConnections(self, n: int, connections: List[List[int]]) -> List[List[int]]:   
     # build graph
    self.graph = defaultdict(list)
    for conn in connections:
        self.graph[conn[0]].append(conn[1])
        self.graph[conn[1]].append(conn[0])

    # init [], low[]
    self.count = [-1] * n
    self.low = [-1] * n
    self.parent = [-1] * n
    self.ans = []

    for i in range(n):
        if self.count[i] == -1:
            self.dfs(i, 0)

    return self.ans


# Tarjan algo
def dfs(self, u, step):
    self.count[u] = self.low[u] = step
    step+=1
    for v in self.graph[u]:
        self.parent[v] = u
        if self.count[v] == -1:
            self.dfs(v, step)
            # 此時low已經被後面的node更新過,若找到circle則更新smallest visit count
            self.low[u] = min(self.low[u], self.low[v])

            # 若u不是起始點
            # 若v之後的node有circle,則low[v]應該小於low[u],沒有circle則是criticle point
            if self.parent[u] != -1 and self.count[u] < self.low[v]:
                self.ans.append([u, v])

        elif self.parent[u] != v:
            # 找到circle的連結點,更新low[u]
            self.low[u] = min(self.low[u], self.count[v])

Link
Video