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

91 算法第六期打卡仓库
28 stars 0 forks source link

【Day 52 】2022-02-01 - Shortest-Cycle-Containing-Target-Node #62

Open azl397985856 opened 2 years ago

azl397985856 commented 2 years ago

Shortest-Cycle-Containing-Target-Node

入选理由

暂无

题目地址

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

前置知识

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

xinhaoyi commented 2 years ago

Shortest Cycle Containing Target Node

Shortest Cycle Containing Target Node | binarysearch

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.

思路一

使用BFS即可,因为从target结点出发,使用BFS第一个回到target结点的肯定是最小的环,这个环的大小就是我们想要的解

我们额外维护一个visited[] 数组,用来保存某个结点是否被遍历过,如果遍历过了,那么这个结点就不要加入到队列中

代码

import java.util.*;

class Solution {
    public int solve(int[][] graph, int target) {
        //graph.length is the total number of the graph
        boolean[] visited = new boolean[graph.length];
        //generate the queue 
        Queue<Integer> q = new LinkedList<>();
        q.add(target);

        //the initial value is 0, as we don't add tartget knot, We think the target is level 0
        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);
                }
            }
            //The level of BFS
            level++;
        }

        return -1;
    }
}
yan0327 commented 2 years ago
func solve(graph [][]int, target int) int{
    q := []int{}
    hashmap := map[int]int{}
    q = append(q,target)
    out := 0
    for len(q) >0{
        out++
        cur := q[0]
        q = q[1:]
        for _,next := range graph[cur]{
            if next == target{
                return out
            }
            if _,ok := hashmap[next];ok{
                continue
            }
            hashmap[next]++
            q = append(q,next)
        }
    }
    return -1
}
charlestang commented 2 years ago

思路

广度优先搜索。

  1. 我们从 traget 出发,进行广度优先搜索。
  2. 使用一个 visited 集合,将访问过的节点,记录。
  3. 遍历的时候,如果遇到见过的节点,就不用继续遍历下去了。因为不管有没有环,如果一旦遇到遍历过的节点,这个环一定比之前遍历的环更长。
  4. 第二次遇到 target 的时候,就是答案。

时间复杂度 O(V),所有节点会遍历一次

空间复杂度,O(V),需要一个队列。

代码

class Solution:
    def solve(self, graph, target):
        visited = set([target])
        q = deque([target])
        cnt = 1
        while q:
            newq = []
            while q:
                cur = q.popleft()
                for n in graph[cur]:
                    if n == target:
                        return cnt
                    if n not in visited:
                        newq.append(n)
                        visited.add(n)
            q = deque(newq)
            cnt += 1
        return -1
yetfan commented 2 years ago

思路 bfs, 从target开始找环

代码

class Solution:
    def solve(self, graph, target):

        q = [target]
        visited = set()
        res = 0

        while q:
            for i in range(len(q)):
                cur = q.pop(0)
                visited.add(cur)
                for neib in graph[cur]:
                    if neib not in visited:
                        q.append(neib)
                    elif neib == target:
                        return res + 1
            res += 1
        return -1

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

ZacheryCao commented 2 years ago

Idea

BFS

Code

class Solution:
    def solve(self, graph, target):
        stack = collections.deque()
        stack.append(target)
        seen = set()
        seen.add(target)
        ans = 0
        circled = False
        while stack and not circled:
            l = len(stack)
            for _ in range(l):
                cur = stack.popleft()
                for nei in graph[cur]:
                    if nei == target:
                        circled = True
                    if nei not in seen:
                        seen.add(nei)
                        stack.append(nei)
            ans += 1
        if not circled:
            return -1
        return ans

Complexity:

Time: O(E+V) Space: O(E)

yingliucreates commented 2 years ago
const shortestCycle = (graph, target) => {
  const queue = [[target, 0]];
  const visited = new Set();

  while (queue.length) {
    for (let i = 0; i < queue.length; i++) {
      const [curr, distance] = queue.shift();
      if (visited.has(String(curr))) continue;
      for (let neighbor of graph[curr]) {
        if (neighbor === target) return distance + 1;
        queue.push([neighbor, distance + 1]);
      }
      visited.add(String(curr));
    }
  }
  return -1;
};
LinnSky commented 2 years ago

