leetcode-pp / 91alg-5-daily-check

91 天学算法第五期打卡
55 stars 14 forks source link

Shortest-Cycle-Containing-Target-Node #71

Open azl397985856 opened 2 years ago

azl397985856 commented 2 years ago

You are given a two-dimensional list of integers graph representing a directed graph as an adjacency list. You are also given an integer target.

Return the length of a shortest cycle that contains target. If a solution does not exist, return -1.

Constraints

n, m ≤ 250 where n and m are the number of rows and columns in graph https://binarysearch.com/problems/Shortest-Cycle-Containing-Target-Node

a244629128 commented 2 years ago

class Solution:
   def solve(self, graph, target):
      visited = set()
      l = [target]
      length = 0

      while l:
         length += 1
         nl = []
         for u in l:
            for v in graph[u]:
               if v == target:
                  return length
               if v in visited:
                  continue
               visited.add(v)
               nl.append(v)
         l = nl

      return -1
jiahui-z commented 2 years ago

思路: depth first search, we start from the target, then explore all nodes it points to and therefore adjacent nodes, until we find that the current node equals target, for all nodes passed we marked them as visited

import java.util.*;

class Solution {
    public int solve(int[][] graph, int target) {
        int result = 0;
        Queue<Integer> queue = new LinkedList<>();
        Set<Integer> visited = new HashSet<>();

        queue.offer(target);
        while (!queue.isEmpty()) {
            int size = queue.size();
            result++;
            for (int i = 0; i < size; i++) {
                int node = queue.poll();
                for (int neighbor : graph[node]) {
                    if (neighbor == target) {
                        return result;
                    }
                    if (visited.contains(neighbor)) {
                        continue;
                    }
                    queue.offer(neighbor);
                    visited.add(neighbor);
                }
            }
        }

        return -1;
    }
}

Time Complexity: O(v + e), v is the number of vertices, e is the number of edges Space Complexity: O(v)

Cartie-ZhouMo commented 2 years ago
class Solution:
    def solve(self, graph, target):
        q = collections.deque([target])
        visited = set()
        steps = 0
        while q:
            for i in range(len(q)):
                cur = q.popleft()
                visited.add(cur)
                for neighbor in graph[cur]:
                    if neighbor not in visited:
                        q.append(neighbor)
                    elif neighbor == target:
                        return steps + 1
            steps += 1
        return -1
ZJP1483469269 commented 2 years ago

思路

bfs

代码

import java.util.*;

class Solution {
    public int solve(int[][] graph, int target) {

        HashSet<Integer> set = new HashSet<>();
        LinkedList<Integer> dq = new LinkedList<>();
        dq.offer(target);
        int ans = 1; 
        while(!dq.isEmpty()){
            int size = dq.size();
            for(int i = 0 ;i < size ; i++){
                int x = dq.poll();
                set.add(x);
                for(int j = 0 ; j < graph[x].length ; j++){
                    if(!set.contains(graph[x][j])){
                        dq.offer(graph[x][j]);
                    }else{
                        if(graph[x][j] == target){
                            return ans;
                        }
                    }
                }

            }
            ans++;

        }
        return -1;

    }
}

复杂度分析

时间复杂度:O(n) 空间复杂度:O(n)

RonghuanYou commented 2 years ago
class Solution:
    def solve(self, graph, target):
        q = [target]
        visited = set()
        steps = 0

        while q:
            for _ in range(len(q)):
                node = q.pop(0)
                visited.add(node)

                for neighbor in graph[node]:
                    if neighbor not in visited:
                        q.append(neighbor)
                    elif neighbor == target:
                        return steps + 1
            steps += 1
        return -1
StefanLeeee commented 2 years ago

思路

BFS

代码

class Solution {
        public int solve(int[][] graph, int target) {
            boolean[] visited = new boolean[graph.length];
            Queue<Integer> q = new LinkedList<>();
            q.add(target);

            int level = 0;
            while (!q.isEmpty()) {
                int size = q.size();
                for (int i = 0; i < size; i++) {
                    int tmp = q.remove();
                    visited[tmp] = true;

                    for (int neighbor : graph[tmp]) {
                        if (neighbor == target)
                            return level + 1;
                        else if (!visited[neighbor])
                            q.add(neighbor);
                    }
                }
                level++;
            }
            return -1;
        }
    }

