题意:二维数组,1表示岛屿,岛屿都是边相连的,有且仅有一个岛。问岛的周长是多少?
solution 1:hash。每访问一个点,就将四周的点的sibling数+1。hash记录坐标-sibling数。原因在于一个点有4条边,每多一个sibling,有效边就少一条。这种方法需要访问所有为1的点,并将其四周的sibling进行操作。
note:如果使用unordered_map会报错,原因是unordered_map对pair没有默认的hash函数。
solution 2:每一个1有四条边,有相邻的岛屿则需要扣除一条边。相邻的情况可以分为上下、左右,因为相邻一定涉及到两个岛屿,因此只需要两个岛屿中的一个做出相应即可,否则会多扣。因此规定只响应右边和下边的相邻。
总结:实际上算法是一样的。本质上都是基于一个“1”*4,然后相邻-1。实现的手段不重要,总的是如何高效的实现算法。
class Solution {
public:
int islandPerimeter(vector<vector<int>>& grid) {
// 1. hash
map<pair<int, int>, int> hash; // x,y - count
int res = 0;
for ( int i = 0; i < grid.size(); i++ ) {
for ( int j = 0; j < grid[i].size(); j++ ) {
if ( grid[i][j] != 0 ) {
pair<int, int> locn = make_pair(i-1, j);
pair<int, int> locs = make_pair(i+1, j);
pair<int, int> locw = make_pair(i, j-1);
pair<int, int> loce = make_pair(i, j+1);
hash[locn]--;
hash[locs]--;
hash[locw]--;
hash[loce]--;
}
}
}
for ( int i = 0; i < grid.size(); i++ ) {
for ( int j = 0; j < grid[i].size(); j++ ) {
if ( grid[i][j]!=0 ) {
int sibling = 0;
pair<int, int> loc = make_pair(i, j);
if ( hash.find(loc) != hash.end() )
sibling = hash[loc];
res += ( 4 + sibling );
}
}
}
return res;
// 2. count and repeat
/*int count = 0, repeat = 0;
for ( int i = 0; i < grid.size(); i++ ) {
for ( int j = 0; j < grid[i].size(); j++ ) {
if ( grid[i][j]==1 ) {
count++;
if ( i+1 < grid.size() && grid[i+1][j]==1 )
repeat++;
if ( j+1 < grid[i].size() && grid[i][j+1]==1 )
repeat++;
}
}
}
return 4*count-2*repeat;*/
}
};
submission:
1. hash
2. count & repeat