Merge pull request #10 from algorithmzuo/master

merge
pull/3/head
ThankyouEverybody 5 years ago committed by GitHub
commit ca13e7e9f9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -30,9 +30,7 @@ public class Code01_IsCBT {
r = head.right; r = head.right;
if ( if (
// 如果遇到了不双全的节点之后,又发现当前节点不是叶节点 // 如果遇到了不双全的节点之后,又发现当前节点不是叶节点
(leaf && (l != null || r != null)) (leaf && (l != null || r != null)) || (l == null && r != null)
||
(l == null && r != null)
) { ) {
return false; return false;
@ -51,13 +49,9 @@ public class Code01_IsCBT {
} }
public static boolean isCBT2(Node head) { public static boolean isCBT2(Node head) {
if (head == null) {
return true;
}
return process(head).isCBT; return process(head).isCBT;
} }
// 对每一棵子树,是否是满二叉树、是否是完全二叉树、高度
public static class Info { public static class Info {
public boolean isFull; public boolean isFull;
public boolean isCBT; public boolean isCBT;
@ -70,50 +64,24 @@ public class Code01_IsCBT {
} }
} }
public static Info process(Node X) { public static Info process(Node x) {
if (X == null) { if (x == null) {
return new Info(true, true, 0); return new Info(true, true, 0);
} }
Info leftInfo = process(X.left); Info leftInfo = process(x.left);
Info rightInfo = process(X.right); Info rightInfo = process(x.right);
int height = Math.max(leftInfo.height, rightInfo.height) + 1; int height = Math.max(leftInfo.height, rightInfo.height) + 1;
boolean isFull = leftInfo.isFull && rightInfo.isFull && leftInfo.height == rightInfo.height;
boolean isFull = leftInfo.isFull
&&
rightInfo.isFull
&& leftInfo.height == rightInfo.height;
boolean isCBT = false; boolean isCBT = false;
if (isFull) { if (leftInfo.isFull && rightInfo.isFull && leftInfo.height == rightInfo.height) {
isCBT = true; isCBT = true;
} else { // 以x为头整棵树不满 } else if (leftInfo.isCBT && rightInfo.isFull && leftInfo.height == rightInfo.height + 1) {
if (leftInfo.isCBT && rightInfo.isCBT) {
if (leftInfo.isCBT
&& rightInfo.isFull
&& leftInfo.height == rightInfo.height + 1) {
isCBT = true; isCBT = true;
} } else if (leftInfo.isFull && rightInfo.isFull && leftInfo.height == rightInfo.height + 1) {
if (leftInfo.isFull
&&
rightInfo.isFull
&& leftInfo.height == rightInfo.height + 1) {
isCBT = true; isCBT = true;
} } else if (leftInfo.isFull && rightInfo.isCBT && leftInfo.height == rightInfo.height) {
if (leftInfo.isFull
&& rightInfo.isCBT && leftInfo.height == rightInfo.height) {
isCBT = true; isCBT = true;
} }
}
}
return new Info(isFull, isCBT, height); return new Info(isFull, isCBT, height);
} }

@ -49,49 +49,41 @@ public class Code03_lowestAncestor {
} }
} }
public static Node lowestAncestor2(Node head, Node o1, Node o2) { public static Node lowestAncestor2(Node head, Node a, Node b) {
return process(head, o1, o2).ans; return process(head, a, b).ans;
} }
// 任何子树,
public static class Info { public static class Info {
public boolean findA;
public boolean findB;
public Node ans; public Node ans;
public boolean findO1;
public boolean findO2;
public Info(Node a, boolean f1, boolean f2) { public Info(boolean fA, boolean fB, Node an) {
ans = a; findA = fA;
findO1 = f1; findB = fB;
findO2 = f2; ans = an;
} }
} }
public static Info process(Node X, Node o1, Node o2) { public static Info process(Node x, Node a, Node b) {
if (X == null) { if (x == null) {
return new Info(null, false, false); return new Info(false, false, null);
} }
Info leftInfo = process(X.left, o1, o2); Info leftInfo = process(x.left, a, b);
Info rightInfo = process(X.right, o1, o2); Info rightInfo = process(x.right, a, b);
boolean findO1 = X == o1 || leftInfo.findO1 || rightInfo.findO1; boolean findA = (x == a) || leftInfo.findA || rightInfo.findA;
boolean findO2 = X == o2 || leftInfo.findO2 || rightInfo.findO2; boolean findB = (x == b) || leftInfo.findB || rightInfo.findB;
// O1和O2最初的交汇点在哪
// 1) 在左树上已经提前交汇了
// 2) 在右树上已经提前交汇了
// 3) 没有在左树或者右树上提前交汇O1 O2 全了
// 4)
Node ans = null; Node ans = null;
if (leftInfo.ans != null) { if (leftInfo.ans != null) {
ans = leftInfo.ans; ans = leftInfo.ans;
} } else if (rightInfo.ans != null) {
if (rightInfo.ans != null) {
ans = rightInfo.ans; ans = rightInfo.ans;
} } else {
if (ans == null) { if (findA && findB) {
if (findO1 && findO2) { ans = x;
ans = X;
} }
} }
return new Info(ans, findO1, findO2); return new Info(findA, findB, ans);
} }
// for test // for test

