-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathSurrounded_Regions.cpp
146 lines (123 loc) · 4.38 KB
/
Surrounded_Regions.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
// 解题思路依然使用并查集,特殊点在于使用了一个虚拟的父亲节点将所有边界上、以及边界上的邻居点都串起来了
// 对于路径压缩,另外一种方法是https://leetcode.com/problems/surrounded-regions/discuss/41617/Solve-it-using-Union-Find,对路径长度减半
// Runtime: 24 ms, faster than 98.26% of C++ online submissions for Surrounded Regions.
// Memory Usage: 14.4 MB, less than 34.94% of C++ online submissions for Surrounded Regions.
class Solution
{
public:
void solve(vector<vector<char>>& board)
{
// 边界条件处理
rows = board.size();
if (rows == 0)
{
return ;
}
cols = board[0].size();
if (cols == 0)
{
return ;
}
// 构建并查集
vector<pair<int, int>> unionTree(rows * cols + 1);
// 初始化并查集 depth parent
for (int i = 0; i < unionTree.size(); i++)
{
unionTree[i].first = 1;
unionTree[i].second = i;
}
// 构建并查集
for (int i = 0; i < rows; i++)
{
for (int j = 0; j < cols; j++)
{
if (board[i][j] == 'O')
{
int index1 = i * cols + j;
// 如果目标在边界上,将其和一个dummy node连接在一起
if (i == 0 || i == rows - 1 || j == 0 || j == cols - 1)
{
int index2 = rows * cols;
unionx(index1, index2, unionTree);
}
// 和上边的数据相连
if (i - 1 >= 0 && board[i - 1][j] == 'O')
{
int index2 = (i - 1) * cols + j;
unionx(index1, index2, unionTree);
}
// 和左边的数据相连
if (j - 1 >= 0 && board[i][j - 1] == 'O')
{
int index2 = i * cols + (j - 1);
unionx(index1, index2, unionTree);
}
}
}
}
// 根据构建好的并查集来翻转数据
for (int i = 0; i < rows; i++)
{
for (int j = 0; j < cols; j++)
{
if (board[i][j] == 'O')
{
if (findParent(i * cols + j, unionTree) != findParent(rows * cols, unionTree))
{
board[i][j] = 'X';
}
}
}
}
}
private:
// 所能接受的最大查询路径长度
int maxPathLength = 3;
int rows;
int cols;
// 合并函数
void unionx(int index1, int index2, vector<pair<int, int>>& unionTree)
{
int parent1 = findParent(index1, unionTree);
int parent2 = findParent(index2, unionTree);
if (parent1 == parent2)
{
return ;
}
// 将高度较低的树向高度较高的树进行合并
if (unionTree[parent1].first > unionTree[parent2].first)
{
unionTree[parent2].second = parent1;
}
else
{
unionTree[parent1].second = parent2;
if (unionTree[parent1].first == unionTree[parent2].first)
{
unionTree[parent2].first++;
}
}
}
// 查找父亲节点
// 如果需要进一步加速就要使用路径压缩算法
int findParent(int index, vector<pair<int, int>>& unionTree)
{
int initIndex = index;
int pathLength = 0;
while (unionTree[index].second != index && unionTree[index].second != -1)
{
pathLength++;
index = unionTree[index].second;
}
if (pathLength > maxPathLength)
{
while (initIndex != index)
{
int temp = initIndex;
initIndex = unionTree[initIndex].second;
unionTree[temp].second = index;
}
}
return index;
}
};