1. 程式人生 > >LC 711. Number of Distinct Islands II

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);
}