LWC 53:694. Number of Distinct Islands

LWC 53:694. Number of Distinct Islands

传送门:694. Number of Distinct Islands

Problem:

Given a non-empty 2D array grid of 0’s and 1’s, an island is a group of 1’s (representing land) connected 4-directionally (horizontal or vertical.) You may assume all four edges of the grid are surrounded by water. Count the number of distinct islands. An island is considered to be the same as another if and only if one island can be translated (and not rotated or reflected) to equal the other.

Example 1:

11000 11000 00011 00011 Given the above grid map, return 1.

Example 2:

11011 10000 00001 11011 Given the above grid map, return 3. Notice that: 1 1 1 and 1 1 1 are considered different island shapes, because we do not consider reflection / rotation.

Note:

The length of each dimension in the given grid does not exceed 50.

思路: 首先dfs求出每个区域,并记录每个区域的起点,接着根据这些起点再dfs一次,判断四个方向上的长度是否相同。比如:

0 1 0 0 0 1 0
1 1 1 0 1 1 1
0 1 0 0 0 1 0

可以记录每个位置上四个方向的延伸长度,如果每个位置的上的四个值均相同,则说明两个区域重复。

实际上超时,可以采用HASH的思想,在第一次DFS时,就把四个方向的信息取回来,最终存一个起点的HASH值即可。

代码如下:

    int[][] dir = {{1, 0},{0, 1},{-1, 0},{0, -1}};
    int[][] dp = new int[50 * 50 + 16][5]; // four direction

    boolean[][] vis = new boolean[52][52];
    int n, m;

    Set<Integer> set = new HashSet<>();
    public int numDistinctIslands(int[][] grid) {
        n = grid.length;
        if (n == 0) return 0;
        m = grid[0].length;
        if (m == 0) return 0;
        vis = new boolean[52][52];
        for (int i = 0; i < n; ++i) {
            for (int j = 0; j < m; ++j) {
                if (grid[i][j] == 1) {
                    if (!vis[i][j]) {
                        si = i;
                        sj = j;
                        dfs(grid, i, j);
                        set.add(dp[i * m + j][4]);
                    }
                }
            }
        }

        return set.size();
    }

    boolean check(int i, int j) {
        return i >= 0 && i < n && j >= 0 && j < m;
    }

    int si, sj;
    public int[] dfs(int[][] grid, int x, int y) {
        vis[x][y] = true;

        for (int k = 0; k < 4; ++k) {
            int[] d = dir[k];
            int nx = d[0] + x;
            int ny = d[1] + y;
            if (check(nx, ny) && !vis[nx][ny] && grid[nx][ny] == 1) {
                dp[x * m + y][k] = 1 + dfs(grid, nx, ny)[k];
                dp[x * m + y][4] += (dp[nx * m + ny][4] + 1) * (k + 1);
            }
        }

        for (int k = 0; k < 4; ++k) {
            dp[x * m + y][4] += (((x - si + 1) * m + (y - sj + 1)) * 177) *  (dp[x * m + y][k] + 1) * (k + 1);
        }

        return dp[x * m + y];
    }

上述代码采用数值的做法,当然,你也可以直接遍历一条链,以字符串的形式存储遍历的顺序,理解起来更直观,代码如下:

    int[][] dir = {{1, 0},{0, 1},{-1, 0},{0, -1}};
    char[]  c   = {'D','R','U','L'};
    int n, m;

    boolean[][] vis;

    public int numDistinctIslands(int[][] grid) {
        n = grid.length;
        if (n == 0) return 0;
        m = grid[0].length;
        if (m == 0) return 0;
        vis = new boolean[n][m];
        Set<String> set = new HashSet<>();
        for (int i = 0; i < n; ++i) {
            for (int j = 0; j < m; ++j) {
                if (grid[i][j] == 1 && !vis[i][j]) {
                    si = i;
                    sj = j;
                    set.add(dfs(grid, i, j));
                }
            }
        }
        return set.size();
    }

    int si, sj;
    public String dfs(int[][] grid, int i, int j) {
        String ans = "" + ((i - si) * m + (j - sj));
        vis[i][j] = true;
        for (int k = 0; k < 4; ++k) {
            int[] d = dir[k];
            int ni = d[0] + i;
            int nj = d[1] + j;
            if (check(ni, nj) && !vis[ni][nj] && grid[ni][nj] == 1) {
                ans += c[k] + dfs(grid, ni, nj);
            }
        }
        return ans;
    }

    boolean check(int i, int j) {
        return i >= 0 && i < n && j >= 0 && j < m;
    }

注意:把相对位置的信息带进来,否则个别案例过不了。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏大数据学习笔记

TensorFlow学习笔记:2、TensorFlow超简单入门程序

TensorFlow学习笔记:2、TensorFlow超简单入门程序 2.1 HelloWorld代码说明 import tensorflow as tf ...

2165
来自专栏落影的专栏

iOS开发-OpenGL ES入门教程1

前言 这里是一篇新手教程,环境是Xcode7+OpenGL ES 2.0,目标写一个OpenGL ES的hello world。 OpenGL ES系列教程在...

2949
来自专栏YoungGy

【优化2】整数优化

概述 IP类型 建立IP 逻辑型 或的逻辑约束 三个选择的或 只有才 更多或 整数可除 多边形组合 固定花费 分段线性 组合型 set covering set...

2175
来自专栏NewbieWeb

ThreeJS的DeviceOrientationControls源代码解析

在学习ThreeJS和WebGL的过程中想着实现一个基于手机陀螺仪的3D环绕视角的例子,遇到了很多困难,一直都没有完成;后来发现ThreeJS中已经有了类似的例...

361
来自专栏数据结构与算法

3110 二叉堆练习3

3110 二叉堆练习3 时间限制: 3 s 空间限制: 128000 KB 题目等级 : 黄金 Gold 题目描述 Description 给定N...

2695
来自专栏wym

卡特兰数

      简介:卡特兰数又称卡塔兰数,英文名Catalan number,是组合数学中一个常出现在各种计数问题中出现的数列。由以比利时的数学家欧仁·查理·卡塔...

820
来自专栏深度学习之tensorflow实战篇

Python生成词云图,TIIDF方法文本挖掘: 词频统计,词云图

python中使用wordcloud包生成的词云图。 下面来介绍一下wordcloud包的基本用法。 class wordcloud.WordCloud(fon...

3586
来自专栏武培轩的专栏

剑指Offer-矩形覆盖

package Recursion; /** * 我们可以用2*1的小矩形横着或者竖着去覆盖更大的矩形。请问用n个2*1的小矩形无重叠地覆盖一个2*n的大矩...

2634
来自专栏一“技”之长

Cocos2d-x-v3动作体系 原

        cocos2d-x-v3版本v2的版本有的很大的改动,最直观的是在一些函数的改动和类名的改动上,首先以CC开头的类,都不再使用CC。在我个人的理...

551
来自专栏烙馅饼喽的技术分享

Silverlight像素着色器编写简明指南 附送文字描边效果

      在玩很多flash网页游戏的时候,看到它们都有非常清晰的宋体字,并且有漂亮的描边效果。如图,这是战将传奇的登录界面中的文字。 ? 对比之下,silv...

1797

扫码关注云+社区