Find Islands

Given matrix MxN of 0s and 1s, return and output all groups of adjacent 1s in form of (row,col)...

1s are considered adjacent if they are adjacent horizontally or vertically.

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

Output:

A: (0,0)(1,0)(0,1)(1,1)(1,2)(1,3)(0,3)
B: (0,5)(1,5)(2,4)(2,5)(3,4)
C: (3,0)
D: (3,2)

Order in the output is insignificant.

#include <iostream>
#include <vector>
#include <functional>
#include <unordered_map>
using namespace std;

// solution with changing the original matrix
vector<vector<pair<int,int>>> findIslands(vector<vector<int>>& mat) {
	int m = mat.size(), n = mat[0].size();
	vector<vector<pair<int,int>>> res;
	vector<pair<int,int>> list;
	vector<vector<int>> dirs = {{0,1},{0,-1},{1,0},{-1,0}};
	function<void(int,int)> dfs = [&](int r, int c) {
		list.emplace_back(r,c);
		mat[r][c] = 0;
		for(auto& dir:dirs) {
			int i = r+dir[0], j = c+dir[1];
			if(i<0 || j<0 || i>=m || j>=n || !mat[i][j]) continue;
			dfs(i, j);
		}
	};
	for(int i=0; i<m; i++) {
		for(int j=0; j<n; j++) {
			if(mat[i][j]) {
				list.clear();
				dfs(i, j);
				res.push_back(list);
			}
		}
	}
	return res;
}

// solution without changing the original matrix, using additional visited bool matrix
vector<vector<pair<int,int>>> findIslands1(vector<vector<int>>& mat) {
	int m = mat.size(), n = mat[0].size();
	vector<vector<pair<int,int>>> res;
	vector<pair<int,int>> list;
	vector<vector<bool>> visited(m, vector<bool>(n));
	vector<vector<int>> dirs = {{0,1},{0,-1},{1,0},{-1,0}};
	function<void(int,int)> dfs = [&](int r, int c) {
		list.emplace_back(r,c);
		visited[r][c] = true;
		for(auto& dir:dirs) {
			int i = r+dir[0], j = c+dir[1];
			if(i<0 || j<0 || i>=m || j>=n || !mat[i][j] || visited[i][j]) continue;
			dfs(i, j);
		}
	};
	for(int i=0; i<m; i++) {
		for(int j=0; j<n; j++) {
			if(mat[i][j] && !visited[i][j]) {
				list.clear();
				dfs(i, j);
				res.push_back(list);
			}
		}
	}
	return res;
}

// solution without changing the original matrix and without additional memory space
vector<unordered_map<int,vector<pair<int,int>>>> findIslands2(vector<vector<int>>& mat) {
	int m = mat.size(), n = mat[0].size();
	vector<unordered_map<int,vector<pair<int,int>>>> res;
	unordered_map<int,vector<pair<int,int>>> map;
	vector<vector<int>> dirs = {{0,1},{0,-1},{1,0},{-1,0}};
	
	auto exists = [&](int r, int c) {
		for(auto& mp:res) {
			if(mp.count(r)) {
				for(auto& p:mp[r])
					if(p.first <= c && p.second >= c)
						return true;
			}
		}
		return false;
	};
	
	function<void(int,int)> dfs = [&](int r, int c) {
		if(map.count(r)) {
			bool inserted = false;
			for(auto& p:map[r]) {
				if(p.first <= c && p.second >= c) return;
				if(c+1 == p.first) {
					p.first = c;
					inserted = true; 
					break;
				} else if(c-1 == p.second) {
					p.second = c;
					inserted = true; 
					break;
				}
			}
			if(!inserted)
				map[r].push_back({c, c});
		} else {
			map[r].push_back({c, c});
		}
		for(auto& dir:dirs) {
			int i = r+dir[0], j = c+dir[1];
			if(i<0 || j<0 || i>=m || j>=n || !mat[i][j]) continue;
			dfs(i, j);
		}
	};
	
	for(int i=0; i<m; i++) {
		for(int j=0; j<n; j++) {
			if(mat[i][j] && !exists(i,j)) {
				map.clear();
				dfs(i, j);
				res.push_back(map);
			}
		}
	}
	return res;
}

int main() {
	vector<vector<int>> mat = { {1, 1, 0, 1, 0, 1},
								{1, 1, 1, 1, 0, 1},
								{0, 0, 0, 0, 1, 1},
								{1, 0, 1, 0, 1, 0}};
	auto res1 = findIslands1(mat);
	for(auto& list:res1) {
		for(auto& p:list)
			cout << "(" << p.first << "," << p.second << ") ";
		cout << endl;
	}
	
	auto res2 = findIslands2(mat);
	for(auto& map:res2) {
		for(auto& kv:map)
			for(auto& pair:kv.second)
				for(int i=pair.first; i<=pair.second; i++)
					cout << "(" << kv.first << "," << i << ") ";
		cout << endl;
	}
	return 0;
}

你可能感兴趣的:(Find Islands)