parent
c9008b25e8
commit
e39312c69a
@ -0,0 +1,194 @@
|
|||||||
|
package zuolaos.jichuban;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Comparator;
|
||||||
|
import java.util.PriorityQueue;
|
||||||
|
import java.util.TreeSet;
|
||||||
|
|
||||||
|
public class Code17_贪心算法 {
|
||||||
|
}
|
||||||
|
|
||||||
|
class 在时间段会议最多 {
|
||||||
|
|
||||||
|
private class Program {
|
||||||
|
int start;
|
||||||
|
int end;
|
||||||
|
|
||||||
|
public Program(int start, int end) {
|
||||||
|
this.start = start;
|
||||||
|
this.end = end;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//贪心解法
|
||||||
|
public int process(Program[] programs) {
|
||||||
|
Arrays.sort(programs, new Comparator<Program>() {
|
||||||
|
@Override
|
||||||
|
public int compare(Program o1, Program o2) {
|
||||||
|
return o1.end - o2.end;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
int start = 0;
|
||||||
|
int ans = 0;
|
||||||
|
for (Program program : programs) {
|
||||||
|
if (program.start >= start) {
|
||||||
|
ans++;
|
||||||
|
start = program.end;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ans;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//暴力解法
|
||||||
|
public int baoli(Program[] programs, int done, int timeLine) {
|
||||||
|
//无会议室可以选择
|
||||||
|
if (programs == null || programs.length == 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//已经选择的
|
||||||
|
int max = done;
|
||||||
|
for (int i = 0; i < programs.length; i++) {
|
||||||
|
if (programs[i].start >= timeLine) {
|
||||||
|
//删除集合返回集合
|
||||||
|
Program[] newprograms = null;
|
||||||
|
int don = baoli(newprograms, done + 1, programs[i].end);
|
||||||
|
max = Math.max(done, don);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return max;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class 数组中按照字典序排列 {
|
||||||
|
//贪心解法
|
||||||
|
public String process(String[] strs) {
|
||||||
|
Arrays.sort(strs, new Comparator<String>() {
|
||||||
|
@Override
|
||||||
|
public int compare(String o1, String o2) {
|
||||||
|
return (o1 + o2).compareTo(o2 + o1);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
String ans = "";
|
||||||
|
for (String str : strs) {
|
||||||
|
ans += str;
|
||||||
|
}
|
||||||
|
return ans;
|
||||||
|
}
|
||||||
|
|
||||||
|
//暴力解法
|
||||||
|
public TreeSet<String> baoli(String[] strs) {
|
||||||
|
TreeSet<String> ans = new TreeSet<>();
|
||||||
|
if (strs == null || strs.length == 0) {
|
||||||
|
ans.add("");
|
||||||
|
return ans;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < strs.length; i++) {
|
||||||
|
String first = strs[i];
|
||||||
|
//删除返回新数组
|
||||||
|
String[] newstrs = null;
|
||||||
|
TreeSet<String> baoli = baoli(newstrs);
|
||||||
|
for (String next : baoli) {
|
||||||
|
ans.add(first + next);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ans;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class 金条分割的最小代价 {
|
||||||
|
|
||||||
|
public int process(int[] arr) {
|
||||||
|
PriorityQueue<Integer> queue = new PriorityQueue<>();
|
||||||
|
for (int i : arr) {
|
||||||
|
queue.add(i);
|
||||||
|
}
|
||||||
|
int sum = 0;
|
||||||
|
int cur = 0;
|
||||||
|
while (queue.size() > 1) {
|
||||||
|
cur = queue.poll() + queue.poll();
|
||||||
|
sum += cur;
|
||||||
|
queue.add(cur);
|
||||||
|
}
|
||||||
|
return sum;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class 有限资金获得最大利润 {
|
||||||
|
|
||||||
|
private class Program {
|
||||||
|
int c; //成本
|
||||||
|
int p; //纯利润
|
||||||
|
|
||||||
|
public Program(int c, int p) {
|
||||||
|
this.c = c;
|
||||||
|
this.p = p;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public int process(int K, int W, int[] c, int[] p) {
|
||||||
|
PriorityQueue<Program> minC = new PriorityQueue<>(new Comparator<Program>() {
|
||||||
|
@Override
|
||||||
|
public int compare(Program o1, Program o2) {
|
||||||
|
return o1.c - o2.c;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
PriorityQueue<Program> maxP = new PriorityQueue<>(new Comparator<Program>() {
|
||||||
|
@Override
|
||||||
|
public int compare(Program o1, Program o2) {
|
||||||
|
return o2.p - o1.p;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
for (int i = 0; i < c.length; i++) {
|
||||||
|
minC.add(new Program(c[i], p[i]));
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < K; i++) {
|
||||||
|
while (!minC.isEmpty() && minC.peek().c >= W) {
|
||||||
|
maxP.add(minC.poll());
|
||||||
|
}
|
||||||
|
if (maxP.isEmpty()) {
|
||||||
|
return W;
|
||||||
|
}
|
||||||
|
W += maxP.poll().p;
|
||||||
|
}
|
||||||
|
return W;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
class 需要放置最大的灯泡数 {
|
||||||
|
|
||||||
|
public int process(String str) {
|
||||||
|
char[] chars = str.toCharArray();
|
||||||
|
int light = 0;
|
||||||
|
int i = 0;
|
||||||
|
while (i < chars.length) {
|
||||||
|
if (chars[i] == 'X') {
|
||||||
|
i++;
|
||||||
|
} else {
|
||||||
|
light++;
|
||||||
|
if (i + 1 == chars.length) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (chars[i + 1] == 'X') {
|
||||||
|
i = i + 2;
|
||||||
|
} else {
|
||||||
|
i = i + 3;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
return light;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,269 @@
|
|||||||
|
package zuolaos.jichuban;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Stack;
|
||||||
|
|
||||||
|
public class Code18_并查集 {
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
class 并查集基本实现 {
|
||||||
|
private class Node<V> {
|
||||||
|
V value;
|
||||||
|
|
||||||
|
public Node(V value) {
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private class UnionQueue<V> {
|
||||||
|
public Map<V, Node> nodes = new HashMap<>();
|
||||||
|
//指向父节点
|
||||||
|
public Map<Node, Node> parents = new HashMap<>();
|
||||||
|
public Map<Node, Integer> nodeSize = new HashMap<>();
|
||||||
|
|
||||||
|
public UnionQueue(List<V> values) {
|
||||||
|
for (V value : values) {
|
||||||
|
Node<V> node = new Node<>(value);
|
||||||
|
nodes.put(value, node);
|
||||||
|
parents.put(node, node);
|
||||||
|
nodeSize.put(node, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Node findFather(Node<V> cur) {
|
||||||
|
Stack<Node> path = new Stack<>();
|
||||||
|
while (cur != parents.get(cur)) {
|
||||||
|
path.add(cur);
|
||||||
|
cur = parents.get(cur);
|
||||||
|
}
|
||||||
|
while (!path.isEmpty()) {
|
||||||
|
parents.put(path.pop(), cur);
|
||||||
|
}
|
||||||
|
return cur;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void union(V a, V b) {
|
||||||
|
Node aHead = findFather(nodes.get(a));
|
||||||
|
Node bHead = findFather(nodes.get(b));
|
||||||
|
if (aHead != bHead) {
|
||||||
|
Integer aSize = nodeSize.get(aHead);
|
||||||
|
Integer bSize = nodeSize.get(bHead);
|
||||||
|
Node big = aSize > bSize ? aHead : bHead;
|
||||||
|
Node small = big == aHead ? bHead : aHead;
|
||||||
|
parents.put(small, big);
|
||||||
|
nodeSize.put(big, aSize + bSize);
|
||||||
|
nodeSize.remove(small);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isSame(V a, V b) {
|
||||||
|
return findFather(nodes.get(a)) == findFather(nodes.get(b));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//二维数组为1 表示认识,判断有多少个圈子
|
||||||
|
class 朋友圈的个数_并查集法 {
|
||||||
|
public static 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.getAllSet();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class UnionFind {
|
||||||
|
//i位置 指向的父节点位置
|
||||||
|
int[] parent;
|
||||||
|
//
|
||||||
|
int[] size;
|
||||||
|
int[] help;
|
||||||
|
int allSet;
|
||||||
|
|
||||||
|
public UnionFind(int N) {
|
||||||
|
parent = new int[N];
|
||||||
|
size = new int[N];
|
||||||
|
help = new int[N];
|
||||||
|
for (int i = 0; i < N; i++) {
|
||||||
|
parent[i] = i;
|
||||||
|
size[i] = 1;
|
||||||
|
}
|
||||||
|
allSet = N;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int findFather(int i) {
|
||||||
|
int index = 0;
|
||||||
|
while (parent[i] != i) {
|
||||||
|
help[index++] = i;
|
||||||
|
i = parent[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
while (index >= 0) {
|
||||||
|
parent[help[index--]] = i;
|
||||||
|
}
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void union(int a, int b) {
|
||||||
|
int findA = findFather(a);
|
||||||
|
int findB = findFather(b);
|
||||||
|
if (findA == findB) {
|
||||||
|
if (size[findA] < size[findB]) {
|
||||||
|
parent[findA] = findB;
|
||||||
|
size[findB] += size[findA];
|
||||||
|
} else {
|
||||||
|
parent[findB] = findA;
|
||||||
|
size[findA] += size[findB];
|
||||||
|
}
|
||||||
|
allSet--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getAllSet() {
|
||||||
|
return allSet;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class 动态岛问题并查集 {
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
class 固定岛问题并查集 {
|
||||||
|
public int numIslands(char[][] board) {
|
||||||
|
int row = board.length;
|
||||||
|
int col = board[0].length;
|
||||||
|
//三个循环,判断是否认识
|
||||||
|
UnionFind uf = new UnionFind(board);
|
||||||
|
for (int j = 1; j < col; j++) {
|
||||||
|
if (board[0][j - 1] == '1' && board[0][j] == '1') {
|
||||||
|
uf.union(0, j - 1, 0, j);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (int i = 1; i < row; i++) {
|
||||||
|
if (board[i - 1][0] == '1' && board[i][0] == '1') {
|
||||||
|
uf.union(i - 1, 0, i, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 1; i < row; i++) {
|
||||||
|
for (int j = 1; j < col; j++) {
|
||||||
|
if (board[i][j] == '1') {
|
||||||
|
if (board[i - 1][j] == '1') {
|
||||||
|
uf.union(i - 1, j, i, j);
|
||||||
|
}
|
||||||
|
if (board[i][j - 1] == '1') {
|
||||||
|
uf.union(i, j - 1, i, j);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return uf.sets;
|
||||||
|
}
|
||||||
|
|
||||||
|
private class UnionFind {
|
||||||
|
private int[] parent;
|
||||||
|
private int[] size;
|
||||||
|
private int[] help;
|
||||||
|
int col;
|
||||||
|
int sets;
|
||||||
|
|
||||||
|
public UnionFind(char[][] board) {
|
||||||
|
col = board[0].length;
|
||||||
|
int row = board.length;
|
||||||
|
int len = col * row;
|
||||||
|
sets = 0;
|
||||||
|
|
||||||
|
parent = new int[len];
|
||||||
|
size = new int[len];
|
||||||
|
help = new int[len];
|
||||||
|
for (int i = 0; i < row; i++) {
|
||||||
|
for (int j = 0; j < col; j++) {
|
||||||
|
if (board[i][j] == '1') {
|
||||||
|
int index = getIndex(i, j);
|
||||||
|
parent[index] = index;
|
||||||
|
size[index] = 1;
|
||||||
|
sets++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getIndex(int i, int j) {
|
||||||
|
return col * i + j;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void union(int r1, int c1, int r2, int c2) {
|
||||||
|
int index1 = getIndex(r1, c1);
|
||||||
|
int index2 = getIndex(r2, c2);
|
||||||
|
int find1 = findFather(index1);
|
||||||
|
int find2 = findFather(index2);
|
||||||
|
if (find1 != find2) {
|
||||||
|
if (size[find1] < size[find2]) {
|
||||||
|
parent[find1] = find2;
|
||||||
|
size[find2] += size[find1];
|
||||||
|
} else {
|
||||||
|
parent[find2] = find1;
|
||||||
|
size[find1] += size[find2];
|
||||||
|
}
|
||||||
|
sets--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public int findFather(int i) {
|
||||||
|
int hi = 0;
|
||||||
|
while (i == parent[i]) {
|
||||||
|
help[hi++] = i;
|
||||||
|
i = parent[i];
|
||||||
|
}
|
||||||
|
while (hi >= 0) {
|
||||||
|
parent[help[hi--]] = i;
|
||||||
|
}
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//二维数组相邻的1连成一个岛
|
||||||
|
class 固定岛问题感染法 {
|
||||||
|
public int numIslands(char[][] board) {
|
||||||
|
int M = board.length;
|
||||||
|
int N = board[0].length;
|
||||||
|
int ans = 0;
|
||||||
|
for (int i = 0; i < M; i++) {
|
||||||
|
for (int j = 0; j < N; j++) {
|
||||||
|
if (board[i][j] == '1') {
|
||||||
|
dfs(board, i, j);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ans;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void dfs(char[][] board, int i, int j) {
|
||||||
|
if (i < 0 || i >= board.length || j < 0 || j >= board[0].length || board[i][j] != '1') {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
board[i][j] = 0;
|
||||||
|
dfs(board, i - 1, j);
|
||||||
|
dfs(board, i + 1, j);
|
||||||
|
dfs(board, i, j - 1);
|
||||||
|
dfs(board, i, j + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in new issue