帖子

  • SomeBottle

    力扣 LeetCode

    图片

    3310. 移除可疑的方法 - 力扣(LeetCode)

    3310. 移除可疑的方法 - 你正在维护一个项目,该项目有 n 个方法,编号从 0 到 n - 1。

    给你两个整数 n 和 k,以及一个二维整数数组 invocations,其中 invocations[i] = [ai, bi] 表示方法 ai 调用了方法 bi。

    已知如果方法 k 存在一个已知的 bug。那么方法 k 以及它直接或间接调用的任何方法都被视为 可疑方法...


    思路

    很典型的有向图问题,可以上 DFS。

    注意题目要求的是一组方法没有被另外任何方法调用时才能移除,也就是说我用 DFS 从 k 开始找到一串可疑方法后,这一串可疑方法如果其中有一个被其他方法调用了,这一串都不能移除。

    显然我们关注的是每个节点有多少入边,这题比较适合用邻接表来存图。DFS 每扫到一个可疑方法,就可以拆掉这个可疑方法的出边(相应节点入度 -1),因为被可疑方法调用不影响可疑方法的移除。

    最后扫描可疑方法,要求所有可疑方法的入度都是 0 才能移除,否则保留所有可疑方法。


    思路```
    class Solution {
    public:
    vector<int> remainingMethods(int n, int k, vector<vector<int>>& invocations) {
    // 有向图,且我们在意每个节点的入度
    // 被标记为可疑节点后其出边可以拆除
    vector<int> in(n,0);
    // 邻接表存图
    vector<vector<int>> adjList(n);
    for(vector<int>& p:invocations){
    adjList[p[0]].emplace_back(p[1]);
    in[p[1]]++;
    }
    // 先从 k 出发,DFS 标记所有可疑节点
    vector<bool> visited(n,false);
    vector<bool> suspicious(n,false);
    auto dfs=[&](auto&& self, int curr){
    if(visited[curr]){
    return;
    }
    visited[curr]=true;
    suspicious[curr]=true;
    // 顺便拆掉所有出边
    for(int next:adjList[curr]){
    in[next]--;
    self(self,next);
    }
    };
    dfs(dfs,k);
    bool removable=true;
    // 所有 suspicious 节点都没有被其他调用才能移除
    for(int i=0;i<n;i++){
    if(suspicious[i]&&in[i]>0){
    removable=false;
    break;
    }
    }
    vector<int> res;
    for(int i=0;i<n;i++){
    if(!suspicious[i]||!removable){
    res.emplace_back(i);
    }
    }
    return res;
    }
    };

    主楼
  • 魔法师

    思路

    题目挺简单的,但是要 认 真 看 题!!!

    今天一看题,第一想法,把调用k的方法断掉,并查集秒了。

    写完之后把案例放上去一看,天塌了,题目要求

    *方法 k 以及它直接或间接调用的任何方法都被视为 可疑方法*

    我给想成

    *方法 k 以及直接或间接调用它的任何方法都被视为 可疑方法*

    之后一直在并查集上修修补补发现好像不行。

    重新梳理后改用BFS。先把可疑方法染色,然后检查是否有方法调用被染色的方法,如果没有输出没被染色的方法,否则输出所有方法。

    代码```
    class Solution {
    public List<Integer> remainingMethods(int n, int k, int[][] invocations) {
    List<Integer>[] path = new List[n];
    for (int i = 0; i < n; i++) {
    path[i] = new ArrayList<>();
    }
    for (int[] invocation : invocations) {
    path[invocation[0]].add(invocation[1]);
    }
    boolean[] visited = new boolean[n];
    Queue<Integer> queue = new ArrayDeque<>();
    queue.add(k);
    while (!queue.isEmpty()) {
    int cur = queue.poll();
    visited[cur] = true;
    for (int next : path[cur]) {
    if (!visited[next]) {
    queue.add(next);
    }
    }
    }
    boolean canRemove = true;
    for (int[] invocation : invocations) {
    if (!visited[invocation[0]] && visited[invocation[1]]) {
    canRemove = false;
    break;
    }
    }
    List<Integer> ans = new ArrayList<>();
    if (canRemove) {
    for (int i = 0; i < n; i++) {
    if (!visited[i]) {
    ans.add(i);
    }
    }
    } else {
    for (int i = 0; i < n; i++) {
    ans.add(i);
    }
    }
    return ans;
    }
    }

    #1
  • Infinity4B

    算术评级 5 第 418 场周赛 Q2 难度分 1711

    写了一坨效率很低的方法```
    class Node:
    def __init__(self, val):
    self.val=val
    self.children=[]
    self.indegrees=0
    self.outdegrees=0

    def add(self, next):
    self.children.append(next)

    class Solution:
    def remainingMethods(self, n: int, k: int, invocations: List[List[int]]) -> List[int]:
    node_dict = defaultdict()
    for a, b in invocations:
    if a not in node_dict:
    a_node=Node(a)
    node_dict[a]=a_node
    if b not in node_dict:
    b_node=Node(b)
    node_dict[b]=b_node
    a_node=node_dict[a]
    b_node=node_dict[b]
    a_node.add(b)
    a_node.outdegrees+=1
    b_node.indegrees+=1
    visited=[False]*n
    def dfs(i):
    if visited[i]: return
    visited[i]=True
    node_i = node_dict[i]
    for j in node_i.children:
    dfs(j)
    total_indegrees=total_outdegrees=0
    if k in node_dict:
    dfs(k)
    for i in range(n):
    if visited[i]:
    total_indegrees+=node_dict[i].indegrees
    total_outdegrees+=node_dict[i].outdegrees
    else:
    visited[k]=True
    if total_indegrees==total_outdegrees:
    return [i for i in range(n) if not visited[i]]
    else:
    return list(range(n))

    #2
  • Lvvvv

    看懂题目就是bfs/dfs就好。```
    class Solution {
    public:
    vector<int> remainingMethods(int n, int k, vector<vector<int>>& invocations) {
    vector<bool> st(n,false);
    vector<vector<int>> g(n,vector<int>());
    for(const auto& e : invocations) {
    int u = e[0], v = e[1];
    g[u].push_back(v);
    }
    queue<int> q;
    q.push(k);
    st[k] = true;
    while(q.size()) {
    auto u = q.front();
    q.pop();
    for(const auto& v : g[u]) {
    if(!st[v]) {
    st[v] = true;
    q.push(v);
    }
    }
    }
    bool ok = true;
    for(int i = 0; i < n && ok; i++) {
    if(!st[i]) {
    for(const auto& j : g[i]) {
    if(st[j]) {
    ok = false;
    break;
    }
    }
    }
    }
    vector<int> res;
    for(int i = 0; i < n; i++) {
    if(ok && st[i]) continue;
    res.push_back(i);
    }
    return res;
    }
    };

    #3
  • GreenOnion

    这题目是给人类看的吗 ^-^```
    impl Solution {
    pub fn remaining_methods(n: i32, k: i32, invocations: Vec<Vec<i32>>) -> Vec<i32> {
    let n = n as usize;
    let k = k as usize;
    let mut edge: Vec<Vec<usize>> = vec![vec![]; n];
    let mut sus: Vec<bool> = vec![false; n];
    for invocation in invocations.iter() {
    let (a, b) = (invocation[0] as usize, invocation[1] as usize);
    edge[a].push(b);
    }
    fn f(sus: &mut Vec<bool>, edge: &Vec<Vec<usize>>, i: usize) {
    if sus[i] { return; }
    sus[i] = true;
    for &e in edge[i].iter() {
    f(sus, edge, e);
    }
    }
    ```图片

    不知道为啥发不出去, 老是提示Awaiting Approval, 用图片似乎可以 ^-^

    #4
  • doge

    感觉这题主要难点是在于阅读理解。。。```
    class Solution:
    def remainingMethods(self, n: int, k: int, invocations: List[List[int]]) -> List[int]:
    g = [[] for _ in range(n)]
    for u, v in invocations:
    g[u].append(v)

    vis = [0] * n
    def dfs(u):
    vis[u] = 1
    for v in g[u]:
    if not vis[v]:
    dfs(v)

    dfs(k)
    # 无法移除 所有 可疑方法,则 不 移除任何方法
    for u, v in invocations:
    if not vis[u] and vis[v]:
    return list(range(n))

    ans = []
    for i in range(n):
    if not vis[i]:
    ans.append(i)
    return ans

    #5

发表回复

登录后回复