复杂度

asterqian commented 2 years ago

思路

target作为队列中第一个节点,从他开始,依次寻找他adjacency list里的邻居,如果邻居还没有visited过,把他加入队列,如果邻居就是target,则证明找到环,此时return答案+1,否则就在一层访问完之后(size==0的时候)把答案+1,代表环中元素多一个。

代码

int solve(vector<vector<int>>& graph, int target) {
    queue<int> q;
    q.push(target);
    int ans = 0;
    unordered_set<int> seen;
    while (!q.empty()) {
        int size = q.size();
        while (size--) {
            int curr = q.front();
            q.pop();
            seen.insert(curr);
            for (int neighbor: graph[curr]) {
                if (seen.find(neighbor) == seen.end()) {
                    q.push(neighbor);
                } else if (neighbor == target) {
                    return ans + 1;
                }
            }
        }
        ans++;
    }
    return -1;
}

复杂度分析

时间复杂度: O(v+e)
空间复杂度: O(v)
kbfx1234 commented 2 years ago

Shortest Cycle Containing Target Node

// bfs
int solve(vector<vector<int>>& graph, int target) {
    queue<int> q;
    int n = graph.size();
    vector<bool> visited(n, false);

    q.push(target);
    visited[target] = true;
    int res = 0;
    while(!q.empty()) {
        int n = q.size();
        for (int i = 0; i < n; i++) {
            int x = q.front();
            q.pop();
            vector<int> v = graph[x];
            for (int i = 0; i < v.size(); i++) {
                if (v[i] == target) return res+1;
                else if (!visited[v[i]]) {
                    q.push(v[i]);
                    visited[v[i]] = true;
                }
            }
        }
        res++;
    }
    return -1;
}
lxy030988 commented 2 years ago

思路

代码 js

const solve = (graph, target) => {
  let result = 0
  let visited = new Set([])
  let check = [target]
  let length = check.length
  while (length > 0) {
    result++
    for (let i = 0; i < length; i++) {
      let vertex = check.shift()
      for (let nextNode of graph[vertex]) {
        if (nextNode === target) {
          return result
        } else {
          if (!visited.has(nextNode)) {
            visited.add(nextNode)
            check.push(nextNode)
          }
        }
      }
    }
    length = check.length
  }
  return -1
}

复杂度分析

yj9676 commented 2 years ago
class Solution {
        public int solve(int[][] graph, int target) {
            boolean[] visited = new boolean[graph.length];
            Queue<Integer> q = new LinkedList<>();
            q.add(target);

            int level = 0;
            while (!q.isEmpty()) {
                int size = q.size();
                for (int i = 0; i < size; i++) {
                    int tmp = q.remove();
                    visited[tmp] = true;

                    for (int neighbor : graph[tmp]) {
                        if (neighbor == target)
                            return level + 1;
                        else if (!visited[neighbor])
                            q.add(neighbor);
                    }
                }
                level++;
            }
            return -1;
        }
    }
ymkymk commented 2 years ago

class Solution { public int solve(int[][] graph, int target) { boolean[] visited = new boolean[graph.length]; Queue q = new LinkedList<>(); q.add(target);

    int level = 0;
    while (!q.isEmpty()) {
        int size = q.size();
        for (int i = 0; i < size; i++) {
            int tmp = q.remove();
            visited[tmp] = true;

            for (int neighbor : graph[tmp]) {
                if (neighbor == target)
                    return level + 1;
                else if (!visited[neighbor])
                    q.add(neighbor);
            }
        }

        level++;
    }

    return -1;
}

}

chaggle commented 2 years ago

title: "Day 52 Shortest Cycle Containing Target Node" date: 2021-10-31T20:26:49+08:00 tags: ["Leetcode", "c++", "traceback", "BFS"] categories: ["91-day-algorithm"] draft: true


Shortest Cycle Containing Target Node

题目

You are given a two-dimensional list of integers graph representing a directed graph as an adjacency list. You are also given an integer target.

Return the length of a shortest cycle that contains target. If a solution does not exist, return -1.