思路

BFS

代码

     const shortestCycle = (graph, target) => {
        const queue = [[target, 0]];
        const visited = new Set();

        while (queue.length) {
          for (let i = 0; i < queue.length; i++) {
            const [curr, distance] = queue.shift();
            if (visited.has(String(curr))) continue;
            for (let neighbor of graph[curr]) {
              if (neighbor === target) return distance + 1;
              queue.push([neighbor, distance + 1]);
            }
            visited.add(String(curr));
          }
        }
        return -1;
      };
falconruo commented 2 years ago

思路:

使用BFS即可,因为从target结点出发

复杂度分析:

代码(C++):

int solve(vector<vector<int>>& graph, int target) {
    set<int> visited;

    queue<int> qt;
    qt.push(target);

    int res = 0;
    while (!qt.empty()) {
        size_t size = qt.size();

        while (size--) {
            int node = qt.front();
            qt.pop();

            visited.insert(node);
            for (auto n : graph[node]) {
                if (!visited.count(n))
                    qt.push(n);
                else if (n == target)
                    return res + 1;
            }
        }
        ++res;
    }

    return -1;
}
cszys888 commented 2 years ago
class Solution:
    def solve(self, graph, target):
        length = 0
        q = [target]
        visited = set()

        while q:
            length += 1
            new_q = []
            for node in q:
                for j in graph[node]:
                    if j == target:
                        return length
                    if j in visited:
                        continue
                    visited.add(j)
                    new_q.append(j)
            q = new_q
        return -1

time complexity: O(v+e) space complexity: O(v)

zhy3213 commented 2 years ago

思路

bfs

代码

    def solve(self, graph, target):
        q=deque(graph[target])
        res=0
        visited=[False]*len(graph)
        for i in graph[target]: visited[i]=True
        while q:
            res+=1
            for _ in range(len(q)):
                cur=q.popleft()
                if cur==target:
                    return res
                q.extend(new:=[i for i in graph[cur] if not visited[i]])
                for i in new: visited[i]=True
        return -1
KennethAlgol commented 2 years ago

'''c++ int solve(vector<vector>& graph, int target) { set visited;

queue<int> qt;
qt.push(target);

int res = 0;
while (!qt.empty()) {
    size_t size = qt.size();

    while (size--) {
        int node = qt.front();
        qt.pop();

        visited.insert(node);
        for (auto n : graph[node]) {
            if (!visited.count(n))
                qt.push(n);
            else if (n == target)
                return res + 1;
        }
    }
    ++res;
}

return -1;

} '''

Tesla-1i commented 2 years ago
class Solution:
    def solve(self, graph, target):
        stack = collections.deque()
        stack.append(target)
        seen = set()
        seen.add(target)
        ans = 0
        circled = False
        while stack and not circled:
            l = len(stack)
            for _ in range(l):
                cur = stack.popleft()
                for nei in graph[cur]:
                    if nei == target:
                        circled = True
                    if nei not in seen:
                        seen.add(nei)
                        stack.append(nei)
            ans += 1
        if not circled:
            return -1
        return ans
feifan-bai 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

zhangzz2015 commented 2 years ago

思路

关键点

代码

C++ Code:


int solve(vector<vector>& graph, int target) {

// use BFS to find min path from target to target. 
vector<bool> visit(graph.size(), false);
queue<int> que; 
que.push(target); 
int level =0; 
while(que.size())
{
    int iSize = que.size(); 
    for(int i=0; i< iSize; i++)
    {
        int topNode = que.front(); 
        que.pop(); 
        for(int j=0; j< graph[topNode].size(); j++)
        {
            if(graph[topNode][j] == target)
               return level+1; 
            if(visit[graph[topNode][j]]==0)
            {
                que.push(graph[topNode][j]); 
                visit[graph[topNode][j]] = 1; 
            }
        }
    }
    level++; 
}
return -1; 
}
alongchong commented 2 years ago

