美文网首页
457. Circular Array Loop,用图的方法做

457. Circular Array Loop,用图的方法做

作者: 尚无花名 | 来源:发表于2019-03-10 07:51 被阅读0次

    这题可以直接simulate,也可以用图的思想找环。
    首先我们可以建一个图。
    图上的node上每一个index,每个index只有一条边。
    这条边可能连到别的点, 也可能是连到它自己。
    对于连到他自己的点,这些点不可能有环,所以可以直接略过这些点。

    然后我们从每一个点出发,一直走下去, 看会不会遇到之前已经走过的点。
    我们保持一个visiting的set。
    同时也保持一个visited的array, 如果遇到一个点是visited,证明这个点以前访问过,
    既然以前访问时没到循环,所以就不用再找了。
    如果某个点在这次访问的时候已经访问过了(出现在visiting里),则肯定有个循环。

    class Solution {
        public boolean circularArrayLoop(int[] nums) {
            int N = nums.length;
            int[] nexts = new int[N];
            boolean[] visited = new boolean[N];
            
            //build graph;
            for (int i = 0; i < N; i++) {
                nexts[i] = (i + (nums[i] < 0 ? N + (nums[i] % N) : nums[i])) % N;
                if(nexts[i] == i) visited[i] = true;
            }
            for (int i = 0; i < N; i++) {
                if (!visited[i]) {
                    if (dfsFoundCycle(i, nums, nexts, visited, new HashSet<>())) return true;
                }
            }
            return false;
        }
        private boolean dfsFoundCycle(int index, int[] nums, int[] nexts, boolean[] visited,
                                     Set<Integer> visiting ) {
            // every level only have at most one branch.
            if (!visiting.add(index)) return true;
            if (visited[index]) return false; //visited, no loop
            visited[index] = true;
            
            // check the next step
            int next = nexts[index];
            
            //if next step has different direction,
    
            if (nums[index] * nums[next] < 0) return false;
            
            if (dfsFoundCycle(next, nums, nexts, visited, visiting))  return true;
            
            return false;
        }
    }
    

    相关文章

      网友评论

          本文标题:457. Circular Array Loop,用图的方法做

          本文链接:https://www.haomeiwen.com/subject/nbgypqtx.html