Constraints

n, m ≤ 250 where n and m are the number of rows and columns in graph
Example 1
Input
Visualize
graph = [
    [1],
    [2],
    [0]
]
target = 0
Output
3
Explanation
The nodes 0 -> 1 -> 2 -> 0 form a cycle

Example 2
Input
Visualize
graph = [
    [1],
    [2],
    [4],
    [],
    [0]
]
target = 3
Output
-1

题目思路

  • 1、BFS,查看其中的非可视化发现图的存储方式为邻接表,所以本题的图的BFS套用模板即可解决问题;
  • 2、扫描整个图,然后判断每个节点跟目标 t 的关系,有直接return true,最后找不到返回false;
int solve(vector<vector<int>>& g, int t) {
    int n = g.size();
    vector<bool> vis(n, 0);
    queue<int> q;
    q.push(t);
    int ans = 0;

    while (!q.empty()) 
    {
        ans++;
        int n = q.size();
        for (int i = 0; i < n; i++) 
        {
            int node = q.front();q.pop();
            for (auto& v : g[node])
            {
                if(v == t) return ans;
                if(!vis[v])  //如果是未访问节点, 等价于 vis[v] == 0
                {
                    q.push(v);
                    vis[v] = 1;
                }
            }
        }
    }
    return -1;
}

复杂度

carterrr commented 2 years ago

class Solution {
    // 步数统计型  每次记录queue.size() 最终求size
    // bfs图注意保留visited记录 避免死循环
    public int solve(int[][] graph, int target) {
       // from target,find next until target by bfs
        // save the steps, return steps first if find the target  or return -1 at the end 
        // step incr in every round
        // graph第一维代表 当前是哪个点 ,第二维代表指向的点,可能指向很多点
        Queue<Integer> queue = new LinkedList<>();
        queue.offer(target);
        HashSet<Integer> visited = new HashSet<>();
        int step = 0;
        while(!queue.isEmpty()) {
            int size = queue.size();
            for(int i = 0; i< size; i++) {
                int cur = queue.poll();
                for(int node : graph[cur]) {
                    if(node == target) {
                        return step + 1;
                    }
                   if(!visited.contains(node)){
                        visited.add(node);
                    queue.offer(node);
                      }

                }
            }
            step ++;
        }
        return -1;
    }
}
guangsizhongbin commented 2 years ago

import java.util.*;

class Solution { public int solve(int[][] graph, int target) { boolean[] visited = new boolean[graph.length]; Queue q = new LinkedList<>(); q.add(target);

    int level = 0;
    while (!q.isEmpty()) {
        int size = q.size();
        for (int i = 0; i < size; i++) {
            int tmp = q.remove();
            visited[tmp] = true;

            for (int neighbor : graph[tmp]) {
                if (neighbor == target)
                    return level + 1;
                else if (!visited[neighbor])
                    q.add(neighbor);
            }
        }
        level++;
    }
    return -1;
}

}

Lydia61 commented 2 years ago

Shortest-Cycle-Containing-Target-Node

思路

代码

class Solution:
    def solve(self, graph, target):
        q = collections.deque([target])
        visited = set()
        steps = 0
        while q:
            for i in range(len(q)):
                cur = q.popleft()
                visited.add(cur)
                for neighbor in graph[cur]:
                    if neighbor not in visited:
                        q.append(neighbor)
                    elif neighbor == target:
                        return steps + 1
            steps += 1
        return -1

复杂度分析

Moin-Jer commented 2 years ago

思路


BFS 反向搜索

代码


class Solution {
    public int solve(int[][] graph, int target) {
        boolean[] visited = new boolean[graph.length];
        Queue<Integer> q = new LinkedList<>();
        q.add(target);

        int level = 0;
        while (!q.isEmpty()) {
            int size = q.size();
            for (int i = 0; i < size; i++) {
                int tmp = q.remove();
                visited[tmp] = true;

                for (int neighbor : graph[tmp]) {
                    if (neighbor == target)
                        return level + 1;
                    else if (!visited[neighbor])
                        q.add(neighbor);
                }
            }

            level++;
        }

        return -1;
    }
}

复杂度分析


