zoukankan      html  css  js  c++  java
  • LC 711. Number of Distinct Islands II

    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 they have the same shape, or have the same shape after rotation (90, 180, or 270 degrees only) or reflection (left/right direction or up/down direction).

    Example 1:

    11000
    10000
    00001
    00011
    

    Given the above grid map, return 1. 

    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:

    11100
    10001
    01001
    01110

    Given the above grid map, return 2.

    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.

     

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

    这道题的难度比较大,涉及到的细节也很多,是一道很好的题。

    注意几个细节:

    1. set 由红黑树实现,unordered_set由哈希表实现,所以想要给vector去重,要用set。

    2. for(auto l : s) ... 这个时候l是一个value,而for(auto &l : s) ... 这个时候l是一个reference。

    3. 上下左右翻转,旋转90,180,270,对于一个(x,y)来讲正好对应8种情况。((+/-)(x/y),(+/-)()),可以自己推一遍。

    4. 在norm函数里,有两次排序,这两次排序至关重要,第一次是对每一个翻转情况中的点进行排序,这一次排序的目的是为了让

    两个ISLAND对应的翻转中最小的点排到第一个来,这样做的目的是因为只有这样,之后两个ISLAND以该点作为原点进行计算时,

    两个ISLAND才能得到一样的点的序列。

    第二次排序是为了在所有可能中拿点序最小的一个,拿最大也可以,只要把这八个可能用一个来表示就行了,然后插入集合中,利用

    set进行去重。

    好题。

    #include "header.h"
    #include <unordered_set>
    #define ALL(x) (x).begin(), (x).end()
    #define FOR(i, a, b) for (remove_cv<remove_reference<decltype(b)>::type>::type i = (a); i < (b); i++)
    #define REP(i, n) FOR(i, 0, n)
    #define PRINT1D(x) do {REP(i,(x).size()) cout << x[i] << " "; cout << endl;} while 0;
    
    #define PRINT1D(X)          
    {                           
      REP(i, (X).size()){       
      cout << (X)[i] << " ";    
      }                         
      cout << endl;             
    }                           
    
    #define PRINT2D(X)                
    {                                 
      REP(i, (X).size()){             
        REP(j,(X)[0].size()){         
          cout << (X)[i][j] << " ";   
        }                             
      cout << endl;                   
      }                               
      cout << endl;                   
    }                                 
    
    
    
    
    class Solution {
    private:
        unordered_map<int, vector<pair<int,int> > > map;
    public:
        void dfs(vector<vector<int>>& grid, int r, int c, int cnt){
          grid[r][c] = 0;
          map[cnt].push_back({r,c});
          int n = grid.size();
          int m = grid[0].size();
          if(r < n && r >= 0 && c < m && c >= 0 && grid[r][c] == 1){
            dfs(grid, r+1, c, cnt);
            dfs(grid, r, c+1, cnt);
            dfs(grid, r-1, c, cnt);
            dfs(grid, r, c-1, cnt);
          }
        }
    
        vector<pair<int,int>> norm(vector<pair<int,int>> originalshape){
          vector<vector<pair<int,int>>> s(8);
          //sort(ALL(originalshape));
          for(auto p : originalshape){
            int x = p.first, y = p.second;
            s[0].push_back({x,y});
            s[1].push_back({x,-y});
            s[2].push_back({-x,-y});
            s[3].push_back({-x,y});
            s[4].push_back({y,-x});
            s[5].push_back({-y,-x});
            s[6].push_back({-x,-y});
            s[7].push_back({y,x});
          }
          //sort(ALL(s));
          for(auto &l : s ) sort(ALL(l));
          for(auto &l : s){
            auto l1st = l[0];
            REP(i,l.size()){
              l[i].first = l[i].first - l1st.first;
              l[i].second = l[i].second - l1st.second;
            }
            l1st.first = 0;
            l1st.second = 0;
          }
          sort(ALL(s));
          return s[0];
        };
    
        int numDistinctIslands2(vector<vector<int>>& grid) {
          set<vector<pair<int,int>>> s;
          int cnt = 0;
          REP(i,grid.size()){
            REP(j,grid[0].size()){
              if(grid[i][j] == 1){
                dfs(grid, i, j, ++cnt);
                s.insert(norm(map[cnt]));
              }
            }
          }
          return s.size();
        }
    };
    
    
    
    int main() {
      vector<vector<int>> mtx(4,vector<int>(4,0));
      set<vector<int>>s;
      Solution s1 = Solution();
      s1.numDistinctIslands2(mtx);
    }
  • 相关阅读:
    微信开发:微信js_sdk分享,使用场景,网页在微信app内部分享时的标题与描述,包括logo设置(一)
    云服务最开始的初始密码与远程连接密码?
    阿里云域名的ssl证书申请与腾讯服务器域名的证书安装
    关于 https的SNI问题
    关于网页授权access_token和普通access_token的区别
    转载:敏捷开发框架的优势
    select自定义下拉三角符号,css样式小细节
    关于ffmpeg /iis 8.5 服务器下,视频截取第一帧参数配置
    C# WebAPI中使用Swagger
    面向对象编程思想(OOP)
  • 原文地址:https://www.cnblogs.com/ethanhong/p/10166609.html
Copyright © 2011-2022 走看看