看的评论区答案


class Solution {
    public int solve(int[][] graph, int target) {
        //graph.length is the total number of the graph
        boolean[] visited = new boolean[graph.length];
        //generate the queue 
        Queue<Integer> q = new LinkedList<>();
        q.add(target);

        //the initial value is 0, as we don't add tartget knot, We think the target is level 0
        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;
    }
}
rzhao010 commented 2 years ago

Thoughts BFS, start from target, the first path to get back to target is the minimum circle

Code

    public int solve(int[][] graph, int target) {
        boolean[] visited = new boolean[graph.length];
        Queue<Integer> queue = new LinkedList<>();
        queue.offer(target);
        int level = 0;
        while (!queue.isEmpty()) {
            int size = queue.size();
            for (int i = 0; i < size; i++) {
                int tmp = queue.poll();
                visited[tmp] = true;

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

Complexity Time: O(V) Space: O(V)

CodingProgrammer commented 2 years ago

思路

BFS

代码

class Solution {
    public int solve(int[][] graph, int target) {
        //graph.length is the total number of the graph
        boolean[] visited = new boolean[graph.length];
        //generate the queue 
        Queue<Integer> q = new LinkedList<>();
        q.add(target);

        //the initial value is 0, as we don't add tartget knot, We think the target is level 0
        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;
    }
}

复杂度

LannyX 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
haixiaolu commented 2 years ago

思路

BFS

代码

class Solution:
    def solve(self, graph, target):
        queue = collections.deque([target])
        visited = set()
        steps = 0

        while queue:
            for i in range(len(queue)):
                cur = queue.popleft()
                visited.add(cur)
                for neighbor in graph[cur]:
                    if neighbor not in visited:
                        queue.append(neighbor)
                    elif neighbor == target:
                        return steps + 1
            steps += 1
        return -1 

复杂度分析

z1ggy-o commented 2 years ago

思路

BFS.

按照题目给的 hint 做了. 从 target 开始进行遍历.

因为是 BFS, 当我们第一次发现 target 的时候, 我们就可以确定这个环是最短环. 如果遍历完之后都没有环, 则说明没有包含 target 的环 (但是可能有其他环, 无所谓)

代码

CPP

int solve(vector<vector<int>>& graph, int target) {
    queue<int> q;
    unordered_set<int> visited;
    int step = 0;

    // traverse from the target to find cycle
    visited.insert(target);
    q.push(target);

    while(!q.empty()) {
        int size = q.size();
        for (int i = 0; i < size; i++) {
            int cur = q.front();
            q.pop();
            visited.insert(cur);

            for (auto& n: graph[cur]) {
                if (visited.find(n) == visited.end()) {
                    // new node
                    q.push(n);
                } else if (n == target) {
                    // we get a cycle that contains target
                    return step + 1;
                }
            }
        }
        step += 1;
    }
    // there is no cycle that start from "target"
    return -1;
}

复杂度分析

Bochengwan commented 2 years ago

思路

反向的bfs的search,从target开始search。

代码

class Solution:
    def solve(self, graph, target):
        queue = collections.deque()
        queue += graph[target]
        if len(queue) == 0:
            return -1
        ans = 0
        seen = set(queue)
        while queue:
            n = len(queue)
            ans+=1
            for _ in range(n):
                curr = queue.popleft()

                if curr == target:

                    return ans
                for e in graph[curr]:
                    if e not in seen:
                        queue.append(e)
                        seen.add(e)
        ans = -1
        return ans

复杂度分析

hdyhdy commented 2 years ago

func solve(graph [][]int, target int) int{ q := []int{} hashmap := map[int]int{} q = append(q,target) out := 0 for len(q) >0{ out++ cur := q[0] q = q[1:] for ,next := range graph[cur]{ if next == target{ return out } if ,ok := hashmap[next];ok{ continue } hashmap[next]++ q = append(q,next) } } return -1 }

xvectorizer commented 2 years ago

bfs,同时记录当前层数

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

思路

题目要求某个起点的最小环路长度,直接使用BFS搜索就能满足最小这个条件。

代码

class Solution:
    # DFS(回溯):从起点出发,DFS搜索,复杂度$O(v!)$,超时。
    def solve1(self, graph, target):

        if not graph[target]:
            return -1
        n = len(graph)
        visited = [False] * n

        def dfs(node, depth):
            if not graph[node]:
                return n + 1
            if node == target and depth > 0:
                return depth

            ans = n + 1
            for other in graph[node]:
                if not visited[other]:
                    visited[other] = True
                    ans = min(ans, dfs(other, depth + 1))
                    visited[other] = False
            return ans

        return -1 if (ans := dfs(target, 0)) == n + 1 else ans

    # BFS:以入度构造邻接表,从起点以BFS反推回起点。复杂度$O(v+e)$
    def solve2(self, graph, target):
        n = len(graph)
        pointed = [[] for _ in range(n)]
        for node in range(n):
            for other in graph[node]:
                pointed[other].append(node)
        visited = [False] * n

        q = deque(pointed[target])
        for other in pointed[target]:
            visited[other] = True

        depth = 0
        while q:
            depth += 1
            for _ in range(len(q)):
                node = q.popleft()
                if node == target:
                    return depth
                for other in pointed[node]:
                    if not visited[other]:
                        q.append(other)
                        visited[other] = True
        return -1

    # BFS:上述改进,直接从起点出发,BFS搜到起点。复杂度$O(v+e)$
    def solve(self, graph, target):
        n = len(graph)
        visited = [False] * n

        q = deque(graph[target])
        for other in graph[target]:
            visited[other] = True

        depth = 0
        while q:
            depth += 1
            for _ in range(len(q)):
                node = q.popleft()
                if node == target:
                    return depth
                for other in graph[node]:
                    if not visited[other]:
                        q.append(other)
                        visited[other] = True
        return -1
wdwxw 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;
}

}

tongxw commented 2 years ago

思路

BFS带层搜索

class Solution {
    public int solve(int[][] graph, int target) {
        if (graph[target].length == 0) {
            return -1;
        }

        Queue<Integer> q = new LinkedList<>();
        boolean[] visited = new boolean[graph.length];
        q.offer(target);

        int step = 0;
        while (!q.isEmpty()) {
            int size = q.size();
            for (int i=0; i<size; i++) {
                int v = q.poll();
                for (int adj : graph[v]) {
                    if (!visited[adj]) {
                        if (adj == target) {
                            return step + 1;
                        }
                        visited[adj] = true;
                        q.offer(adj);
                    }
                }
            }
            step++;
        }

        return -1;
    }
}

TC: O(V+E) SC: O(V)

zhiyuanpeng 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
tian-pengfei commented 2 years ago
int solve(vector<vector<int>>& graph, int target) {
     vector<int> flag;
      int n ;
        n = graph.size();
        flag.resize(n,0);
        deque<int> q;
        for(auto & a: graph[target]){
            q.emplace_back(a);
            if(a==target)return 1;
            flag[a]=1;
        }
        int step = 1;
        while (!q.empty()){
            step++;
            int length = q.size();
            for (int i = 0; i < length; ++i) {
                auto v = q.front();
                q.pop_front();
                for(auto & a: graph[v]){

                    if(a==target)return step;
                    if(flag[a])continue;
                    q.emplace_back(a);
                    flag[a]=1;
                }
            }

        }
        return -1;

    }
JudyZhou95 commented 2 years ago

代码

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

        while q:
            l = len(q)
            for i in range(l):
                cur = q.pop(0)
                visited.add(cur)
                for neighbor in graph[cur]:
                    if neighbor not in visited:
                        q.append(neighbor)
                    elif neighbor == target:
                        return level+1
            level += 1

        return -1

复杂度

TC: O(V+E)\ SC:O(V)

ZJP1483469269 commented 2 years ago
class Solution:
    def solve(self, graph, target):
        dq = []

        dq.append((target,0))
        vis = set()
        vis.add(target)

        while dq:
            x , layer = dq.pop(0)
            for i in graph[x]:
                if i == target:
                    return layer + 1
                if i not in vis:
                    dq.append((i ,layer + 1))
                    vis.add(i)

        return -1
ray-hr commented 2 years ago

代码

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

approach: bfs


code:

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

        int len = 0;
        while (!queue.isEmpty()) {
            int size = queue.size();
            for (int i = 0; i < size; i ++) {
                int t = queue.remove();
                visited[t] = true;

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

complexity:

Time: O(V + E)

Space: O(V)

hx-code 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

declan92 commented 2 years ago

思路
==>从target出度顶点中,寻找至target的最短路径
步骤

  1. 遍历target的出度顶点;
  2. 使用BFS求出每个顶点值target的距离,打擂台获取最小值;
    java code

    class Solution {
    public int solve(int[][] graph, int target) {
        int ans = Integer.MAX_VALUE;
        int n = graph.length;
        if(target<0||target>=n){
            return -1;
        }
        int m = graph[target].length;
        for(int i = 0;i<m;i++){
            ans = Math.min(bfs(graph,target,graph[target][i]),ans);
        }
        if(ans == Integer.MAX_VALUE){
            return -1;
        }
        return ans;
    }
    
    public int bfs(int[][] graph,int target,int i){
        Set<Integer> visited = new HashSet();
        Queue<int[]> queue = new LinkedList();
        queue.add(new int[]{i,1});
        while(!queue.isEmpty()){
            int[] vertex = queue.poll();
            int val = vertex[0];
            int dis = vertex[1];
            if(visited.contains(val)){    
                continue;
            }
            if(val==target){
                return dis;
            }
            visited.add(val);
            for(int k = 0;k<graph[val].length;k++){
                if(!visited.contains(graph[val][k])){
                    queue.offer(new int[]{graph[val][k],dis+1});
                }
            }
        }
        return Integer.MAX_VALUE;
    }
    }

    时间:O($nm^2$),n为graph的长度,m为target的出度
    空间:O($m
    n$),queue和visited长度

lilililisa1998 commented 2 years ago

func solve(graph [][]int, target int) int{ q := []int{} hashmap := map[int]int{} q = append(q,target) out := 0 for len(q) >0{ out++ cur := q[0] q = q[1:] for ,next := range graph[cur]{ if next == target{ return out } if ,ok := hashmap[next];ok{ continue } hashmap[next]++ q = append(q,next) } } return -1 }

wenlong201807 commented 2 years ago

代码块


const shortestCircle = (graph, target) => {
  let seen  = false;
  for (let i = 0; i < graph.length; i ++ ) {
    if (graph[i][0] === target ) {
      seen = true; 
      targetPos = i
    }
    if (!graph[i][0]) return -1
  }
  return graph.length 
};

时间复杂度和空间复杂度

Toms-BigData commented 2 years ago

func solve(graph [][]int, target int) int{ q := []int{} hashmap := map[int]int{} q = append(q,target) out := 0 for len(q) >0{ out++ cur := q[0] q = q[1:] for ,next := range graph[cur]{ if next == target{ return out } if ,ok := hashmap[next];ok{ continue } hashmap[next]++ q = append(q,next) } } return -1 }

ZZRebas commented 2 years ago

思路

BFS

代码(Python)

import collections
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

复杂度分析

令 v 节点数, e 为边数。

demo410 commented 2 years ago
ninghuang456 commented 2 years ago
// BFS
 class Solution {
        public int solve(int[][] graph, int target) {
            if (graph[target].length == 0) {
                return -1;
            }

            Queue<Integer> queue = new LinkedList<>();
            boolean[] visited = new boolean[graph.length];
            queue.offer(target);

            int res = 0;
            while (!queue.isEmpty()) {
                int size = queue.size();
                for (int i=0; i<size; i++) {
                    int v = queue.poll();
                    for (int cur : graph[v]) {
                        if (!visited[cur]) {
                            if (cur == target) {
                                return res + 1;
                            }
                            visited[cur] = true;
                            queue.offer(cur);
                        }
                    }
                }
                res++;
            }

            return -1;
        }
    }
stackvoid commented 2 years ago

思路

BFS

代码

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

        int len = 0;
        while (!queue.isEmpty()) {
            int size = queue.size();
            for (int i = 0; i < size; i ++) {
                int t = queue.remove();
                visited[t] = true;

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

算法分析

Time O(V) Space O(1)

junbuer commented 2 years ago

思路

dahaiyidi commented 2 years ago

Problem

Shortest Cycle Containing Target Node

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

++

Medium

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


Note


Complexity


Python

class Sol的ution:
    def solve(self, graph, target):
        visited = set()
        q = [target]
        res = 1
        while len(q):
            # 需要层次信息,因此需要根据q的size进行遍历
            for i in range(len(q)):
                cur = q.pop(0)
                visited.add(cur)
                for nei in graph[cur]:
                    # 遍历邻居
                    if nei not in visited:
                        # 未遍历过,可以添加到q
                        q.append(nei)

                    elif nei == target:
                        # 找到target,可以返回
                        return res

            res += 1

        return -1

C++

From : https://github.com/dahaiyidi/awsome-leetcode

ZhangNN2018 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
baddate commented 2 years ago
int solve(vector<vector<int>>& graph, int target) {
    bool visited[graph.size()];
    memset(visited, false, sizeof(visited));
    queue<int> q;
    q.push(target);
    int ans = 0;
    visited[target] = true;
    while (!q.empty()) {
        ans++;
        int n = q.size();
        for (int i = 0; i < n; i++) {
            int x = q.front();
            q.pop();
            vector<int> v = graph[x];
            for (int j = 0; j < v.size(); j++) {
                if (v[j] == target) return ans;
                if (!visited[v[j]]) q.push(v[j]);
                visited[v[j]] = true;
            }
        }
    }
    return -1;
}
Hacker90 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

for123s commented 2 years ago
int solve(vector<vector<int>>& graph, int target) {
    set<int> visited;

    queue<int> qt;
    qt.push(target);

    int res = 0;
    while (!qt.empty()) {
        size_t size = qt.size();

        while (size--) {
            int node = qt.front();
            qt.pop();

            visited.insert(node);
            for (auto n : graph[node]) {
                if (!visited.count(n))
                    qt.push(n);
                else if (n == target)
                    return res + 1;
            }
        }
        ++res;
    }

    return -1;
}
spacker-343 commented 2 years ago

思路

bfs,从target结点开始按层扩散

代码

import java.util.*;

class Solution {
  public int solve(int[][] graph, int target) {
    Queue<Integer> queue = new LinkedList<>();
    queue.add(target);
    Set<Integer> set = new HashSet<>();
    int steps = 0;
    set.add(target);
    while (!queue.isEmpty()) {
      int size = queue.size();
      for (int j = 0; j < size; j++) {
        int cur = queue.poll();
        for (int i : graph[cur]) {
          if (i == target) {
            return steps + 1;
          }
          if (!set.contains(i)) {
            queue.add(i);
            set.add(i);
          }
        }
      }
      steps++;
    }
    return -1;
  }
}
eliassama 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
Alfie100 commented 2 years ago

题目链接: Shortest Cycle Containing Target Node https://binarysearch.com/problems/Shortest-Cycle-Containing-Target-Node

解题思路

target 出发,进行 BFS,若能回到 target,则当前路径长度即为满足题意的解。

代码

class Solution:
    def solve(self, graph, target):

        if target > len(graph):
            return -1

        deque = collections.deque([target])
        visited = set()

        step = 0
        while deque:
            step += 1
            for _ in range(len(deque)):
                u = deque.popleft()
                for v in graph[u]:  # 下一步将回到起点 target
                    if v == target:
                        return step
                    if v not in visited:
                        deque.append(v)
                        visited.add(v)

        return -1

复杂度分析