kendj-staff commented 2 years ago
import java.util.*;

class Solution {
    public int solve(int[][] graph, int target) {
        Set<Integer> visited = new HashSet<Integer>();
        Deque<Integer> stack = new LinkedList<Integer>();
        stack.push(target);     
        int res = 0;
        while (!stack.isEmpty()) {
            int cur = stack.pop();
            visited.add(cur);
            for (int i : graph[cur]) {
                if (!visited.contains(i)) {
                    stack.push(i);
                } else if (i == target) {
                    return res + 1;
                }

            }
            res += 1;
        }
        return - 1;
    }
}
learning-go123 commented 2 years ago

思路

代码

JavaScript Code:


class Solution {
    solve(graph, target) {
        let q = [target]
        let v = new Set([])
        let res = 0
        while (q.length > 0) {
            res++
            let size = q.length
            for (let i = 0; i < size; i++) {
                for (let next of graph[q.shift()]) {
                    if (next === target) {
                        return res
                    } else if (!v.has(next)) {
                        v.add(next)
                        q.push(next)
                    }
                }
            }
        }

        return -1
    }
}

复杂度分析

令 n 为数组长度。

machuangmr commented 2 years ago
class Solution {
    public int solve(int[][] graph, int target) {
        Set<Integer> visited = new HashSet<Integer>();
        Deque<Integer> stack = new LinkedList<Integer>();
        stack.push(target);     
        int res = 0;
        while (!stack.isEmpty()) {
            int cur = stack.pop();
            visited.add(cur);
            for (int i : graph[cur]) {
                if (!visited.contains(i)) {
                    stack.push(i);
                } else if (i == target) {
                    return res + 1;
                }

            }
            res += 1;
        }
        return - 1;
    }
}
Toms-BigData commented 2 years ago

class Solution: def solve(self, graph, target): q = collections.deque([target]) visited = set() steps = 0 while q: for i in range(len(q)): cur = q.popleft() visited.add(cur) for neighbor in graph[cur]: if neighbor not in visited: q.append(neighbor) elif neighbor == target: return steps + 1 steps += 1 return -1

mokrs commented 2 years ago
int solve(vector<vector<int>>& graph, int target) {
    queue<int> q;       
    q.push(target);

    int res = 0;
    unordered_set<int> st;

    while (!q.empty()) {
        int size = q.size();
        while (size--) {
            int node = q.front();
            q.pop();

            st.insert(node);
            for (int next : graph[node]) {
                if (next == target) {
                    return res + 1;
                }
                else if (st.find(next) == st.end()) {
                    q.push(next);
                }               
            }
        }

        ++res;
    }
    return -1;
}
HouHao1998 commented 2 years ago

代码

import java.util.*;

class Solution {
    public int solve(int[][] graph, int target) {
        HashSet<Integer> visited = new HashSet();
        Queue<Integer> fringe = new ArrayDeque();
        visited.add(target);
        fringe.offer(target);

        int res = 0;
        while (!fringe.isEmpty()) {
            int size = fringe.size();
            for (int i = 0; i < size; i++) {
                int cur = fringe.poll();
                for (int neighbor : graph[cur]) {
                    if (neighbor == target) {
                        return res + 1;
                    }
                    if (visited.contains(neighbor)) {
                        continue;
                    }
                    visited.add(neighbor);
                    fringe.offer(neighbor);
                }
            }
            res++;
        }

        return -1;
    }
}
Zhang6260 commented 2 years ago

JAVA版本

思路:该题的主要思想是使用BFS,如果存在环的话,那么就会遍历到之前已经遍历过的点。

   public int solve(int[][] graph, int target) {
       HashSet<Integer> visited = new HashSet<Integer>();
       Stack<Integer> stack = new Stack<Integer>();
       stack.push(target);
       int res = 0;
       while (!stack.isEmpty()) {
           int cur = stack.pop();
           visited.add(cur);
           for (int i : graph[cur]) {
               if (!visited.contains(i)) {
                   stack.push(i);
               } else if (i == target) {
                   return res + 1;
               }

           }
           res += 1;
       }
       return - 1;
   }

时间复杂度:O(v+e)

空间复杂度:O(v)

naomiwufzz commented 2 years ago