@ -46,36 +46,34 @@ public class Code04_MaxHappy {
} }
} }
public static int maxHappy2(Employee boss) { public static int maxHappy2(Employee head) {
if (boss == null) { Info allInfo = process(head);
return 0; return Math.max(allInfo.no, allInfo.yes);
}
Info all = process2(boss);
return Math.max(all.yes, all.no);
} }
public static class Info { public static class Info {
public int yes;
public int no; public int no;
public int yes;
public Info(int y, int n) { public Info(int n, int y) {
yes = y;
no = n; no = n;
yes = y;
} }
} }
public static Info process2(Employee x) { public static Info process(Employee x) {
if (x.nexts.isEmpty()) { if (x == null) {
return new Info(x.happy, 0); return new Info(0, 0);
} }
int yes = x.happy;
int no = 0; int no = 0;
int yes = x.happy;
for (Employee next : x.nexts) { for (Employee next : x.nexts) {
Info nextInfo = process2(next); Info nextInfo = process(next);
no += Math.max(nextInfo.no, nextInfo.yes);
yes += nextInfo.no; yes += nextInfo.no;
no += Math.max(nextInfo.yes, nextInfo.no);
} }
return new Info(yes, no); return new Info(no, yes);
} }
// for test // for test

@ -1,9 +1,8 @@
package class09_13; package class09_13;
import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Comparator; import java.util.Comparator;
import java.util.HashSet; import java.util.TreeSet;
public class Code01_LowestLexicography { public class Code01_LowestLexicography {
@ -11,34 +10,41 @@ public class Code01_LowestLexicography {
if (strs == null || strs.length == 0) { if (strs == null || strs.length == 0) {
return ""; return "";
} }
ArrayList<String> all = new ArrayList<>(); TreeSet<String> ans = process(strs);
HashSet<Integer> use = new HashSet<>(); return ans.size() == 0 ? "" : ans.first();
process(strs, use, "", all);
String lowest = all.get(0);
for (int i = 1; i < all.size(); i++) {
if (all.get(i).compareTo(lowest) < 0) {
lowest = all.get(i);
}
}
return lowest;
} }
// strs里放着所有的字符串 // strs中所有字符串全排列返回所有可能的结果
// 已经使用过的字符串的下标在use里登记了不要再使用了 public static TreeSet<String> process(String[] strs) {
// 之前使用过的字符串,拼接成了-> path TreeSet<String> ans = new TreeSet<>();
// 用all收集所有可能的拼接结果 if (strs.length == 0) {
public static void process(String[] strs, HashSet<Integer> use, String path, ArrayList<String> all) { ans.add("");
if (use.size() == strs.length) { return ans;
all.add(path); }
} else {
for (int i = 0; i < strs.length; i++) { for (int i = 0; i < strs.length; i++) {
if (!use.contains(i)) { String first = strs[i];
use.add(i); String[] nexts = removeIndexString(strs, i);
process(strs, use, path + strs[i], all); TreeSet<String> next = process(nexts);
use.remove(i); for (String cur : next) {
ans.add(first + cur);
}
}
return ans;
} }
// {"abc", "cks", "bct"}
// 0 1 2
// removeIndexString(arr , 1) -> {"abc", "bct"}
public static String[] removeIndexString(String[] arr, int index) {
int N = arr.length;
String[] ans = new String[N - 1];
int ansIndex = 0;
for (int i = 0; i < N; i++) {
if (i != index) {
ans[ansIndex++] = arr[i];
} }
} }
return ans;
} }
public static class MyComparator implements Comparator<String> { public static class MyComparator implements Comparator<String> {
@ -91,13 +97,7 @@ public class Code01_LowestLexicography {
public static void main(String[] args) { public static void main(String[] args) {
int arrLen = 6; int arrLen = 6;
int strLen = 5; int strLen = 5;
int testTimes = 100000; int testTimes = 10000;
String[] arr = generateRandomStringArray(arrLen, strLen);
System.out.println("先打印一个生成的字符串");
for (String str : arr) {
System.out.print(str + ",");
}
System.out.println();
System.out.println("test begin"); System.out.println("test begin");
for (int i = 0; i < testTimes; i++) { for (int i = 0; i < testTimes; i++) {
String[] arr1 = generateRandomStringArray(arrLen, strLen); String[] arr1 = generateRandomStringArray(arrLen, strLen);

@ -18,9 +18,7 @@ public class Code01_Light {
if (index == str.length) { // 结束的时候 if (index == str.length) { // 结束的时候
for (int i = 0; i < str.length; i++) { for (int i = 0; i < str.length; i++) {
if (str[i] != 'X') { // 当前位置是点的话 if (str[i] != 'X') { // 当前位置是点的话
if (!lights.contains(i - 1) if (!lights.contains(i - 1) && !lights.contains(i) && !lights.contains(i + 1)) {
&& !lights.contains(i)
&& !lights.contains(i + 1)) {
return Integer.MAX_VALUE; return Integer.MAX_VALUE;
} }
} }
@ -41,20 +39,20 @@ public class Code01_Light {
public static int minLight2(String road) { public static int minLight2(String road) {
char[] str = road.toCharArray(); char[] str = road.toCharArray();
int index = 0; int i = 0;
int light = 0; int light = 0;
while (index < str.length) { while (i < str.length) {
if (str[index] == 'X') { if (str[i] == 'X') {
index++; i++;
} else { // i -> . } else {
light++; light++;
if (index + 1 == str.length) { if (i + 1 == str.length) {
break; break;
} else { // 有i位置 i+ 1 X .
if (str[i + 1] == 'X') {
i = i + 2;
} else { } else {
if (str[index + 1] == 'X') { i = i + 3;
index = index + 2;
} else {
index = index + 3;
} }
} }
} }

@ -4,6 +4,7 @@ import java.util.PriorityQueue;
public class Code02_LessMoneySplitGold { public class Code02_LessMoneySplitGold {
// 纯暴力!
public static int lessMoney1(int[] arr) { public static int lessMoney1(int[] arr) {
if (arr == null || arr.length == 0) { if (arr == null || arr.length == 0) {
return 0; return 0;
@ -11,6 +12,8 @@ public class Code02_LessMoneySplitGold {
return process(arr, 0); return process(arr, 0);
} }
// 等待合并的数都在arr里pre之前的合并行为产生了多少总代价
// arr中只剩一个数字的时候停止合并返回最小的总代价
public static int process(int[] arr, int pre) { public static int process(int[] arr, int pre) {
if (arr.length == 1) { if (arr.length == 1) {
return pre; return pre;

@ -15,6 +15,7 @@ public class Code03_BestArrange {
} }
} }
// 暴力!所有情况都尝试!
public static int bestArrange1(Program[] programs) { public static int bestArrange1(Program[] programs) {
if (programs == null || programs.length == 0) { if (programs == null || programs.length == 0) {
return 0; return 0;
@ -22,8 +23,8 @@ public class Code03_BestArrange {
return process(programs, 0, 0); return process(programs, 0, 0);
} }
// 还剩什么会议都放在programs里 // 还剩下的会议都放在programs里
// done 之前已经安排了多少会议,数量 // done之前已经安排了多少会议的数量
// timeLine目前来到的时间点是什么 // timeLine目前来到的时间点是什么
// 目前来到timeLine的时间点已经安排了done多的会议剩下的会议programs可以自由安排 // 目前来到timeLine的时间点已经安排了done多的会议剩下的会议programs可以自由安排
@ -32,7 +33,7 @@ public class Code03_BestArrange {
if (programs.length == 0) { if (programs.length == 0) {
return done; return done;
} }
// 还有会议可以选择 // 还剩下会议
int max = done; int max = done;
// 当前安排的会议是什么会,每一个都枚举 // 当前安排的会议是什么会,每一个都枚举
for (int i = 0; i < programs.length; i++) { for (int i = 0; i < programs.length; i++) {
@ -55,10 +56,12 @@ public class Code03_BestArrange {
return ans; return ans;
} }
// 会议的开始时间和结束时间,都是数值,不会 < 0
public static int bestArrange2(Program[] programs) { public static int bestArrange2(Program[] programs) {
Arrays.sort(programs, new ProgramComparator()); Arrays.sort(programs, new ProgramComparator());
int timeLine = 0; int timeLine = 0;
int result = 0; int result = 0;
// 依次遍历每一个会议,结束时间早的会议先遍历
for (int i = 0; i < programs.length; i++) { for (int i = 0; i < programs.length; i++) {
if (timeLine <= programs[i].start) { if (timeLine <= programs[i].start) {
result++; result++;

@ -5,6 +5,10 @@ import java.util.PriorityQueue;
public class Code04_IPO { public class Code04_IPO {
// 最多K个项目
// W是初始资金
// Profits[] Capital[] 一定等长
// 返回最终最大的资金
public static int findMaximizedCapital(int K, int W, int[] Profits, int[] Capital) { public static int findMaximizedCapital(int K, int W, int[] Profits, int[] Capital) {
PriorityQueue<Program> minCostQ = new PriorityQueue<>(new MinCostComparator()); PriorityQueue<Program> minCostQ = new PriorityQueue<>(new MinCostComparator());
PriorityQueue<Program> maxProfitQ = new PriorityQueue<>(new MaxProfitComparator()); PriorityQueue<Program> maxProfitQ = new PriorityQueue<>(new MaxProfitComparator());

@ -1,10 +1,10 @@
package class10; package class09_14;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Stack; import java.util.Stack;
public class Code01_UnionFind { public class Code05_UnionFind {
public static class Node<V> { public static class Node<V> {
V value; V value;
@ -31,14 +31,14 @@ public class Code01_UnionFind {
} }
} }
// 从点cur开始一直往上找找到不能再往上的代表点返回 // 给你一个节点,请你往上到不能再往上,把代表返回
public Node<V> findFather(Node<V> cur) { public Node<V> findFather(Node<V> cur) {
Stack<Node<V>> path = new Stack<>(); Stack<Node<V>> path = new Stack<>();
while (cur != parents.get(cur)) { while (cur != parents.get(cur)) {
path.push(cur); path.push(cur);
cur = parents.get(cur); cur = parents.get(cur);
} }
// cur头节点 // cur == parents.get(cur)
while (!path.isEmpty()) { while (!path.isEmpty()) {
parents.put(path.pop(), cur); parents.put(path.pop(), cur);
} }
@ -46,16 +46,10 @@ public class Code01_UnionFind {
} }
public boolean isSameSet(V a, V b) { public boolean isSameSet(V a, V b) {
if (!nodes.containsKey(a) || !nodes.containsKey(b)) {
return false;
}
return findFather(nodes.get(a)) == findFather(nodes.get(b)); return findFather(nodes.get(a)) == findFather(nodes.get(b));
} }
public void union(V a, V b) { public void union(V a, V b) {
if (!nodes.containsKey(a) || !nodes.containsKey(b)) {
return;
}
Node<V> aHead = findFather(nodes.get(a)); Node<V> aHead = findFather(nodes.get(a));
Node<V> bHead = findFather(nodes.get(b)); Node<V> bHead = findFather(nodes.get(b));
if (aHead != bHead) { if (aHead != bHead) {
@ -68,6 +62,10 @@ public class Code01_UnionFind {
sizeMap.remove(small); sizeMap.remove(small);
} }
} }
public int sets() {
return sizeMap.size();
} }
} }
}

@ -0,0 +1,248 @@
package class09_14;
import java.util.ArrayList;
import java.util.List;
import class09_14.Code05_UnionFind.UnionSet;
public class Code06_IslandProblem {
public static int solve1(int[][] board) {
int islands = 0;
for (int i = 0; i < board.length; i++) {
for (int j = 0; j < board[0].length; j++) {
if (board[i][j] == 1) {
islands++;
infect(board, i, j);
}
}
}
return islands;
}
public static void infect(int[][] 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] = 2;
infect(board, i - 1, j);
infect(board, i + 1, j);
infect(board, i, j - 1);
infect(board, i, j + 1);
}
public static int solve2(int[][] board) {
int row = board.length;
int col = board[0].length;
Dot[][] dots = new Dot[row][col];
List<Dot> dotList = new ArrayList<>();
for (int i = 0; i < row; i++) {
for (int j = 0; j < col; j++) {
if (board[i][j] == 1) {
dots[i][j] = new Dot();
dotList.add(dots[i][j]);
}
}
}
UnionSet<Dot> us = new UnionSet<>(dotList);
for (int j = 1; j < col; j++) {
if (board[0][j - 1] == 1 && board[0][j] == 1) {
us.union(dots[0][j - 1], dots[0][j]);
}
}
for (int i = 1; i < row; i++) {
if (board[i - 1][0] == 1 && board[i][0] == 1) {
us.union(dots[i - 1][0], dots[i][0]);
}
}
for (int i = 1; i < row; i++) {
for (int j = 1; j < col; j++) {
if (board[i][j] == 1) {
if (board[i][j - 1] == 1) {
us.union(dots[i][j - 1], dots[i][j]);
}
if (board[i - 1][j] == 1) {
us.union(dots[i - 1][j], dots[i][j]);
}
}
}
}
return us.sets();
}
public static class Dot {
}
public static int solve3(int[][] 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][j - 1] == 1) {
uf.union(i, j - 1, i, j);
}
if (board[i - 1][j] == 1) {
uf.union(i - 1, j, i, j);
}
}
}
}
return uf.sets();
}
public static class UnionFind {
private int[] parent;
private int[] size;
private int[] help;
private int col;
private int sets;
public UnionFind(int[][] board) {
col = board[0].length;
sets = 0;
int row = board.length;
int len = row * col;
parent = new int[len];
size = new int[len];
help = new int[len];
for (int r = 0; r < row; r++) {
for (int c = 0; c < col; c++) {
if (board[r][c] == 1) {
int i = index(r, c);
parent[i] = i;
size[i] = 1;
sets++;
}
}
}
}
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;
}
public void union(int r1, int c1, int r2, int c2) {
int i1 = index(r1, c1);
int i2 = index(r2, c2);
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 sets() {
return sets;
}
}
public static int[][] generateRandomMatrix(int row, int col) {
int[][] board = new int[row][col];
for (int i = 0; i < row; i++) {
for (int j = 0; j < col; j++) {
board[i][j] = Math.random() < 0.5 ? 1 : 0;
}
}
return board;
}
public static int[][] copy(int[][] board) {
int row = board.length;
int col = board[0].length;
int[][] ans = new int[row][col];
for (int i = 0; i < row; i++) {
for (int j = 0; j < col; j++) {
ans[i][j] = board[i][j];
}
}
return ans;
}
public static void main(String[] args) {
int row = 0;
int col = 0;
int[][] board1 = null;
int[][] board2 = null;
int[][] board3 = null;
long start = 0;
long end = 0;
row = 1000;
col = 1000;
board1 = generateRandomMatrix(row, col);
board2 = copy(board1);
board3 = copy(board1);
System.out.println("感染方法、并查集(map实现)、并查集(数组实现)的运行结果和运行时间");
System.out.println("随机生成的二维矩阵规模 : " + row + " * " + col);
start = System.currentTimeMillis();
System.out.println("感染方法的运行结果: " + solve1(board1));
end = System.currentTimeMillis();
System.out.println("感染方法的运行时间: " + (end - start) + " ms");
start = System.currentTimeMillis();
System.out.println("并查集(map实现)的运行结果: " + solve2(board2));
end = System.currentTimeMillis();
System.out.println("并查集(map实现)的运行时间: " + (end - start) + " ms");
start = System.currentTimeMillis();
System.out.println("并查集(数组实现)的运行结果: " + solve3(board3));
end = System.currentTimeMillis();
System.out.println("并查集(数组实现)的运行时间: " + (end - start) + " ms");
System.out.println();
row = 10000;
col = 10000;
board1 = generateRandomMatrix(row, col);
board3 = copy(board1);
System.out.println("感染方法、并查集(数组实现)的运行结果和运行时间");
System.out.println("随机生成的二维矩阵规模 : " + row + " * " + col);
start = System.currentTimeMillis();
System.out.println("感染方法的运行结果: " + solve1(board1));
end = System.currentTimeMillis();
System.out.println("感染方法的运行时间: " + (end - start) + " ms");
start = System.currentTimeMillis();
System.out.println("并查集(数组实现)的运行结果: " + solve3(board3));
end = System.currentTimeMillis();
System.out.println("并查集(数组实现)的运行时间: " + (end - start) + " ms");
}
}

@ -4,7 +4,7 @@ import java.util.HashSet;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.Queue; import java.util.Queue;
public class Code02_BFS { public class Code01_BFS {
// 从node出发进行宽度优先遍历 // 从node出发进行宽度优先遍历
public static void bfs(Node node) { public static void bfs(Node node) {

@ -0,0 +1,58 @@
package class12;
// 这个问题leetcode上可以直接测
// 链接https://leetcode.com/problems/longest-common-subsequence/
public class Code05_LongestCommonSubsequence {
public static int longestCommonSubsequence1(String text1, String text2) {
if (text1 == null || text2 == null || text1.length() == 0 || text2.length() == 0) {
return 0;
}
return process(text1.toCharArray(), text2.toCharArray(), text1.length() - 1, text2.length() - 1);
}
// str1[0..i]与str2[0..j]最长公共子序列多长
public static int process(char[] str1, char[] str2, int i, int j) {
if (i == 0 && j == 0) {
return str1[0] == str2[0] ? 1 : 0;
}
if (i == 0) {
return str1[0] == str2[j] ? 1 : process(str1, str2, 0, j - 1);
}
if (j == 0) {
return str1[i] == str2[0] ? 1 : process(str1, str2, i - 1, 0);
}
int p1 = process(str1, str2, i - 1, j);
int p2 = process(str1, str2, i, j - 1);
int p3 = str1[i] == str2[j] ? (process(str1, str2, i - 1, j - 1) + 1) : 0;
return Math.max(Math.max(p1, p2), p3);
}
public static int longestCommonSubsequence2(String text1, String text2) {
if (text1 == null || text2 == null || text1.length() == 0 || text2.length() == 0) {
return 0;
}
char[] str1 = text1.toCharArray();
char[] str2 = text2.toCharArray();
int N = str1.length;
int M = str2.length;
int[][] dp = new int[N][M];
dp[0][0] = str1[0] == str2[0] ? 1 : 0;
for (int i = 1; i < N; i++) {
dp[i][0] = str1[i] == str2[0] ? 1 : dp[i - 1][0];
}
for (int j = 1; j < M; j++) {
dp[0][j] = str1[0] == str2[j] ? 1 : dp[0][j - 1];
}
for (int i = 1; i < N; i++) {
for (int j = 1; j < M; j++) {
dp[i][j] = Math.max(dp[i - 1][j], dp[i][j - 1]);
if (str1[i] == str2[j]) {
dp[i][j] = Math.max(dp[i][j], dp[i - 1][j - 1] + 1);
}
}
}
return dp[N - 1][M - 1];
}
}
Loading…
Cancel
Save