pull/3/head
Leo 5 years ago
parent e57027d5f7
commit 196be85def

@ -7,24 +7,25 @@ package leo.class09_13;
* @Description
* headab
* ab
* https://leetcode-cn.com/problems/er-cha-shu-de-zui-jin-gong-gong-zu-xian-lcof/
*/
public class LowestAncestor {
static class Code {
static Node lowestAncestor(Node head, Node a, Node b) {
static TreeNode lowestCommonAncestor(TreeNode head, TreeNode a, TreeNode b) {
return process(head, a, b).ans;
}
static Info process(Node node, Node a, Node b) {
static Info process(TreeNode node, TreeNode a, TreeNode b) {
if (node == null) {
return new Info(null, false, false);
}
Info left = process(node, a, b);
Info right = process(node, a, b);
Info left = process(node.left, a, b);
Info right = process(node.right, a, b);
boolean findA = left.findA || right.findA || a == node;
boolean findB = left.findB || right.findB || b == node;
Node ans = null;
TreeNode ans = null;
if (left.ans != null) {
ans = left.ans;
}
@ -40,15 +41,110 @@ public class LowestAncestor {
}
static class Info {
Node ans;
TreeNode ans;
boolean findA;
boolean findB;
public Info(Node ans, boolean findA, boolean findB) {
public Info(TreeNode ans, boolean findA, boolean findB) {
this.ans = ans;
this.findA = findA;
this.findB = findB;
}
}
}
class Code1 {
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
return process(root, p, q).ans;
}
public Info process(TreeNode node,TreeNode a,TreeNode b) {
if (node == null) {
return new Info(null, false, false);
}
Info left = process(node.left, a, b);
Info right = process(node.right, a, b);
boolean findA = left.findA || right.findA || node == a;
boolean findB = left.findB || right.findB || node == b;
TreeNode ans = null;
if (left.ans != null) {
ans = left.ans;
}
if (right.ans != null) {
ans = right.ans;
}
if (ans == null) {
if (findA && findB) {
ans = node;
}
}
return new Info(ans, findA, findB);
}
class Info {
TreeNode ans;
boolean findA;
boolean findB;
public Info(TreeNode ans, boolean findA, boolean findB) {
this.ans = ans;
this.findA = findA;
this.findB = findB;
}
}
}
class Code2 {
public TreeNode lowestCommonAncestor(TreeNode head, TreeNode a, TreeNode b) {
return process(head, a, b).ans;
}
public Info process(TreeNode node, TreeNode a, TreeNode b) {
if (node == null) {
return new Info(null, false, false);
}
Info left = process(node.left, a, b);
Info right = process(node.right, a, b);
boolean findA = left.findA || right.findA || node == a;
boolean findB = left.findB || right.findB || node == b;
TreeNode ans = null;
if (left.ans != null) {
ans = left.ans;
}
if (right.ans != null) {
ans = right.ans;
}
if (findA && findB) {
if (ans == null) {
ans = node;
}
}
return new Info(ans, findA, findB);
}
class Info{
TreeNode ans;
boolean findA;
boolean findB;
public Info(TreeNode ans, boolean a, boolean b) {
this.ans = ans;
this.findA = a;
this.findB = b;
}
}
}
public class TreeNode {
int val;
TreeNode left;
TreeNode right;
TreeNode(int x) { val = x; }
}
}

@ -9,71 +9,137 @@ package leo.class09_15;
*/
public class FriendCircles {
public int findCircleNum(int[][] M) {
int n = M.length;
UnionFind unionFind = new UnionFind(n);
for (int i = 0; i < n; i++) {
for (int j = i + 1; j < n; j++) {
if (M[i][j] == 1) {
unionFind.union(i, j);
class Code1 {
public int findCircleNum(int[][] M) {
int n = M.length;
UnionFind unionFind = new UnionFind(n);
for (int i = 0; i < n; i++) {
for (int j = i + 1; j < n; j++) {
if (M[i][j] == 1) {
unionFind.union(i, j);
}
}
}
}
return unionFind.sets;
}
return unionFind.sets;
}
public class UnionFind {
// i的父级节点是parent[i]
int[] parent;
// i的集合大小为size[i]
int[] size;
//辅助结构
int[] help;
//一共多少个集合
int sets;
public UnionFind(int n) {
parent = new int[n];
size = new int[n];
help = new int[n];
sets = n;
public class UnionFind {
// i的父级节点是parent[i]
int[] parent;
// i的集合大小为size[i]
int[] size;
//辅助结构
int[] help;
//一共多少个集合
int sets;
public UnionFind(int n) {
parent = new int[n];
size = new int[n];
help = new int[n];
sets = n;
for (int i = 0; i < n; i++) {
parent[i] = i;
size[i] = 1;
}
}
public int find(int i) {
int h = 0;
while (i != parent[i]) {
help[h++] = i;
i = parent[i];
}
for (h--; h >= 0; h--) {
parent[help[h]] = i;
}
return i;
}
public void union(int i, int j) {
int iF = find(i);
int jF = find(j);
if (jF != iF) {
int iSize = size[iF];
int jSize = size[jF];
int big = iSize >= jSize ? iF : jF;
int small = big == iF ? jF : iF;
parent[small] = big;
size[big] = jSize + iSize;
sets--;
}
}
public int sets() {
return sets;
}
}
}
class Code2 {
public int findCircleNum(int[][] M) {
int n = M.length;
UnionFind unionFind = new UnionFind(n);
for (int i = 0; i < n; i++) {
parent[i] = i;
size[i] = 1;
for (int j = i + 1; j < n; j++) {
if (M[i][j] == 1) {
unionFind.union(i, j);
}
}
}
return unionFind.sets;
}
public int find(int i) {
int h = 0;
while (i != parent[i]) {
help[h++] = i;
i = parent[i];
public class UnionFind {
int[] parent;
int[] size;
int[] help;
int sets;
public UnionFind(int n) {
parent = new int[n];
size = new int[n];
help = new int[n];
sets = n;
for (int i = 0; i < n; i++) {
parent[i] = i;
size[i] = 1;
}
}
for (h--; h >= 0; h--) {
parent[help[h]] = i;
public int find(int i) {
int h = 0;
while (i != parent[i]) {
help[h++] = i;
i = parent[i];
}
for (h--; h >= 0; h--) {
parent[help[h]] = i;
}
return i;
}
return i;
}
public void union(int i, int j) {
int iF = find(i);
int jF = find(j);
if (iF != jF) {
int iSize = size[iF];
int jSize = size[jF];
int big = iSize >= jSize ? iF : jF;
int small = big == iF ? jF : iF;
parent[small] = big;
size[big] = iSize + jSize;
sets--;
}
public void union(int i, int j) {
int iF = find(i);
int jF = find(j);
if (jF != iF) {
int iSize = size[iF];
int jSize = size[jF];
int big = iSize >= jSize ? iF : jF;
int small = big == iF ? jF : iF;
parent[small] = big;
size[big] = jSize + iSize;
sets--;
}
}
public int sets() {
return sets;
public int sets() {
return sets;
}
}
}
}

@ -1,9 +1,6 @@
package leo.class09_15;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Stack;
import java.util.*;
/**
* @author Leo
@ -41,6 +38,31 @@ public class NumberOfIslands {
infect(grid, r, c+1);
}
}
static class C1 {
public static int numIslands (char[][] grid) {
int count = 0;
for (int i = 0; i < grid.length; i++) {
for (int j = 0; j < grid[0].length; j++) {
if (grid[i][j] == '1') {
count++;
infect(grid, i, j);
}
}
}
return count;
}
private static void infect(char[][] grid, int i, int j) {
if (i < 0 || j == grid[0].length || j < 0 || i == grid.length || grid[i][j] != '1') {
return;
}
grid[i][j] = '2';
infect(grid, i + 1, j);
infect(grid, i - 1, j);
infect(grid, i, j + 1);
infect(grid, i, j - 1);
}
}
}
@ -147,6 +169,114 @@ public class NumberOfIslands {
}
}
static class C1 {
public int numIslands(char[][] grid) {
List<Dot> list = new ArrayList<>();
int r = grid.length;
int c = grid[0].length;
Dot[][] dot = new Dot[r][c];
for (int i = 0; i < r; i++) {
for (int j = 0; j < c; j++) {
if (grid[i][j] == '1') {
dot[i][j] = new Dot();
list.add(dot[i][j]);
}
}
}
UnionFind u = new UnionFind(list);
//上左依次合并
//第一行每一列与第二行每一列合并
for (int i = 1; i < grid.length; i++) {
if (grid[i - 1][0] == '1' && grid[i][0] == '1') {
u.union(dot[i - 1][0], dot[i][0]);
}
}
//每行的第一列与第二列合并
for (int i = 1; i < grid[0].length; i++) {
if (grid[0][i - 1] == '1' && grid[0][i] == '1') {
u.union(dot[0][i - 1], dot[0][i]);
}
}
for (int i = 1; i < r; i++) {
for (int j = 1; j < c; j++) {
if (grid[i][j] == '1') {
if (grid[i - 1][j] == '1') {
u.union(dot[i][j], dot[i - 1][j]);
}
if (grid[i][j - 1] == '1') {
u.union(dot[i][j], dot[i][j - 1]);
}
}
}
}
return u.sets();
}
class UnionFind<V>{
HashMap<V,Node<V>> nodes;
HashMap<Node<V>,Node<V>> parent;
HashMap<Node<V>,Integer> size;
public UnionFind(List<V> list) {
nodes = new HashMap<>();
parent = new HashMap<>();
size = new HashMap<>();
for (int i = 0; i < list.size(); i++) {
Node node = new Node(list.get(i));
nodes.put(list.get(i), node);
parent.put(node, node);
size.put(node, 1);
}
}
public Node find(V v) {
Stack<Node> stack = new Stack<>();
Node cur = nodes.get(v);
while (cur != parent.get(cur)) {
stack.push(cur);
cur = parent.get(cur);
}
while (!stack.isEmpty()) {
parent.put(stack.pop(), cur);
}
return cur;
}
public void union(V a, V b) {
Node aF = find(a);
Node bF = find(b);
if (aF == bF) {
return;
}
int aSize = size.get(aF);
int bSize = size.get(bF);
Node big = aSize >= bSize ? aF : bF;
Node small = big == aF ? bF : aF;
parent.put(small, big);
size.put(big, aSize + bSize);
size.remove(small);
}
public int sets() {
return size.size();
}
}
class Dot {
}
class Node<V> {
V value ;
public Node(V v) {
this.value = v;
}
}
}
}
@ -248,9 +378,101 @@ public class NumberOfIslands {
return r * col + c;
}
}
}
class C1 {
public int numIslands(char[][] grid) {
UnionFind u = new UnionFind(grid);
int row = grid.length;
int col = grid[0].length;
for (int i = 1; i < row; i++) {
if (grid[i - 1][0] == '1' && grid[i][0] == '1') {
u.union(i - 1, 0, i, 0);
}
}
for (int i = 1; i < col; i++) {
if (grid[0][i - 1] == '1' && grid[0][i] == '1') {
u.union(0, i - 1, 0, i);
}
}
for (int i = 1; i < row; i++) {
for (int j = 1; j < col; j++) {
if (grid[i][j] == '1') {
if (grid[i - 1][j] == '1') {
u.union(i, j, i - 1, j);
}
if (grid[i][j - 1] == '1') {
u.union(i, j, i, j - 1);
}
}
}
}
return u.sets();
}
class UnionFind {
int[] parent;
int[] size;
int[] help;
int col;
int set;
public UnionFind(char[][] grid) {
int row = grid.length;
col = grid[0].length;
int n = row * col;
parent = new int[n];
size = new int[n];
help = new int[n];
set = 0;
for (int i = 0; i < row; i++) {
for (int j = 0; j < col; j++) {
if (grid[i][j] == '1') {
int x = getIndex(i, j);
parent[x] = x;
size[x] = 1;
set++;
}
}
}
}
public int find(int i) {
int hi = 0;
while (i != parent[i]) {
help[hi++] = i;
i = parent[i];
}
for (hi--; hi >= 0; hi--) {
parent[help[hi]] = i;
}
return i;
}
public void union(int i1, int j1, int i2, int j2) {
int a = getIndex(i1, j1);
int b = getIndex(i2, j2);
int aF = find(a);
int bF = find(b);
if (aF == bF) {
return;
}
int aSize = size[aF];
int bSize = size[bF];
int big = aSize >= bSize ? aF : bF;
int small = big == aF ? bF : aF;
parent[small] = big;
size[big] = aSize + bSize;
set--;
}
public int sets() {
return set;
}
public int getIndex(int i, int j) {
return i * col + j;
}
}
}
}

@ -0,0 +1,237 @@
package leo.class09_15;
import java.util.ArrayList;
import java.util.List;
/**
* @author Leo
* @ClassName NumberOfIslandsII
* @DATE 2020/12/25 3:14
* @Description 305
* https://leetcode.com/problems/number-of-islands-ii/
*/
public class NumberOfIslandsII {
static class C {
public static List<Integer> numIslands(int m, int n, int[][] positions) {
UnionFind1 uf = new UnionFind1(m, n);
List<Integer> ans = new ArrayList<>();
for (int[] position : positions) {
ans.add(uf.connect(position[0], position[1]));
}
return ans;
}
public static class UnionFind1 {
private int[] parent;
private int[] size;
private int[] help;
private final int row;
private final int col;
private int sets;
public UnionFind1(int m, int n) {
row = m;
col = n;
sets = 0;
int len = row * col;
parent = new int[len];
size = new int[len];
help = new int[len];
}
private int index(int r, int c) {
return r * col + c;
}
private int find(int i) {
int hi = 0;
while (i != parent[i]) {
help[hi++] = i;
i = parent[i];
}
for (hi--; hi >= 0; hi--) {
parent[help[hi]] = i;
}
return i;
}
private void union(int r1, int c1, int r2, int c2) {
if (r1 < 0 || r1 == row || r2 < 0 || r2 == row || c1 < 0 || c1 == col || c2 < 0 || c2 == col) {
return;
}
int i1 = index(r1, c1);
int i2 = index(r2, c2);
if (size[i1] == 0 || size[i2] == 0) {
return;
}
int f1 = find(i1);
int f2 = find(i2);
if (f1 != f2) {
if (size[f1] >= size[f2]) {
size[f1] += size[f2];
parent[f2] = f1;
} else {
size[f2] += size[f1];
parent[f1] = f2;
}
sets--;
}
}
public int connect(int r, int c) {
int index = index(r, c);
if (size[index] == 0) {
parent[index] = index;
size[index] = 1;
sets++;
union(r - 1, c, r, c);
union(r + 1, c, r, c);
union(r, c - 1, r, c);
union(r, c + 1, r, c);
}
return sets;
}
}
}
static class C1 {
public static List<Integer> numIslands(int m,int n,int[][] positions) {
UnionFind unionFind = new UnionFind(m, n);
List<Integer> list = new ArrayList<>();
for (int[] position : positions) {
list.add(unionFind.connect(position[0], position[1]));
}
return list;
}
static class UnionFind {
int[] parent;
int[] size;
int[] help;
int col;
int row;
int set;
public UnionFind(int m, int n) {
row = m;
col = n;
int len = row * col;
parent = new int[len];
size = new int[len];
help = new int[len];
set = 0;
}
public int find(int i) {
int hi = 0;
while (i != parent[i]) {
help[hi++] = i;
i = parent[i];
}
for (hi--; hi >= 0; hi--) {
parent[help[hi]] = i;
}
return i;
}
public int index(int r, int c) {
return r * col + c;
}
public void union(int r1, int c1, int r2, int c2) {
if (r1 < 0 || r1 == row || r2 < 0 || r2 == row || c1 < 0 || c1 == col || c2 < 0 || c2 == col) {
return;
}
int i1 = index(r1, c1);
int i2 = index(r2, c2);
if (size[i1] == 0 || size[i2] == 0) {
return;
}
int aF = find(i1);
int bF = find(i2);
if (aF == bF) {
return;
}
int aSize = size[aF];
int bSize = size[bF];
int big = aSize >= bSize ? aF : bF;
int small = big == aF ? bF : aF;
parent[small] = big;
size[big] = aSize + bSize;
set--;
}
public int connect(int r, int c) {
int i = index(r, c);
if (size[i] == 0) {
size[i] = 1;
parent[i] = i;
set++;
union(r - 1, c, r, c);
union(r + 1, c, r, c);
union(r, c - 1, r, c);
union(r, c + 1, r, c);
}
return set;
}
}
}
public static void main(String[] args){
int mMax = 20;
int nMax = 20;
int test = 100;
System.out.println("start");
for (int i = 0; i < test; i++) {
int m = (int) ((Math.random() * mMax) + 1);
int n = (int) ((Math.random() * nMax) + 1);
int[][] positions = randomPositions(m, n);
List<Integer> list = C.numIslands(m, n, positions);
List<Integer> list1 = C1.numIslands(m, n, positions);
if (!isListEqual(list, list1)) {
System.out.println(list.toString());
System.out.println(list1.toString());
break;
}
}
System.out.println("end");
}
public static boolean isListEqual(List l0, List l1){
if (l0 == l1)
return true;
if (l0 == null && l1 == null)
return true;
if (l0 == null || l1 == null)
return false;
if (l0.size() != l1.size())
return false;
for (Object o : l0) {
if (!l1.contains(o))
return false;
}
for (Object o : l1) {
if (!l0.contains(o))
return false;
}
return true;
}
private static int[][] randomPositions(int m, int n) {
int size = (int) (Math.random() * m * n) + 1;
int[][] positions = new int[size][2];
for (int i = 0; i < positions.length; i++) {
positions[i][0] = (int) (Math.random() * m);
positions[i][1] = (int) (Math.random() * n);
}
return positions;
}
}
Loading…
Cancel
Save