思路:bfs

一般看到最短路径可以考虑bfs。多源搜索肯定是复杂夫更高,可以从target开始搜索,如果再次碰到target那肯定是一个环,且bfs碰到的第一个环肯定是最小的环。

代码

from collections import deque
class Solution:
    def solve(self, graph, target):
        if target < 0 or target > len(graph):
            return -1
        q = deque([target])
        visited = set()
        res = 0
        while q:
            for _ in range(len(q)):
                cur = q.popleft()
                visited.add(cur)
                for neighbor in graph[cur]:
                    if neighbor == target:
                        return res + 1
                    else:
                        if neighbor not in visited:
                            q.append(neighbor)
            res += 1
        return -1

复杂度分析

taoyr722 commented 2 years ago

代码

class Solution:
    def solve(self, graph, target):
        queue = collections.deque([target])
        visited = set()
        res = 0
        while queue:
            res += 1
            for _ in range(len(queue)):
                cur = queue.popleft()
                for nxt in graph[cur]:
                    if nxt == target:
                        return res
                    if nxt in visited:
                        continue
                    visited.add(nxt)
                    queue.append(nxt)
        return -1
ChenJingjing85 commented 2 years ago
class Solution:
    def solve(self, graph, target):
        visited = set()
        layer = [target]
        length = 0

        while layer:
            length += 1
            next_layer = []
            for u in layer:
                for v in graph[u]:
                    if v == target:
                        return length
                    if v in visited:
                        continue
                    visited.add(v)
                    next_layer.append(v)
            layer = next_layer

        return -1
15691894985 commented 2 years ago

【Day 52】Shortest-Cycle-Containing-Target-Node

https://binarysearch.com/problems/Shortest-Cycle-Containing-Target-Node

class Solution:
    def solve(self, graph, target):
        queue = collections.deque([target])
        visited = set()
        res = 0
        while queue:
            res += 1
            for _ in range(len(queue)):
                cur = queue.popleft()
                for nxt in graph[cur]:
                    if nxt == target:
                        return res
                    if nxt in visited:
                        continue
                    visited.add(nxt)
                    queue.append(nxt)
        return -1

复杂度分析:

时间复杂度:O(V+E)

空间复杂度:O(V)

BlueRui commented 2 years ago

Problem Shortest Cycle Containing Target Node

Algorithm

Complexity

Code

Language: Java

public int solve(int[][] graph, int target) {
    Queue<Integer> q = new LinkedList<>();
    Set<Integer> visited = new HashSet<>();
    int result = 0;
    q.offer(target);
    while (!q.isEmpty()) {
        int size = q.size();
        for (int i = 0; i < size; i++) {
            int cur = q.poll();
            visited.add(cur);
            for (int neighbor : graph[cur]) {
                if (!visited.contains(neighbor)) {
                    q.offer(neighbor);
                } else if (neighbor == target) {
                    return result + 1;
                }
            }
        }
        result++;
    }
    return -1;
}
yyangeee commented 2 years ago
#官方解打卡
class Solution:
    def solve(self, graph, target):
        q = collections.deque([target])
        visited = set()
        steps = 0
        while q:
            for i in range(len(q)):
                cur = q.popleft()
                visited.add(cur)
                for neighbor in graph[cur]:
                    if neighbor not in visited:
                        q.append(neighbor)
                    elif neighbor == target:
                        return steps + 1
            steps += 1
        return -1
hellowxwworld commented 2 years ago

思路

bfs 搜索从 target 开始,如果重新搜索到 target,那就存在环,且是最小的环;

代码

int solve(vector<vector<int>>& g, int t) {
    int n = g.size();
    vector<bool> vis(n, 0);
    queue<int> q;
    q.push(t);
    int ans = 0;

    while (!q.empty()) {
        ans++;
        int n = q.size();
        for (int i = 0; i < n; i++) {
            int node = q.front();q.pop();
            for (auto& v : g[node]) {
                if (v == t)
                    return ans;
                if (!vis[v]) {
                    q.push(v);
                    vis[v] = 1;
                }
            }
        }
    }
    return -1;
}
yukicoding commented 2 years ago
#官方解打卡
class Solution:
    def solve(self, graph, target):
        q = collections.deque([target])
        visited = set()
        steps = 0
        while q:
            for i in range(len(q)):
                cur = q.popleft()
                visited.add(cur)
                for neighbor in graph[cur]:
                    if neighbor not in visited:
                        q.append(neighbor)
                    elif neighbor == target:
                        return steps + 1
            steps += 1
        return -1
