• 图-dfs-连通分量-旋转变换-804. 不同岛屿的数量II


    2020-04-04 18:25:18

    问题描述:

    给定一个01的非空的二维数组网格,一个岛是一个1(表示陆地)的组,4个方向(水平或垂直)连接。你可以假设网格的所有四条边都被水包围。
    计算不同岛屿的数量。当一个岛被认为与另一个岛相同时,它们有相同的形状,或在旋转后的形状相同(90,180,或270度)或翻转(左/右方向或向上/向下方向)。

    样例

    Example 1:

    Input: [[1,1,0,0,0],[1,0,0,0,0],[0,0,0,0,1],[0,0,0,1,1]]
    Output: 1
    Explanation:
    The island is look like this:
    11000
    10000
    00001
    00011
    
    Notice that:
    11
    1
    and
     1
    11
    are considered same island shapes. Because if we make a 180 degrees clockwise rotation on the first island, then two islands will have the same shapes.
    

    Example 2:

    Input: [[1,1,1,0,0],[1,0,0,0,1],[0,1,0,0,1],[0,1,1,1,0]]
    Output: 2
    Explanation:
    The island is look like this:
    11100
    10001
    01001
    01110
    
    Here are the two distinct islands:
    111
    1
    and
    1
    1
    
    Notice that:
    111
    1
    and
    1
    111
    are considered same island shapes. Because if we flip the first array in the up/down direction, then they have the same shapes.
    

    注意事项

    每个维度在给定网格的长度不超过50

    问题求解:

        public int numDistinctIslands2(int[][] grid) {
            if (grid == null || grid.length == 0 || grid[0].length == 0) {
                return 0;
            }
            int m = grid.length, n = grid[0].length;
            Set<String> res = new HashSet<>();
            
            for (int i = 0; i < m; ++i) {
                for (int j = 0; j < n; ++j) {
                    if (grid[i][j] == 1) {
                        List<int[]> island = new ArrayList<>();
                        dfs(grid, i, j, island);
                        res.add(getUnique(island));
                    }
                }
            }
            
            return res.size();
        }
        
        private void dfs(int[][]grid, int x, int y, List<int[]> island) {
            int m = grid.length, n = grid[0].length;
            
            island.add(new int[]{x, y});
            grid[x][y] = 0;
            
            int[] dirs = {-1, 0, 1, 0, -1};
            for (int i = 0; i < 4; ++i) {
                int nx = x + dirs[i];
                int ny = y + dirs[i + 1];
                if (nx >= 0 && nx < m && ny >= 0 && ny < n && grid[nx][ny] == 1) {
                    dfs(grid, nx, ny, island);
                }
            }
        }
        
        private String getUnique(List<int[]> island) {
            List<String> sameIslands = new ArrayList<>();
            
            int[][] trans={{1, 1}, {1, -1}, {-1, 1}, {-1, -1}};
            
            for (int i = 0; i < 4; ++i) {
                List<int[]> l1 = new ArrayList<>(), l2 = new ArrayList<>();
                
                for (int[] is : island) {
                    int x = is[0], y = is[1];
                    l1.add(new int[]{x * trans[i][0], y * trans[i][1]});
                    l2.add(new int[]{y * trans[i][0], x * trans[i][1]});
                }
                sameIslands.add(getStr(l1));
                sameIslands.add(getStr(l2));
            }
            
            Collections.sort(sameIslands);
            return sameIslands.get(0);
        }
        
        private String getStr(List<int[]> island) {
            
            Collections.sort(island, (int[] o1, int[] o2) -> o1[0] == o2[0] ? Integer.compare(o1[1], o2[1]) : Integer.compare(o1[0], o2[0]));
            
            StringBuilder sb = new StringBuilder();
            int x = island.get(0)[0], y = island.get(0)[1];
            
            for (int[] point : island) {
                sb.append((point[0] - x) + " " + (point[1] - y) + " ");
            }
            return sb.toString();
        }
    

      

  • 相关阅读:
    STL简介
    Java语言实现简单FTP软件------>上传下载队列窗口的实现(七)
    c++模板
    10891
    错误处理:java.lang.NoSuchMethodException: org.apache.catalina.deploy.WebXml addFilter
    Linux crontab 语法和具体的例子
    LoadImage()使用
    matplotlib简单的新手教程和动画
    三白话经典算法系列 Shell排序实现
    AccountManager教程
  • 原文地址:https://www.cnblogs.com/hyserendipity/p/12633097.html
Copyright © 2020-2023  润新知