2022-1-16图day4
题1:
给你一个
m x n
的矩阵 board
,由若干字符 'X'
和 'O'
,找到所有被 'X'
围绕的区域,并将这些区域里所有的 'O'
用 'X'
填充。
示例 1:
输入:board = [["X","X","X","X"],["X","O","O","X"],["X","X","O","X"],["X","O","X","X"]] 输出:[["X","X","X","X"],["X","X","X","X"],["X","X","X","X"],["X","O","X","X"]] 解释:被围绕的区间不会存在于边界上,换句话说,任何边界上的'O'
都不会被填充为'X'
。 任何不在边界上,或不与边界上的'O'
相连的'O'
最终都会被填充为'X'
。如果两个元素在水平或垂直方向相邻,则称它们是“相连”的。
示例 2:
输入:board = [["X"]] 输出:[["X"]]
提示:
m == board.length
n == board[i].length
1 <= m, n <= 200
board[i][j]
为'X'
或'O'
1 class Solution { 2 class Union{ 3 int[] parent; 4 public Union(int n){ 5 parent=new int[n]; 6 for (int i=0;i<n;i++) parent[i]=i; 7 } 8 9 public int find(int x) { 10 while (parent[x]!=x) { 11 //parent[x]=parent[parent[x]]; 12 x=parent[x]; 13 } 14 return x; 15 } 16 17 public void union(int x,int y){ 18 int rootx=find(x); 19 int rooty=find(y); 20 if (rootx==rooty) return; 21 else parent[rootx]=rooty; 22 } 23 24 public boolean isConnect(int x,int y){ 25 return find(x)==find(y); 26 } 27 } 28 public void solve(char[][] board) { 29 int row=board.length,col=board[0].length; 30 int dummy=row*col; 31 Union union=new Union(dummy+1); 32 for (int i=0;i<row;i++) { 33 for (int j=0;j<col;j++) { 34 if (board[i][j]=='O') { 35 if (i==0||j==0||i==row-1||j==col-1){ 36 union.union(i*col+j,dummy); 37 }else{ 38 if (i>0&&board[i-1][j]=='O') union.union(i*col+j-col,i*col+j); 39 if (j>0&&board[i][j-1]=='O') union.union(i*col+j-1,i*col+j); 40 if (i<row-1&&board[i+1][j]=='O') union.union(i*col+j+col,i*col+j); 41 if (j<col-1&&board[i][j+1]=='O') union.union(i*col+j+1,i*col+j); 42 } 43 } 44 } 45 } 46 47 for (int i=0;i<row;i++) { 48 for (int j=0;j<col;j++) { 49 if (!union.isConnect(i*col+j,dummy)){ 50 board[i][j]='X'; 51 } 52 } 53 } 54 } 55 }
思路:常规思路DFS或者BFS,可以用并查集解决。并查集有构造函数,所有节点的根节点指向自己。找根节点;连接两个节点,即将根节点一样;是否连通:判断根节点是否一样。
二维压缩为一维数组,坐标x,y 变为x*column+y;最大就是m*n;第一次遍历,将所有边界上的O与虚拟节点连通,不是边界的O与相邻节点连通。
第二次遍历,将所有不与虚拟节点连通的点染为X;
题2:
给定一个由表示变量之间关系的字符串方程组成的数组,每个字符串方程 equations[i]
的长度为 4
,并采用两种不同的形式之一:"a==b"
或 "a!=b"
。在这里,a 和 b 是小写字母(不一定不同),表示单字母变量名。
只有当可以将整数分配给变量名,以便满足所有给定的方程时才返回 true
,否则返回 false
。
示例 1:
输入:["a==b","b!=a"] 输出:false 解释:如果我们指定,a = 1 且 b = 1,那么可以满足第一个方程,但无法满足第二个方程。没有办法分配变量同时满足这两个方程。
示例 2:
输入:["b==a","a==b"] 输出:true 解释:我们可以指定 a = 1 且 b = 1 以满足满足这两个方程。
示例 3:
输入:["a==b","b==c","a==c"] 输出:true
示例 4:
输入:["a==b","b!=c","c==a"] 输出:false
示例 5:
输入:["c==c","b==d","x!=z"] 输出:true
提示:
1 <= equations.length <= 500
equations[i].length == 4
equations[i][0]
和equations[i][3]
是小写字母equations[i][1]
要么是'='
,要么是'!'
equations[i][2]
是'='
1 class Solution { 2 class Union{ 3 int[] parent; 4 public Union(){ 5 parent=new int[26]; 6 for (int i=0;i<26;i++) parent[i]=i; 7 } 8 9 public int find(int x) { 10 while (parent[x]!=x) { 11 //parent[x]=parent[parent[x]]; 12 x=parent[x]; 13 } 14 return x; 15 } 16 17 public void union(int x,int y){ 18 int rootx=find(x); 19 int rooty=find(y); 20 if (rootx==rooty) return; 21 else parent[rootx]=rooty; 22 } 23 24 public boolean isConnect(int x,int y){ 25 return find(x)==find(y); 26 } 27 } 28 public boolean equationsPossible(String[] equations) { 29 Union union=new Union(); 30 for (String s:equations){ 31 char first=s.charAt(0),second=s.charAt(3); 32 if (s.charAt(1)=='=') { 33 union.union(first-'a',second-'a'); 34 } 35 } 36 for (String s:equations){ 37 char first=s.charAt(0),second=s.charAt(3); 38 if (s.charAt(1)=='!'&&union.isConnect(first-'a',second-'a')) { 39 return false; 40 } 41 } 42 return true; 43 } 44 }
思路:并查集。第一次遍历,将所有相等的字母连通,第二次遍历,判断所有不相等的是否连通,连通返回FALSE;否则返回true;