wangwiitao commented 2 years ago

思路:看的题解

代码:

class Solution {
    solve(graph, target) {
        let q = [target]
        let v = new Set([])
        let res = 0
        while (q.length > 0) {
            res++
            let size = q.length
            for (let i = 0; i < size; i++) {
                for (let next of graph[q.shift()]) {
                    if (next === target) {
                        return res
                    } else if (!v.has(next)) {
                        v.add(next)
                        q.push(next)
                    }
                }
            }
        }

        return -1
    }
}
xj-yan commented 2 years ago
import java.util.*;

class Solution {
    public int solve(int[][] graph, int target) {
        Map<Integer, Set<Integer>> map = new HashMap<>();
        for (int i = 0; i < graph.length; i++){
            map.put(i, new HashSet<>());
            for (int j = 0; j < graph[i].length; j++){
                map.get(i).add(graph[i][j]);
            }
        }

        if (map.get(target) == null || map.get(target).size() == 0) return -1;
        int step = 0;
        Queue<Integer> queue = new LinkedList<>();
        queue.offer(target);
        Set<Integer> visited = new HashSet<>();
        visited.add(target);

        while (!queue.isEmpty()){
            int size = queue.size();
            step++;
            for (int i = 0; i < size; i++){
                int curt = queue.poll();
                for (int next : map.get(curt)){
                    if (next == target) return step;
                    if (visited.add(next)) queue.offer(next);
                }
            }
        }
        return -1;
    }
}

Time Complexity: O(n), Space Complexity: O(n)

flagyk5 commented 2 years ago
class Solution:
    def solve(self, graph, target):
        que = collections.deque([target])
        vis = set()
        steps = 0
        while que:
            for i in range(len(que)):
                cur = que.popleft()
                vis.add(cur)
                for j in graph[cur]:
                    if j not in vis: que.append(j)
                    elif j == target: return steps + 1
            steps += 1
        return -1
Auto-SK commented 2 years ago

思路

BFS + 反向搜索

程序

class Solution:
    def solve(self, graph, target):
        q = collections.deque([target])
        visited = set()
        steps = 0
        while q:
            for i in range(len(q)):
                cur = q.popleft()
                visited.add(cur)
                for neighbor in graph[cur]:
                    if neighbor not in visited:
                        q.append(neighbor)
                    elif neighbor == target:
                        return steps + 1
            steps += 1
        return -1

复杂度

heyqz commented 2 years ago
class Solution:
    def solve(self, graph, target):
        q = deque([target])
        visited = set()
        steps = 0
        while q:
            for i in range(len(q)):
                cur = q.popleft()
                visited.add(cur)
                for nei in graph[cur]:
                    if nei not in visited:
                        q.append(nei)
                    elif nei == target:
                        return steps + 1
            steps += 1
        return -1
yanglr commented 2 years ago

思路:

本题的输入比较特别, 需要自己先好好理解一下。

方法: BFS

从目标节点target开始往后一层一层遍历

1.先遍历target向后连接的节点们,再遍历这些节点们向后连接的节点们

2.如果遍历回target了,那就返回到目前为止遍历的次数,也就是环的大小

3.如果循环结束也没有返回,说明target不在环里,返回-1

4.遍历的过程中,注意已经遍历过的节点不能再遍历了,否则循环结束不了


代码

实现语言: C++

int solve(vector<vector<int>>& graph, int target) {
    queue<int> q;
    unordered_set<int> visited;
    q.push(target);
    int res = 0;
    while(!q.empty())
    {
        res++;
        int size = q.size();
        for(int i = 0; i < size; i++)
        {
            int cur = q.front();
            q.pop();
            for(int& next : graph[cur])
            {
                if(next == target)
                {
                    return res;
                }
                if (visited.count(next))
                    continue;
                visited.insert(next);
                q.push(next);
            }
        }
    }
    return -1;    
}

复杂度分析

xieyj17 commented 2 years ago
class Solution:
    def solve(self, graph, target):
        queue = deque()
        queue.append((target,0))
        visited = set()
        while queue:
            for i in range(len(queue)):
                curr, length = queue.popleft()
                if curr in visited:
                    continue
                for j in graph[curr]:
                    if j == target:
                        return length+1
                    queue.append([j, length+1])
                visited.add(curr)
        return -1

Time: O(N*M) every combination of node and edge

Space: O(N)

chakochako commented 2 years ago
class Solution:
    def solve(self, graph, target):
        visited = set()
        layer = [target]
        length = 0

        while layer:
            length += 1
            next_layer = []
            for u in layer:
                for v in graph[u]:
                    if v == target:
                        return length
                    if v in visited:
                        continue
                    visited.add(v)
                    next_layer.append(v)
            layer = next_layer

        return -1
joriscai commented 2 years ago

思路

代码

javascript

class Solution {
  solve(graph, target) {
    const queue = [target]
    const visited = {}
    let steps = 0
    while (queue.length) {
      let levelLen = queue.length
      while (levelLen--) {
        const node = queue.shift()
        visited[node] = true
        const list = graph[node]
        for (let i = 0; i < list.length; i++) {
          const neighbor = list[i]
          if (!visited[neighbor]) {
            queue.push(neighbor)
          } else if (neighbor === target) {
            return steps + 1
          }
        }
      }
      steps += 1
    }
    return -1
  }
}

复杂度分析

yibenxiao commented 2 years ago

【Day 52】Shortest-Cycle-Containing-Target-Node

思路

BFS,反向搜索

代码

class Solution:
    def solve(self, graph, target):
        q = collections.deque([target])
        visited = set()
        steps = 0
        while q:
            for i in range(len(q)):
                cur = q.popleft()
                visited.add(cur)
                for neighbor in graph[cur]:
                    if neighbor not in visited:
                        q.append(neighbor)
                    elif neighbor == target:
                        return steps + 1
            steps += 1
        return -1

复杂度

时间复杂度:O(V+E)

空间复杂度:O(V)

falsity commented 2 years ago
import java.util.*;

class Solution {
    public int solve(int[][] graph, int target) {
        boolean[] visited = new boolean[graph.length];
        Queue<Integer> q = new LinkedList<>();
        q.add(target);

        int level = 0;
        while (!q.isEmpty()) {
            int size = q.size();
            for (int i = 0; i < size; i++) {
                int tmp = q.remove();
                visited[tmp] = true;

                for (int neighbor : graph[tmp]) {
                    if (neighbor == target)
                        return level + 1;
                    else if (!visited[neighbor])
                        q.add(neighbor);
                }
            }

            level++;
        }

        return -1;
    }
}

时间复杂度:O(V+E)

空间复杂度:O(V)

vaqua commented 2 years ago

思路

BFS target为起点

class Solution{
    solve(graph, target) {
        let q = [target]
        let v = new Set([])
        let ans = 0
        while(q.length > 0) {
            ans++
            let size = q.length
            for(let i = 0; i < size; i++) {
                for(let next of graph[q.shift()]) {
                    if(next === target) {
                        return ans
                    } else if (!v.has(next)) {
                        v.add(next)
                        q.push(next)
                    }
                }
            }
        }
        return - 1
    }
}

复杂度分析

时间复杂度:O(n+e),n为节点数,e为边数
空间复杂度:O(n)

ZETAVI commented 2 years ago
class Solution {
    public int solve(int[][] graph, int target) {
        HashSet<Integer> visited = new HashSet();
        Queue<Integer> fringe = new ArrayDeque();
        visited.add(target);
        fringe.offer(target);

        int res = 0;
        while (!fringe.isEmpty()) {
            int size = fringe.size();
            for (int i = 0; i < size; i++) {
                int cur = fringe.poll();
                for (int neighbor : graph[cur]) {
                    if (neighbor == target) {
                        return res + 1;
                    }
                    if (visited.contains(neighbor)) {
                        continue;
                    }
                    visited.add(neighbor);
                    fringe.offer(neighbor);
                }
            }
            res++;
        }

        return -1;
    }
}

复杂度分析

时间复杂度:O(N+E),N为节点数,E为边数 空间复杂度:O(N)

lihuiwen commented 2 years ago

代码

class Solution {
  solve(graph, target) {
    const queue = [target]
    const visited = {}
    let steps = 0
    while (queue.length) {
      let levelLen = queue.length
      while (levelLen--) {
        const node = queue.shift()
        visited[node] = true
        const list = graph[node]
        for (let i = 0; i < list.length; i++) {
          const neighbor = list[i]
          if (!visited[neighbor]) {
            queue.push(neighbor)
          } else if (neighbor === target) {
            return steps + 1
          }
        }
      }
      steps += 1
    }
    return -1
  }
}
Richard-LYF commented 2 years ago

def solve(self, graph, target): q = collections.deque([target]) visited = set() steps = 0 while q: for i in range(len(q)): cur = q.popleft() visited.add(cur) for neighbor in graph[cur]: if neighbor not in visited: q.append(neighbor) elif neighbor == target: return steps + 1 steps += 1 return -1

for123s commented 2 years ago

class Solution { public int solve(int[][] graph, int target) { Deque queue = new LinkedList<>(); queue.offer(target); int level = 0; Set visited = new HashSet<>(); // use set to track visited nodes, used to check cycles // stop the while loop when all the edges have been checked while (!queue.isEmpty()) {
// visit nodes level by level
level++; Set levelnodes = new HashSet<>(); // use to store nodes in the current level, exclude duplicates, this set is not necessary int size = queue.size(); // save initial queue's size here, cannot use queue.size() in the for loop, because queue.size() keeps changing for (int j = 0; j < size; j++) { int node = queue.poll(); visited.add(node);
for (int neighbor: graph[node]) { levelnodes.add(neighbor); } } for (int cur: levelnodes) { // detect a cycle if (visited.contains(cur)) { if (cur == target) return level; // level is the length of the shortest cycle } else queue.offer(cur); // if no cycle, put node in this level into the queue }
}
return -1;
} }

KennethAlgol commented 2 years ago
    public int solve(int[][] graph, int target) {
        boolean[] visited = new boolean[graph.length];
        Queue<Integer> queue = new LinkedList<>();
        queue.add(target);
        visited[target] = true;
        int step = 0;
        while (!queue.isEmpty()) {
            int size = queue.size();
            for (int i = 0; i < size; i++) {
                int cur = queue.poll();
                for (int next : graph[cur]) {
                    if (next == target) {
                        return step + 1;
                    } else if (!visited[next]) {
                        visited[next] = true;
                        queue.add(next);
                    }
                }
            }
            step++;
        }
        return -1;
    }
jaysonss commented 2 years ago

思路

BFS

代码

class Solution {
    int min = Integer.MAX_VALUE;
    public int solve(int[][] graph, int target) {
        int[] visited = new int[graph.length];

        LinkedList<Integer> queue = new LinkedList<>();
        queue.offerLast(target);
        visited[target]=1;
        int step = 0;

        while(!queue.isEmpty()){
            int size = queue.size();
            for(int i = 0;i<size;i++){
                int first = queue.pollFirst();

                for(int neighbor : graph[first]){
                    if(visited[neighbor] == 1){
                        if(neighbor == target){
                            return step + 1;
                        }else {
                        }
                    }else {
                        visited[neighbor] = 1;
                        queue.offerLast(neighbor);
                    }
                }
            }
            step++;
        }
        return -1;
    }
}
kennyxcao commented 2 years ago

Shortest Cycle Containing Target Node

Problem Source

Intuition

Code

class Solution {
  solve(graph, target) {
    const queue = [target]
    const visited = new Set()
    let steps = 0
    while (queue.length > 0) {
      steps += 1;
      for (let i = queue.length - 1; i >= 0; i--) {
        const node = queue.shift()
        visited.add(node);
        for (const neighbor of graph[node]) {
          if (neighbor === target) return steps;
          if (!visited.has(neighbor)) {
            queue.push(neighbor)
          }
        }
      }
    }
    return -1
  }
}

Complexity Analysis