linkedList = new LinkedList<>();
+ linkedList.add(root);
+
+ while (!linkedList.isEmpty()) {
+
+ int size = linkedList.size();
+
+ for (int i = 0; i < size; i++) {
+ TreeNode node = linkedList.poll();
+ if (node.left != null) {
+ linkedList.add(node.left);
+ }
+
+ if (node.right != null) {
+ linkedList.add(node.right);
+ }
+
+ TreeNode temp = node.left;
+ node.left = node.right;
+ node.right = temp;
+ }
+ }
+ return root;
+ }
+
+
+ @Test
+ public void testCase() {
+
+
+ TreeNode elementLeft_2_1 = new TreeNode(10, null, null);
+ TreeNode elementRight_2_1 = new TreeNode(60, null, null);
+ TreeNode elementLeft_2_2_1 = new TreeNode(110, null, null);
+
+ TreeNode elementLeft_1_1 = new TreeNode(50, elementLeft_2_1, elementRight_2_1);
+ TreeNode elementRight_1_1 = new TreeNode(120, elementLeft_2_2_1, null);
+
+ TreeNode root = new TreeNode(100, elementLeft_1_1, elementRight_1_1);
+
+ System.out.println("before===="+JSONObject.toJSONString(root));
+
+ revert(root);
+
+ System.out.println("after===="+JSONObject.toJSONString(root));
+
+ }
+
+
+}
diff --git a/src/main/java/com/chen/algorithm/array/ArrayFind.java b/src/main/java/com/chen/algorithm/array/ArrayFind.java
new file mode 100644
index 0000000..640293b
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/array/ArrayFind.java
@@ -0,0 +1,32 @@
+package com.chen.algorithm.array;
+
+/**
+ * 二维数组,从上到下递增;从左到右递增;
+ * 查找二维数组中是否含有某个整数
+ *
+ * @author : chen weijie
+ * @Date: 2020-04-28 19:17
+ */
+public class ArrayFind {
+
+
+ public boolean find(int target, int[][] array) {
+
+ int row = array.length - 1;
+ int column = 0;
+
+ while (row >= 0 && column <= array[0].length) {
+ if (array[row][column] > target) {
+ row--;
+ } else if (array[row][column] < target) {
+ column++;
+ } else {
+ return true;
+ }
+ }
+
+
+ return false;
+ }
+
+}
diff --git a/src/main/java/com/chen/algorithm/backtrack/Cal8queens.java b/src/main/java/com/chen/algorithm/backtrack/Cal8queens.java
new file mode 100644
index 0000000..bc06bc0
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/backtrack/Cal8queens.java
@@ -0,0 +1,70 @@
+package com.chen.algorithm.backtrack;
+
+import org.junit.Test;
+
+/**
+ * 使用回溯算法解决8皇后问题
+ *
+ * @author : chen weijie
+ * @Date: 2020-05-01 18:04
+ */
+public class Cal8queens {
+
+
+ int[] result = new int[8];//全局或成员变量,下标表示行,值表示queen存储在哪一列
+
+ public void cal8queens(int row) { // 调用方式:cal8queens(0);
+ if (row == 8) { // 8个棋子都放置好了,打印结果
+ printQueens(result);
+ return; // 8行棋子都放好了,已经没法再往下递归了,所以就return
+ }
+ for (int column = 0; column < 8; ++column) { // 每一行都有8中放法
+ if (isOk(row, column)) { // 有些放法不满足要求
+ result[row] = column; // 第row行的棋子放到了column列
+ cal8queens(row + 1); // 考察下一行
+ }
+ }
+ }
+
+ private boolean isOk(int row, int column) {//判断row行column列放置是否合适
+ int leftup = column - 1, rightup = column + 1;
+ for (int i = row - 1; i >= 0; --i) { // 逐行往上考察每一行
+ if (result[i] == column) {
+ return false; // 第i行的column列有棋子吗?
+ }
+ if (leftup >= 0) { // 考察左上对角线:第i行leftup列有棋子吗?
+ if (result[i] == leftup) {
+ return false;
+ }
+ }
+ if (rightup < 8) { // 考察右上对角线:第i行rightup列有棋子吗?
+ if (result[i] == rightup) {
+ return false;
+ }
+ }
+ --leftup;
+ ++rightup;
+ }
+ return true;
+ }
+
+ private void printQueens(int[] result) { // 打印出一个二维矩阵
+ for (int row = 0; row < 8; ++row) {
+ for (int column = 0; column < 8; ++column) {
+ if (result[row] == column) {
+ System.out.print("Q ");
+ } else {
+ System.out.print("* ");
+ }
+ }
+ System.out.println();
+ }
+ System.out.println();
+ }
+
+
+ @Test
+ public void main() {
+ cal8queens(0);
+ }
+}
diff --git a/src/main/java/com/chen/algorithm/backtrack/Mindist.java b/src/main/java/com/chen/algorithm/backtrack/Mindist.java
new file mode 100644
index 0000000..eea7cb5
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/backtrack/Mindist.java
@@ -0,0 +1,35 @@
+package com.chen.algorithm.backtrack;
+
+/**
+ * 最短路径问题
+ *
+ * @author : chen weijie
+ * @Date: 2020-05-01 22:25
+ */
+public class Mindist {
+
+
+ // 全局变量或者成员变量
+ private int minDist = Integer.MAX_VALUE;
+
+ // 调用方式:minDistBacktracing(0, 0, 0, w, n);
+ public void minDistBT(int i, int j, int dist, int[][] w, int n) {
+ // 到达了n-1, n-1这个位置了,这里看着有点奇怪哈,你自己举个例子看下
+ if (i == n && j == n) {
+ if (dist < minDist) {
+ minDist = dist;
+ }
+ return;
+ }
+ // 往下走,更新i=i+1, j=j
+ if (i < n) {
+ minDistBT(i + 1, j, dist + w[i][j], w, n);
+ }
+ // 往右走,更新i=i, j=j+1
+ if (j < n) {
+ minDistBT(i, j + 1, dist + w[i][j], w, n);
+ }
+ }
+
+
+}
diff --git a/src/main/java/com/chen/algorithm/backtrack/ZeroOneBag.java b/src/main/java/com/chen/algorithm/backtrack/ZeroOneBag.java
new file mode 100644
index 0000000..11ec9af
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/backtrack/ZeroOneBag.java
@@ -0,0 +1,52 @@
+package com.chen.algorithm.backtrack;
+
+/**
+ * 0-1 背包问题
+ *
+ *
+ * 我们有一个背包,背包总的承载重量是Wkg。现在我们有n个物品,每个物品的重量不等,并且不可分割。我们现在期望选择几件物品,
+ * 装载到背包中。在不超过背包所能装载重量的前提下,如何让背包中物品的总重量最大?
+ *
+ * @author : chen weijie
+ * @Date: 2020-05-01 18:10
+ */
+public class ZeroOneBag {
+
+
+ //存储背包中物品总重量的最大值
+ public int maxW = Integer.MIN_VALUE;
+
+
+ /**
+ * // cw表示当前已经装进去的物品的重量和;i表示考察到哪个物品了;
+ * // w背包重量;items表示每个物品的重量;n表示物品个数
+ * // 假设背包可承受重量100,物品个数10,物品重量存储在数组a中,那可以这样调用函数:
+ * // f(0, 0, a, 10, 100)
+ *
+ * 我们可以把物品依次排列,整个问题就分解为了 n 个阶段,每个阶段对应一个物品怎么选择。
+ * 先对第一个物品进行处理,选择装进去或者不装进去,然后再递归地处理剩下的物品。
+ *
+ * @param i
+ * @param cw
+ * @param items
+ * @param n
+ * @param w
+ */
+ public void solution(int i, int cw, int[] items, int n, int w) {
+ // cw==w表示装满了;i==n表示已经考察完所有的物品
+ if (cw == w || i == n) {
+ if (cw > maxW) {
+ maxW = cw;
+ }
+ return;
+ }
+ solution(i + 1, cw, items, n, w);
+ // 已经超过可以背包承受的重量的时候,就不要再装了
+ if (cw + items[i] <= w) {
+ solution(i + 1, cw + items[i], items, n, w);
+ }
+ }
+
+
+
+}
diff --git a/src/main/java/com/chen/algorithm/backtrack/ZeroOneBag2.java b/src/main/java/com/chen/algorithm/backtrack/ZeroOneBag2.java
new file mode 100644
index 0000000..0bed150
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/backtrack/ZeroOneBag2.java
@@ -0,0 +1,40 @@
+package com.chen.algorithm.backtrack;
+
+/**
+ * 0-1 背包问题
+ *
+ *
+ * 我们有一个背包,背包总的承载重量是Wkg。现在我们有n个物品,每个物品的重量不等,并且不可分割。我们现在期望选择几件物品,
+ * 装载到背包中。在不超过背包所能装载重量的前提下,如何让背包中物品的总重量最大?
+ *
+ * @author : chen weijie
+ * @Date: 2020-05-01 18:10
+ */
+public class ZeroOneBag2 {
+
+
+ private int maxW = Integer.MIN_VALUE; // 结果放到maxW中
+ private int[] weight = {2, 2, 4, 6, 3}; // 物品重量
+ private int n = 5; // 物品个数
+ private int w = 9; // 背包承受的最大重量
+ private boolean[][] mem = new boolean[5][10]; // 备忘录,默认值false
+
+ public void f(int i, int cw) { // 调用f(0, 0)
+ if (cw == w || i == n) { // cw==w表示装满了,i==n表示物品都考察完了
+ if (cw > maxW) {
+ maxW = cw;
+ }
+ return;
+ }
+ if (mem[i][cw]) {
+ return; // 重复状态
+ }
+ mem[i][cw] = true; // 记录(i, cw)这个状态
+ f(i + 1, cw); // 选择不装第i个物品
+ if (cw + weight[i] <= w) {
+ f(i + 1, cw + weight[i]); // 选择装第i个物品
+ }
+ }
+
+
+}
diff --git a/src/main/java/com/chen/algorithm/bsearch/AdviceBsearch.java b/src/main/java/com/chen/algorithm/bsearch/AdviceBsearch.java
new file mode 100644
index 0000000..d1929a0
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/bsearch/AdviceBsearch.java
@@ -0,0 +1,126 @@
+package com.chen.algorithm.bsearch;
+
+import org.junit.Test;
+
+/**
+ * https://blog.csdn.net/bat67/article/details/72049104
+ *
+ * @author : chen weijie
+ * @Date: 2020-07-03 16:45
+ */
+public class AdviceBsearch {
+
+
+ /**
+ * 获取第一个等于target的目标,当key=array[mid]时, 往左边一个一个逼近,right = mid -1; 返回left
+ * @param array
+ * @param target
+ * @return
+ */
+ public int bSearch(int[] array, int target) {
+
+ int left = 0, right = array.length - 1;
+
+ while (right >= left) {
+ int mid = (right + left) / 2;
+ if (array[mid] >= target) {
+ right = mid - 1;
+ } else {
+ left = mid + 1;
+ }
+ }
+ if (left < array.length && array[left] == target) {
+ return left;
+ }
+
+
+ return -1;
+ }
+
+
+
+
+
+
+
+ /**
+ * 获取最后一个等于target的目标,当key=array[mid]时, 往右边一个一个逼近,left = mid + 1; 返回right
+ * @param array
+ * @param target
+ * @return
+ */
+ public int bSearch2(int[] array, int target) {
+
+ int left = 0, right = array.length - 1;
+
+ while (right >= left) {
+ int mid = (right + left) / 2;
+ if (array[mid] > target) {
+ right = mid - 1;
+ } else {
+ left = mid + 1;
+ }
+ }
+
+ if (right >= 0 && array[right] == target) {
+ return right;
+ }
+
+ return -1;
+ }
+
+ /**
+ * 获取最后一个小于等于target的目标,当key=array[mid]时, 往右边一个一个逼近,left = mid + 1; 返回right
+ * @param array
+ * @param target
+ * @return
+ */
+ public int bSearch3(int[] array, int target) {
+
+ int left = 0, right = array.length - 1;
+
+ while (right >= left) {
+ int mid = (right + left) / 2;
+ if (array[mid] > target) {
+ right = mid - 1;
+ } else {
+ left = mid + 1;
+ }
+ }
+ return right;
+ }
+
+ /**
+ * 查找第一个等于或者大于target的目标,当key=array[mid]时, 往左边一个一个逼近,right = mid - 1; 返回left
+ * @param array
+ * @param target
+ * @return
+ */
+ public int bSearch4(int[] array, int target) {
+
+ int left = 0, right = array.length - 1;
+
+ while (right >= left) {
+ int mid = (right + left) / 2;
+ if (array[mid] >= target) {
+ right = mid - 1;
+ } else {
+ left = mid + 1;
+ }
+ }
+ return left;
+ }
+
+
+
+ @Test
+ public void test() {
+
+ int[] n = {3, 4, 5, 7, 8, 9, 10};
+ int res = bSearch4(n, 6);
+ System.out.println(res);
+
+ }
+
+
+}
diff --git a/src/main/java/com/chen/algorithm/bsearch/AdviceBsearch2.java b/src/main/java/com/chen/algorithm/bsearch/AdviceBsearch2.java
new file mode 100644
index 0000000..6b1dee7
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/bsearch/AdviceBsearch2.java
@@ -0,0 +1,122 @@
+package com.chen.algorithm.bsearch;
+
+import org.junit.Test;
+
+/**
+ * https://blog.csdn.net/bat67/article/details/72049104
+ *
+ * @author : chen weijie
+ * @Date: 2020-07-03 16:45
+ */
+public class AdviceBsearch2 {
+
+
+ /**
+ * 获取第一个等于target的目标,当key=array[mid]时, 往左边一个一个逼近,right = mid -1; 返回left
+ *
+ * @param array
+ * @param target
+ * @return
+ */
+ public int bSearch(int[] array, int target) {
+
+ int start = 0, end = array.length - 1;
+ while (end >= start) {
+ int mid = start + (end - start) / 2;
+
+ if (array[mid] >= target) {
+ end = mid - 1;
+ } else {
+ start = mid + 1;
+ }
+ }
+
+ if (start < array.length - 1 && array[start] == target) {
+ return start;
+ }
+ return -1;
+ }
+
+
+ /**
+ * 获取最后一个等于target的目标,当key=array[mid]时, 往右边一个一个逼近,left = mid + 1; 返回right
+ *
+ * @param array
+ * @param target
+ * @return
+ */
+ public int bSearch2(int[] array, int target) {
+
+ int left = 0, right = array.length - 1;
+
+ while (right >= left) {
+ int mid = left + (right - left) / 2;
+ if (array[mid] > target) {
+ right = mid - 1;
+ } else {
+ left = mid + 1;
+ }
+ }
+
+ if (right >= 0 && array[right] == target) {
+ return right;
+ }
+ return -1;
+ }
+
+ /**
+ * 获取最后一个小于等于target的目标,当key=array[mid]时, 往右边一个一个逼近,left = mid + 1; 返回right
+ *
+ * @param array
+ * @param target
+ * @return
+ */
+ public int bSearch3(int[] array, int target) {
+ int left = 0, right = array.length - 1;
+ while (right >= left) {
+ int mid = left + (right - left) / 2;
+ if (array[mid] > target) {
+ right = mid - 1;
+ } else {
+ left = mid + 1;
+ }
+ }
+
+ return right;
+ }
+
+ /**
+ * 查找第一个等于或者大于target的目标,当key=array[mid]时, 往左边一个一个逼近,right = mid - 1; 返回left
+ *
+ * @param array
+ * @param target
+ * @return
+ */
+ public int bSearch4(int[] array, int target) {
+
+ int left =0, right = array.length -1;
+
+ while (left <= right){
+ int mid = (right - left) / 2 + left;
+ if (target > array[mid]) {
+ left = mid + 1;
+ } else {
+ right = mid - 1;
+ }
+ }
+
+ return left;
+ }
+
+
+ @Test
+ public void test() {
+
+ int[] n = {3, 4, 5, 7, 8, 9, 10};
+ int res = bSearch4(n, 6);
+ System.out.println(res);
+
+ }
+
+
+}
diff --git a/src/main/java/com/chen/algorithm/bsearch/HanNuoTa.java b/src/main/java/com/chen/algorithm/bsearch/HanNuoTa.java
new file mode 100644
index 0000000..0d2f055
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/bsearch/HanNuoTa.java
@@ -0,0 +1,35 @@
+package com.chen.algorithm.bsearch;
+
+/**
+ * @author : chen weijie
+ * @Date: 2020-05-02 11:56
+ */
+public class HanNuoTa {
+
+ /**
+ * 汉诺塔问题
+ *
+ * @param dish 盘子个数
+ * @param from 初始塔数
+ * @param temp 中介塔数
+ * @param to 目标塔数
+ */
+ public static void move(int dish, String from, String temp, String to) {
+
+ if (dish == 1) {
+ System.out.println("将盘子" + dish + "从塔座" + from + "移动到目标塔座" + to);
+ } else {
+ //A为初始塔,B为目标塔,C为中介塔
+ move(dish - 1, from, to, temp);
+ System.out.println("将盘子" + dish + "从塔座" + from + "移动到目标塔座" + to);
+ //B为初始塔,C为目标塔,A是中介塔
+ move(dish - 1, temp, from, to);
+ }
+ }
+
+
+ public static void main(String[] args) {
+
+ move(4, "A", "C", "B");
+ }
+}
diff --git a/src/main/java/com/chen/algorithm/recursion/Search.java b/src/main/java/com/chen/algorithm/bsearch/Search.java
similarity index 64%
rename from src/main/java/com/chen/algorithm/recursion/Search.java
rename to src/main/java/com/chen/algorithm/bsearch/Search.java
index a7f7d93..578f961 100644
--- a/src/main/java/com/chen/algorithm/recursion/Search.java
+++ b/src/main/java/com/chen/algorithm/bsearch/Search.java
@@ -1,4 +1,4 @@
-package com.chen.algorithm.recursion;
+package com.chen.algorithm.bsearch;
/**
* 不用递归的二分查找
@@ -17,7 +17,6 @@ public class Search {
* @return
*/
public static int findTwoPoint(int[] array, int key) {
-
if (array == null || array.length == 0) {
return -1;
}
@@ -28,13 +27,10 @@ public static int findTwoPoint(int[] array, int key) {
while (max >= min) {
int mid = (max + min) / 2;
-
if (key == array[mid]) {
return mid;
}
-
if (key > array[mid]) {
-
min = mid + 1;
}
@@ -79,32 +75,7 @@ public static int sort(int low, int high, int[] array, int key) {
}
- /**
- * 汉诺塔问题
- *
- * @param dish 盘子个数
- * @param from 初始塔数
- * @param temp 中介塔数
- * @param to 目标塔数
- */
- public static void move(int dish, String from, String temp, String to) {
-
- if (dish == 1) {
- System.out.println("将盘子" + dish + "从塔座" + from + "移动到目标塔座" + to);
- } else {
- //A为初始塔,B为目标塔,C为中介塔
- move(dish - 1, from, to, temp);
- System.out.println("将盘子" + dish + "从塔座" + from + "移动到目标塔座" + to);
- //B为初始塔,C为目标塔,A是中介塔
- move(dish - 1, temp, from, to);
- }
- }
-
-
- public static void main(String[] args) {
- move(4,"A","C","B");
- }
}
diff --git a/src/main/java/com/chen/algorithm/dynamicprogramming/MinDistDP.java b/src/main/java/com/chen/algorithm/dynamicprogramming/MinDistDP.java
new file mode 100644
index 0000000..1807f53
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/dynamicprogramming/MinDistDP.java
@@ -0,0 +1,76 @@
+package com.chen.algorithm.dynamicprogramming;
+
+/**
+ * 最短路径问题,
+ * 使用动态规划的
+ *
+ * @author : chen weijie
+ * @Date: 2020-05-01 22:25
+ */
+public class MinDistDP {
+
+
+ /**
+ * 状态转移表法表 来解决问题
+ * @param matrix
+ * @param n
+ * @return
+ */
+ public int minDistDP(int[][] matrix, int n) {
+ int[][] states = new int[n][n];
+ int sum = 0;
+ // 初始化states的第一行数据
+ for (int j = 0; j < n; ++j) {
+ sum += matrix[0][j];
+ states[0][j] = sum;
+ }
+ sum = 0;
+ // 初始化states的第一列数据
+ for (int i = 0; i < n; ++i) {
+ sum += matrix[i][0];
+ states[i][0] = sum;
+ }
+ for (int i = 1; i < n; ++i) {
+ for (int j = 1; j < n; ++j) {
+ states[i][j] = matrix[i][j] + Math.min(states[i][j - 1], states[i - 1][j]);
+ }
+ }
+ return states[n - 1][n - 1];
+ }
+
+
+ private int[][] matrix = {{1, 3, 5, 9}, {2, 1, 3, 4}, {5, 2, 6, 7}, {6, 8, 4, 3}};
+ private int n = 4;
+ private int[][] mem = new int[4][4];
+
+
+ /**
+ * 状态转移方程来解决问题
+ *
+ * @param i
+ * @param j
+ * @return
+ */
+ public int minDist(int i, int j) { // 调用minDist(n-1, n-1);
+ if (i == 0 && j == 0) {
+ return matrix[0][0];
+ }
+ if (mem[i][j] > 0) {
+ return mem[i][j];
+ }
+ int minLeft = Integer.MAX_VALUE;
+ if (j - 1 >= 0) {
+ minLeft = minDist(i, j - 1);
+ }
+ int minUp = Integer.MAX_VALUE;
+ if (i - 1 >= 0) {
+ minUp = minDist(i - 1, j);
+ }
+
+ int currMinDist = matrix[i][j] + Math.min(minLeft, minUp);
+ mem[i][j] = currMinDist;
+ return currMinDist;
+ }
+
+
+}
diff --git a/src/main/java/com/chen/algorithm/dynamicprogramming/ZeroOndBag3.java b/src/main/java/com/chen/algorithm/dynamicprogramming/ZeroOndBag3.java
new file mode 100644
index 0000000..b24de62
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/dynamicprogramming/ZeroOndBag3.java
@@ -0,0 +1,59 @@
+package com.chen.algorithm.dynamicprogramming;
+
+/**
+ * 动态规划实现背包问题
+ * 我们有一个背包,背包总的承载重量是Wkg。现在我们有n个物品,每个物品的重量不等,并且不可分割。我们现在期望选择几件物品,
+ * 装载到背包中。在不超过背包所能装载重量的前提下,如何让背包中物品的总重量最大?
+ *
+ * @author : chen weijie
+ * @Date: 2020-05-01 18:41
+ */
+public class ZeroOndBag3 {
+
+
+ /**
+ * 我们把整个求解过程分为n个阶段,每个阶段会决策一个物品是否放到背包中。每个物品决策(放入或者不放入背包)完之后,背包中的物品的重量会有多种情况,也就是说,会达到多种不同的状态,对应到递归树中,就是有很多不同的节点。
+ *
+ * 我们把每一层重复的状态(节点)合并,只记录不同的状态,然后基于上一层的状态集合,来推导下一层的状态集合。我们可以通过合并每一层重复的状态,这样就保证每一层不同状态的个数都不会超过w个(w表示背包的承载重量),也就是例子中的9。于是,我们就成功避免了每层状态个数的指数级增长。
+ *
+ * 我们用一个二维数组states[n][w+1],来记录每层可以达到的不同状态。
+ *
+ * 第0个(下标从0开始编号)物品的重量是2,要么装入背包,要么不装入背包,决策完之后,会对应背包的两种状态,背包中物品的总重量是0或者2。我们用states[0][0]=true和states[0][2]=true来表示这两种状态。
+ *
+ * 第1个物品的重量也是2,基于之前的背包状态,在这个物品决策完之后,不同的状态有3个,背包中物品总重量分别是0(0+0),2(0+2 or 2+0),4(2+2)。我们用states[1][0]=true,states[1][2]=true,states[1][4]=true来表示这三种状态。
+ *
+ * 以此类推,直到考察完所有的物品后,整个states状态数组就都计算好了。我把整个计算的过程画了出来,你可以看看。图中0表示false,1表示true。我们只需要在最后一层,找一个值为true的最接近w(这里是9)的值,就是背包中物品总重量的最大值。
+ * @param weight
+ * @param n
+ * @param w
+ * @return
+ */
+
+ // weight:物品重量(2、2、4、6、3),n:物品个数(0-5),w:背包可承载重量(0-9)
+ public int knapsack(int[] weight, int n, int w) {
+
+ boolean[][] states = new boolean[n][w + 1]; // 默认值false
+ states[0][0] = true; // 第一行的数据要特殊处理,可以利用哨兵优化
+ states[0][weight[0]] = true;
+ for (int i = 1; i < n; ++i) { // 动态规划状态转移
+ for (int j = 0; j <= w; ++j) {// 不把第i个物品放入背包
+ if (states[i - 1][j] == true) {
+ states[i][j] = states[i - 1][j];
+ }
+ }
+ for (int j = 0; j <= w - weight[i]; ++j) {//把第i个物品放入背包
+ if (states[i - 1][j] == true) {
+ states[i][j + weight[i]] = true;
+ }
+ }
+ }
+ for (int i = w; i >= 0; --i) { // 输出结果
+ if (states[n - 1][i] == true) {
+ return i;
+ }
+ }
+ return 0;
+ }
+
+
+}
diff --git a/src/main/java/com/chen/algorithm/exercise/exercise4/TwoBranchTree.java b/src/main/java/com/chen/algorithm/exercise/exercise4/TwoBranchTree.java
new file mode 100644
index 0000000..75d0f26
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/exercise/exercise4/TwoBranchTree.java
@@ -0,0 +1,86 @@
+package com.chen.algorithm.exercise.exercise4;
+
+/**
+ * @author Chen WeiJie
+ * @date 2020-04-21 18:07:23
+ **/
+public class TwoBranchTree {
+
+
+ public static class TreeNode {
+
+ int value;
+
+ TreeNode leftNode;
+
+ TreeNode rightNode;
+
+
+ }
+
+
+ private TreeNode root = new TreeNode();
+
+
+ /**
+ * 二叉树查找
+ *
+ * @param value
+ * @return
+ */
+ public TreeNode findNode(int value) {
+
+ if (root == null) {
+ return null;
+ }
+
+ while (true) {
+
+ if (root == null) {
+ return null;
+ }
+
+ if (root.value == value) {
+ return root;
+ } else if (value > root.value) {
+ root = root.rightNode;
+ } else {
+ root = root.leftNode;
+ }
+ }
+ }
+
+
+ public void insertNode(TreeNode newNode) {
+
+
+ TreeNode parent = root;
+ while (true) {
+ if (root == null) {
+ break;
+ }
+
+ parent = root;
+ if (root.value < newNode.value) {
+ root = root.rightNode;
+ } else {
+ root = root.leftNode;
+ }
+
+ }
+
+
+ if (parent != null) {
+ if (newNode.value < parent.value) {
+ parent.leftNode = newNode;
+ } else {
+ parent.rightNode = newNode;
+ }
+
+ }
+
+
+ }
+
+
+}
diff --git a/src/main/java/com/chen/algorithm/exercise/heap/Heap.java b/src/main/java/com/chen/algorithm/exercise/heap/Heap.java
new file mode 100644
index 0000000..eaed12b
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/exercise/heap/Heap.java
@@ -0,0 +1,115 @@
+package com.chen.algorithm.exercise.heap;
+
+/**
+ *
+ * 堆化非常简单,就是顺着节点所在的路径,向上或者向下,对比,然后交换。
+ *
+ * 我这里画了一张堆化的过程分解图。我们可以让新插入的节点与父节点对比大小。如果不满足子节点小于等于父节点的大小关系,我们就互换两个节点。一直重复这个过程,直到父子节点之间满足刚说的那种大小关系。
+ *
+ * @author : chen weijie
+ * @Date: 2020-04-19 18:44
+ */
+public class Heap {
+
+ private int[] a; // 数组,从下标1开始存储数据
+ private int n; // 堆可以存储的最大数据个数
+ private int count; // 堆中已经存储的数据个数
+
+ public Heap(int capacity) {
+ a = new int[capacity + 1];
+ n = capacity;
+ count = 0;
+ }
+
+ public void insert(int data) {
+ if (count >= n) {
+ return; // 堆满了
+ }
+ ++count;
+ a[count] = data;
+ int i = count;
+ while (i / 2 > 0 && a[i] > a[i / 2]) { // 自下往上堆化
+ swap(a, i, i / 2); // swap()函数作用:交换下标为i和i/2的两个元素
+ i = i / 2;
+ }
+ }
+
+
+ /**
+ * 我们把最后一个节点放到堆顶,然后利用同样的父子节点对比方法。对于不满足父子节点大小关系的,
+ * 互换两个节点,并且重复进行这个过程,直到父子节点之间满足大小关系为止。这就是从上往下的堆化方法
+ */
+ public void removeMax() {
+ if (count == 0) {
+ // 堆中没有数据
+ return;
+ }
+ a[1] = a[count];
+ --count;
+ heapify(a, count, 1);
+ }
+
+
+ /**
+ * 建堆
+ *
+ * @param a
+ * @param n
+ */
+ private static void buildHeap(int[] a, int n) {
+ for (int i = n / 2; i >= 1; --i) {
+ heapify(a, n, i);
+ }
+ }
+
+ /**
+ * 堆排序
+ *
+ * @param a
+ * @param n
+ */
+ public static void sort(int[] a, int n) {
+ buildHeap(a, n);
+ int k = n;
+ while (k > 1) {
+ swap(a, 1, k);
+ --k;
+ heapify(a, k, 1);
+ }
+ }
+
+
+
+
+ private static void heapify(int[] a, int n, int i) { // 自上往下堆化
+ while (true) {
+ int maxPos = i;
+ if (i * 2 <= n && a[i] < a[i * 2]) {
+ maxPos = i * 2;
+ }
+ if (i * 2 + 1 <= n && a[maxPos] < a[i * 2 + 1]) {
+ maxPos = i * 2 + 1;
+ }
+ if (maxPos == i) {
+ break;
+ }
+ swap(a, i, maxPos);
+ i = maxPos;
+ }
+ }
+
+
+ /**
+ *
+ * @param a
+ * @param i
+ * @param j
+ */
+ public static void swap(int[] a, int i, int j) {
+ int tem = a[i];
+ a[i] = a[j];
+ a[j] = tem;
+ }
+
+
+}
diff --git a/src/main/java/com/chen/algorithm/exercise/strmatch/BMStrMatch.java b/src/main/java/com/chen/algorithm/exercise/strmatch/BMStrMatch.java
new file mode 100644
index 0000000..454aeba
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/exercise/strmatch/BMStrMatch.java
@@ -0,0 +1,29 @@
+package com.chen.algorithm.exercise.strmatch;
+
+/**
+ * 字符匹配算法
+ *
+ * @author : chen weijie
+ * @Date: 2020-05-01 15:23
+ */
+public class BMStrMatch {
+
+ public int bm(char[] a, int n, char[] b, int m) {
+ int[] bc = new int[b.length]; // 记录模式串中每个字符最后出现的位置
+// generateBC(b, m, bc); // 构建坏字符哈希表
+ int i = 0; // i表示主串与模式串对齐的第一个字符
+ while (i <= n - m) {
+ int j;
+ for (j = m - 1; j >= 0; --j) { // 模式串从后往前匹配
+ if (a[i + j] != b[j]) break; // 坏字符对应模式串中的下标是j
+ }
+ if (j < 0) {
+ return i; // 匹配成功,返回主串与模式串第一个匹配的字符的位置
+ }
+ // 这里等同于将模式串往后滑动j-bc[(int)a[i+j]]位
+ i = i + (j - bc[(int) a[i + j]]);
+ }
+ return -1;
+ }
+
+}
diff --git a/src/main/java/com/chen/algorithm/exercise/tree/RedBlackTree.java b/src/main/java/com/chen/algorithm/exercise/tree/RedBlackTree.java
new file mode 100644
index 0000000..aac4d0c
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/exercise/tree/RedBlackTree.java
@@ -0,0 +1,19 @@
+package com.chen.algorithm.exercise.tree;
+
+/**
+ *
+ *
+ * 我们学习数据结构和算法,要学习它的由来、特性、适用的场景以及它能解决的问题
+ *
+ * 红黑树是一种平衡二叉查找树。它是为了解决普通二叉查找树在数据更新的过程中,复杂度退化的问题而产生的。红黑树的高度近似log2n,
+ * 所以它是近似平衡,插入、删除、查找操作的时间复杂度都是O(logn)。
+ *
+ * @author : chen weijie
+ * @Date: 2020-04-18 21:12
+ */
+public class RedBlackTree {
+
+
+
+
+}
diff --git a/src/main/java/com/chen/algorithm/exercise/tree/Trie.java b/src/main/java/com/chen/algorithm/exercise/tree/Trie.java
new file mode 100644
index 0000000..a6368db
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/exercise/tree/Trie.java
@@ -0,0 +1,53 @@
+package com.chen.algorithm.exercise.tree;
+
+/**
+ * @author : chen weijie
+ * @Date: 2020-05-01 15:36
+ */
+public class Trie {
+
+
+// 当我们在Trie树中查找字符串的时候,我们就可以通过字符的ASCII码减去“a”的ASCII码,迅速找到匹配的子节点的指针。
+// 比如,d的ASCII码减去a的ASCII码就是3,那子节点d的指针就存储在数组中下标为3的位置中。
+
+ private TrieNode root = new TrieNode('/'); // 存储无意义字符
+
+ // 往Trie树中插入一个字符串
+ public void insert(char[] text) {
+ TrieNode p = root;
+ for (int i = 0; i < text.length; ++i) {
+ int index = text[i] - 'a';
+ if (p.children[index] == null) {
+ TrieNode newNode = new TrieNode(text[i]);
+ p.children[index] = newNode;
+ }
+ p = p.children[index];
+ }
+ p.isEndingChar = true;
+ }
+
+ // 在Trie树中查找一个字符串
+ public boolean find(char[] pattern) {
+ TrieNode p = root;
+ for (int i = 0; i < pattern.length; ++i) {
+ int index = pattern[i] - 'a';
+ if (p.children[index] == null) {
+ return false; // 不存在pattern
+ }
+ p = p.children[index];
+ }
+ if (p.isEndingChar == false) return false; // 不能完全匹配,只是前缀
+ else return true; // 找到pattern
+ }
+
+ public class TrieNode {
+ public char data;
+ public TrieNode[] children = new TrieNode[26];
+ public boolean isEndingChar = false;
+
+ public TrieNode(char data) {
+ this.data = data;
+ }
+ }
+
+}
diff --git a/src/main/java/com/chen/algorithm/exercise/tree/binarysearchTree/BinarySearchTree.java b/src/main/java/com/chen/algorithm/exercise/tree/binarysearchTree/BinarySearchTree.java
new file mode 100644
index 0000000..f9c5308
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/exercise/tree/binarysearchTree/BinarySearchTree.java
@@ -0,0 +1,142 @@
+package com.chen.algorithm.exercise.tree.binarysearchTree;
+
+/**
+ * @author : chen weijie
+ * @Date: 2020-04-18 19:35
+ */
+public class BinarySearchTree {
+
+ Node tree;
+
+ /**
+ * 二叉树查找操作
+ *
+ * @param data
+ * @return
+ */
+ public Node serach(int data) {
+
+ Node p = tree;
+ while (p != null) {
+ if (data > p.data) {
+ p = p.right;
+ } else if (data < p.data) {
+ p = p.left;
+ } else {
+ return p;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * 二叉树的插入操作
+ *
+ * @param data
+ */
+ public void insert(int data) {
+ if (tree == null) {
+ tree = new Node(data);
+ return;
+ }
+
+ Node p = tree;
+ while (p != null) {
+ if (data > p.data) {
+ if (p.right == null) {
+ p.right = new Node(data);
+ return;
+ }
+ p = p.right;
+ } else { // data < p.data
+ if (p.left == null) {
+ p.left = new Node(data);
+ return;
+ }
+ p = p.left;
+ }
+ }
+ }
+
+
+ /**
+ * 二叉查找树的查找、插入操作都比较简单易懂,但是它的删除操作就比较复杂了 。针对要删除节点的子节点个数的不同,我们需要分三种情况来处理。
+ *
+ * 第一种情况是,如果要删除的节点没有子节点,我们只需要直接将父节点中,指向要删除节点的指针置为null。比如图中的删除节点55。
+ *
+ * 第二种情况是,如果要删除的节点只有一个子节点(只有左子节点或者右子节点),我们只需要更新父节点中,指向要删除节点的指针,让它指向要删除节点的子节点就可以了。比如图中的删除节点13。
+ *
+ * 第三种情况是,如果要删除的节点有两个子节点,这就比较复杂了。我们需要找到这个节点的右子树中的最小节点,把它替换到要删除的节点上。然后再删除掉这个最小节点,
+ * 因为最小节点肯定没有左子节点(如果有左子结点,那就不是最小节点了),所以,我们可以应用上面两条规则来删除这个最小节点。比如图中的删除节点18。
+ * @param data
+ */
+ public void delete (int data){
+
+ Node p = tree; // p指向要删除的节点,初始化指向根节点
+ Node pp = null; // pp记录的是p的父节点
+ while (p != null && p.data != data) {
+ pp = p;
+ if (data > p.data) {
+ p = p.right;
+ } else {
+ p = p.left;
+ }
+ }
+ if (p == null) {
+ return; // 没有找到
+ }
+
+ // 要删除的节点有两个子节点
+ if (p.left != null && p.right != null) { // 查找右子树中最小节点
+ Node minP = p.right;
+ Node minPP = p; // minPP表示minP的父节点
+ while (minP.left != null) {
+ minPP = minP;
+ minP = minP.left;
+ }
+ p.data = minP.data; // 将minP的数据替换到p中
+ p = minP; // 下面就变成了删除minP了
+ pp = minPP;
+ }
+
+ // 删除节点是叶子节点或者仅有一个子节点
+ Node child; // p的子节点
+ if (p.left != null) {
+ child = p.left;
+ } else if (p.right != null) {
+ child = p.right;
+ } else {
+ child = null;
+ }
+
+ if (pp == null) {
+ tree = child; // 删除的是根节点
+ } else if (pp.left == p) {
+ pp.left = child;
+ } else {
+ pp.right = child;
+ }
+
+
+ }
+
+
+
+
+ private static class Node {
+
+ private Integer data;
+
+ private Node left;
+
+ private Node right;
+
+ public Node(int data) {
+ this.data = data;
+ }
+
+
+ }
+
+
+}
diff --git a/src/main/java/com/chen/algorithm/exercise/tree/traverseTree/InorderTraversal.java b/src/main/java/com/chen/algorithm/exercise/tree/traverseTree/InorderTraversal.java
new file mode 100644
index 0000000..226022d
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/exercise/tree/traverseTree/InorderTraversal.java
@@ -0,0 +1,113 @@
+package com.chen.algorithm.exercise.tree.traverseTree;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Stack;
+
+/**
+ * https://leetcode-cn.com/problems/binary-tree-inorder-traversal/ 94
+ * 中序遍历
+ *
+ *
+ * https://leetcode-cn.com/problems/binary-tree-preorder-traversal/solution/leetcodesuan-fa-xiu-lian-dong-hua-yan-shi-xbian-2/
+ *
+ * @author : chen weijie
+ * @Date: 2020-04-29 23:31
+ */
+public class InorderTraversal {
+
+
+ static class TreeNode {
+
+ int val;
+ TreeNode left;
+ TreeNode right;
+
+ TreeNode(int x) {
+ val = x;
+ }
+ }
+
+
+ public List inorderTraversal(TreeNode root) {
+ List list = new ArrayList<>();
+ inOrder(list, root);
+ return list;
+ }
+
+
+ public void inOrder(List result, TreeNode node) {
+ if (node == null) {
+ return;
+ }
+ inOrder(result, node.left);
+ result.add(node.val);
+ inOrder(result, node.right);
+ }
+
+
+
+
+ public static void inOrderIteration(TreeNode head, List list) {
+ if (head == null) {
+ return;
+ }
+ TreeNode cur = head;
+ Stack stack = new Stack<>();
+ while (!stack.isEmpty() || cur != null) {
+ while (cur != null) {
+ stack.push(cur);
+ cur = cur.left;
+ }
+ TreeNode node = stack.pop();
+ list.add(node.val);
+ if (node.right != null) {
+ cur = node.right;
+ }
+ }
+ }
+
+
+
+
+
+ public static void inOrderIteration2(TreeNode head, List list) {
+
+ if (head == null ){
+ return;
+ }
+ Stack stack = new Stack<>();
+ stack.push(head);
+ TreeNode current = head;
+
+ while (!stack.isEmpty() || current != null) {
+ while (current != null) {
+ stack.push(current);
+ current = current.left;
+ }
+ current = stack.pop();
+ list.add(current.val);
+ current = current.right;
+ }
+ }
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+}
diff --git a/src/main/java/com/chen/algorithm/exercise/tree/traverseTree/LevelTraverseTree.java b/src/main/java/com/chen/algorithm/exercise/tree/traverseTree/LevelTraverseTree.java
new file mode 100644
index 0000000..b0fb0f1
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/exercise/tree/traverseTree/LevelTraverseTree.java
@@ -0,0 +1,106 @@
+package com.chen.algorithm.exercise.tree.traverseTree;
+
+import java.util.ArrayList;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Queue;
+
+/**
+ * https://leetcode-cn.com/problems/binary-tree-level-order-traversal/solution/er-cha-shu-de-ceng-ci-bian-li-by-leetcode/
+ * 层序遍历
+ *
+ * @author : chen weijie
+ * @Date: 2020-04-29 23:31
+ */
+public class LevelTraverseTree {
+
+
+ static class TreeNode {
+
+ int val;
+ TreeNode left;
+ TreeNode right;
+
+ TreeNode(int x) {
+ val = x;
+ }
+ }
+
+
+ List> levels = new ArrayList<>();
+
+
+ public List> levelOrder(TreeNode TreeNode) {
+ if (TreeNode == null) {
+ return levels;
+ }
+ helper(TreeNode, 0);
+ return levels;
+ }
+
+
+ /**
+ * 递归实现
+ * @param TreeNode
+ * @param level
+ */
+ public void helper(TreeNode TreeNode, Integer level) {
+ // start the current level
+ if (levels.size() == level) {
+ levels.add(new ArrayList<>());
+ }
+ // fulfil the current level
+ levels.get(level).add(TreeNode.val);
+ // process child nodes for the next level
+ if (TreeNode.left != null) {
+ helper(TreeNode.left, level + 1);
+ }
+ if (TreeNode.right != null) {
+ helper(TreeNode.right, level + 1);
+ }
+ }
+
+ /**
+ * 迭代实现
+ *
+ * @param root
+ * @return
+ */
+ public List> levelOrder2(TreeNode root) {
+ List> levels = new ArrayList<>();
+ if (root == null) {
+ return levels;
+ }
+
+ Queue queue = new LinkedList<>();
+ queue.add(root);
+ int level = 0;
+ while (!queue.isEmpty()) {
+ // start the current level
+ levels.add(new ArrayList<>());
+
+ // number of elements in the current level
+ int level_length = queue.size();
+ for (int i = 0; i < level_length; ++i) {
+ TreeNode TreeNode = queue.poll();
+
+ // fulfill the current level
+ levels.get(level).add(TreeNode.val);
+
+ // add child nodes of the current level
+ // in the queue for the next level
+ if (TreeNode.left != null) {
+ queue.add(TreeNode.left);
+ }
+ if (TreeNode.right != null) {
+ queue.add(TreeNode.right);
+ }
+ }
+ // go to next level
+ level++;
+ }
+ return levels;
+
+ }
+
+}
diff --git a/src/main/java/com/chen/algorithm/exercise/tree/traverseTree/PostorderTraversal.java b/src/main/java/com/chen/algorithm/exercise/tree/traverseTree/PostorderTraversal.java
new file mode 100644
index 0000000..dc2aa0f
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/exercise/tree/traverseTree/PostorderTraversal.java
@@ -0,0 +1,101 @@
+package com.chen.algorithm.exercise.tree.traverseTree;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Stack;
+
+/**
+ * https://leetcode-cn.com/problems/binary-tree-postorder-traversal/ 145
+ * 后续遍历
+ *
+ *
+ * https://leetcode-cn.com/problems/binary-tree-preorder-traversal/solution/leetcodesuan-fa-xiu-lian-dong-hua-yan-shi-xbian-2/
+ *
+ * @author : chen weijie
+ * @Date: 2020-04-29 23:31
+ */
+public class PostorderTraversal {
+
+
+ static class TreeNode {
+
+ int val;
+ TreeNode left;
+ TreeNode right;
+
+ TreeNode(int x) {
+ val = x;
+ }
+ }
+
+
+ public List postorderTraversal(TreeNode root) {
+ List list = new ArrayList<>();
+ postOrder(list, root);
+ return list;
+ }
+
+
+ public void postOrder(List result, TreeNode node) {
+ if (node == null) {
+ return;
+ }
+ postOrder(result, node.left);
+ postOrder(result, node.right);
+ result.add(node.val);
+ }
+
+ public static void postOrderIteration(TreeNode head, List list) {
+ if (head == null) {
+ return;
+ }
+ Stack stack1 = new Stack<>();
+ Stack stack2 = new Stack<>();
+ stack1.push(head);
+ while (!stack1.isEmpty()) {
+ TreeNode node = stack1.pop();
+ stack2.push(node);
+ if (node.left != null) {
+ stack1.push(node.left);
+ }
+ if (node.right != null) {
+ stack1.push(node.right);
+ }
+ }
+ while (!stack2.isEmpty()) {
+ list.add(stack2.pop().val);
+ }
+ }
+
+
+ public static void postOrderIteration2(TreeNode head, List list) {
+
+
+ if (head == null) {
+ return;
+ }
+
+ Stack stack1 = new Stack<>();
+ Stack stack2 = new Stack<>();
+ stack1.push(head);
+
+ while (!stack1.isEmpty()) {
+ TreeNode node = stack1.pop();
+ stack2.push(node);
+
+ if (node.left != null) {
+ stack1.push(node.left);
+ }
+
+ if (node.right != null) {
+ stack1.push(node.right);
+ }
+ }
+
+ while (!stack2.isEmpty()){
+ list.add(stack2.pop().val);
+ }
+ }
+
+
+}
diff --git a/src/main/java/com/chen/algorithm/exercise/tree/traverseTree/PreTraverseTree.java b/src/main/java/com/chen/algorithm/exercise/tree/traverseTree/PreTraverseTree.java
new file mode 100644
index 0000000..60aeb9d
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/exercise/tree/traverseTree/PreTraverseTree.java
@@ -0,0 +1,78 @@
+package com.chen.algorithm.exercise.tree.traverseTree;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Stack;
+
+/**
+ * https://leetcode-cn.com/problems/binary-tree-preorder-traversal/ 144
+ * 先序遍历
+ *
+ *
+ * https://leetcode-cn.com/problems/binary-tree-preorder-traversal/solution/leetcodesuan-fa-xiu-lian-dong-hua-yan-shi-xbian-2/
+ *
+ * @author : chen weijie
+ * @Date: 2020-04-29 23:31
+ */
+public class PreTraverseTree {
+
+
+ static class TreeNode {
+
+ int val;
+ TreeNode left;
+ TreeNode right;
+
+ TreeNode(int x) {
+ val = x;
+ }
+ }
+
+
+ public List preorderTraversal(TreeNode root) {
+ List list = new ArrayList<>();
+// preOrder(list, root);
+ preOrderIteration(root, list);
+ return list;
+ }
+
+
+ public void preOrder(List result, TreeNode node) {
+ if (node == null) {
+ return;
+ }
+ result.add(node.val);
+ preOrder(result, node.left);
+ preOrder(result, node.right);
+ }
+
+
+ /**
+ * 迭代实现
+ *
+ * @param head
+ */
+ public static void preOrderIteration(TreeNode head, List list) {
+
+ if (head == null) {
+ return;
+ }
+
+ Stack stack = new Stack<>();
+ stack.push(head);
+
+ while (!stack.isEmpty()) {
+ TreeNode node = stack.pop();
+ list.add(node.val);
+
+ if (node.right != null) {
+ stack.push(node.right);
+ }
+ if (node.left != null) {
+ stack.push(node.left);
+ }
+ }
+ }
+
+
+}
diff --git "a/src/main/java/com/chen/algorithm/exercise/tree/\344\272\214\345\217\211\346\237\245\346\211\276\346\240\221.jpg" "b/src/main/java/com/chen/algorithm/exercise/tree/\344\272\214\345\217\211\346\237\245\346\211\276\346\240\221.jpg"
new file mode 100644
index 0000000..4ba80ae
Binary files /dev/null and "b/src/main/java/com/chen/algorithm/exercise/tree/\344\272\214\345\217\211\346\237\245\346\211\276\346\240\221.jpg" differ
diff --git a/src/main/java/com/chen/algorithm/fooBarThread/ConditionFooBar.java b/src/main/java/com/chen/algorithm/fooBarThread/ConditionFooBar.java
new file mode 100644
index 0000000..451dd4d
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/fooBarThread/ConditionFooBar.java
@@ -0,0 +1,57 @@
+package com.chen.algorithm.fooBarThread;
+
+import java.util.concurrent.locks.Condition;
+import java.util.concurrent.locks.ReentrantLock;
+
+/**
+ * @author : chen weijie
+ * @Date: 2020-08-04 17:25
+ */
+public class ConditionFooBar {
+
+ private ReentrantLock lock = new ReentrantLock();
+ private Condition fooCondition = lock.newCondition();
+ private Condition barCondition = lock.newCondition();
+ private volatile boolean flag = true;
+ private int n;
+
+ public int getN() {
+ return n;
+ }
+
+ public void setN(int n) {
+ this.n = n;
+ }
+
+ public void foo(Runnable printFoo) throws InterruptedException {
+ for (int i = 0; i < n; i++) {
+ lock.lock();
+ if (flag) {
+ fooCondition.await();
+ }
+ // printFoo.run() outputs "foo". Do not change or remove this line.
+ printFoo.run();
+ barCondition.signal();
+ flag = true;
+ lock.unlock();
+ }
+ }
+
+ public void bar(Runnable printBar) throws InterruptedException {
+ for (int i = 0; i < n; i++) {
+ lock.lock();
+ if (!flag) {
+ barCondition.await();
+ }
+ // printBar.run() outputs "bar". Do not change or remove this line.
+ printBar.run();
+ fooCondition.signal();
+ flag = false;
+ lock.unlock();
+ }
+ }
+
+
+
+
+}
diff --git a/src/main/java/com/chen/algorithm/fooBarThread/ReentrantLockFooBar.java b/src/main/java/com/chen/algorithm/fooBarThread/ReentrantLockFooBar.java
new file mode 100644
index 0000000..231b2fa
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/fooBarThread/ReentrantLockFooBar.java
@@ -0,0 +1,52 @@
+package com.chen.algorithm.fooBarThread;
+
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantLock;
+
+/**
+ * @author : chen weijie
+ * @Date: 2020-08-04 16:57
+ */
+public class ReentrantLockFooBar {
+ public ReentrantLockFooBar() {
+ }
+
+ private int n;
+
+ public int getN() {
+ return n;
+ }
+
+ public void setN(int n) {
+ this.n = n;
+ }
+
+ Lock lock = new ReentrantLock(true);
+ volatile boolean permitFoo = true;
+
+ public void foo(Runnable printFoo) throws InterruptedException {
+
+ for (int i = 0; i < n; ) {
+ lock.lock();
+ if (permitFoo) {
+ printFoo.run();
+ i++;
+ permitFoo = false;
+ }
+ lock.unlock();
+ }
+ }
+
+ public void bar(Runnable printBar) throws InterruptedException {
+ for (int i = 0; i < n; ) {
+ lock.lock();
+ if (!permitFoo) {
+ printBar.run();
+ i++;
+ permitFoo = true;
+ }
+ lock.unlock();
+ }
+ }
+}
+
diff --git a/src/main/java/com/chen/algorithm/fooBarThread/SemaphoreFooBar.java b/src/main/java/com/chen/algorithm/fooBarThread/SemaphoreFooBar.java
new file mode 100644
index 0000000..6188af1
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/fooBarThread/SemaphoreFooBar.java
@@ -0,0 +1,44 @@
+package com.chen.algorithm.fooBarThread;
+
+import java.util.concurrent.Semaphore;
+
+/**
+ * @author : chen weijie
+ * @Date: 2020-08-04 17:15
+ */
+public class SemaphoreFooBar {
+
+
+ public SemaphoreFooBar(){}
+ private int n;
+
+ public int getN() {
+ return n;
+ }
+
+ public void setN(int n) {
+ this.n = n;
+ }
+
+ Semaphore foo = new Semaphore(1);
+ Semaphore bar = new Semaphore(0);
+
+ public void foo(Runnable printFoo) throws InterruptedException {
+
+ for (int i = 0; i < n; i++) {
+ foo.acquire();
+ printFoo.run();
+ bar.release();
+ }
+
+ }
+
+ public void bar(Runnable printBar) throws InterruptedException {
+ for (int i = 0; i < n; i++ ) {
+ bar.acquire();
+ printBar.run();
+ foo.release();
+ }
+ }
+
+}
diff --git a/src/main/java/com/chen/algorithm/fooBarThread/SynchronizedFooBar.java b/src/main/java/com/chen/algorithm/fooBarThread/SynchronizedFooBar.java
new file mode 100644
index 0000000..bc818d2
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/fooBarThread/SynchronizedFooBar.java
@@ -0,0 +1,53 @@
+package com.chen.algorithm.fooBarThread;
+
+/**
+ * @author : chen weijie
+ * @Date: 2020-08-04 17:39
+ */
+public class SynchronizedFooBar {
+
+ private int n;
+ private boolean fooTurn = true;
+ private Object lock = new Object();
+
+ public int getN() {
+ return n;
+ }
+
+ public void setN(int n) {
+ this.n = n;
+ }
+
+ public void foo(Runnable printFoo) throws InterruptedException {
+
+ for (int i = 0; i < n; i++) {
+
+ synchronized (lock) {
+ if (!fooTurn) {
+ lock.wait();
+ }
+ fooTurn = false;
+ // printFoo.run() outputs "foo". Do not change or remove this line.
+ printFoo.run();
+ lock.notifyAll();
+ }
+ }
+ }
+
+ public void bar(Runnable printBar) throws InterruptedException {
+
+ for (int i = 0; i < n; i++) {
+
+ synchronized (lock) {
+ if (fooTurn) {
+ lock.wait();
+ }
+ fooTurn = true;
+ // printBar.run() outputs "bar". Do not change or remove this line.
+ printBar.run();
+ lock.notifyAll();
+ }
+ }
+ }
+
+}
diff --git a/src/main/java/com/chen/algorithm/fooBarThread/TestCase.java b/src/main/java/com/chen/algorithm/fooBarThread/TestCase.java
new file mode 100644
index 0000000..9f00452
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/fooBarThread/TestCase.java
@@ -0,0 +1,48 @@
+package com.chen.algorithm.fooBarThread;
+
+import org.junit.Test;
+
+/**
+ * @author : chen weijie
+ * @Date: 2020-08-04 17:28
+ */
+public class TestCase {
+
+ @Test
+ public void testCase() {
+
+ SynchronizedFooBar fooBar = new SynchronizedFooBar();
+ fooBar.setN(10);
+
+ Thread t1 = new Thread(() -> {
+ try {
+ fooBar.foo(() -> System.out.println("foo"));
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ });
+
+
+ Thread t2 = new Thread(() -> {
+ try {
+ fooBar.bar(() -> System.out.println("bar"));
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ });
+
+ t1.start();
+ t2.start();
+
+ try {
+ t1.join();
+ t2.join();
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+
+
+
+ }
+
+}
diff --git a/src/main/java/com/chen/algorithm/jianzhi/test66/Solution.java b/src/main/java/com/chen/algorithm/jianzhi/test66/Solution.java
new file mode 100644
index 0000000..72a51ff
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/jianzhi/test66/Solution.java
@@ -0,0 +1,51 @@
+package com.chen.algorithm.jianzhi.test66;
+
+import org.junit.Test;
+
+import java.util.Arrays;
+
+/**
+ * 整体思路,结果集中任何一个元素 = 其左边所有元素的乘积 * 其右边所有元素的乘积。
+ * 一轮循环构建左边的乘积并保存在结果集中,
+ * 二轮循环 构建右边乘积的过程,乘以左边的乘积,并将最终结果保存
+ *
+ * @author : chen weijie
+ * @Date: 2020-09-12 19:31
+ */
+public class Solution {
+
+
+ public int[] constructArr(int[] a) {
+
+ if (a == null || a.length == 0) {
+ return new int[0];
+ }
+
+ int[] b = new int[a.length];
+ b[0] = 1;
+ int temp = 1;
+
+ for (int i = 1; i < a.length; i++) {
+ b[i] = b[i - 1] * a[i - 1];
+ }
+
+
+ for (int i = a.length - 2; i >= 0; i--) {
+ temp = a[i + 1] * temp;
+ b[i] = temp * b[i];
+ }
+
+ return b;
+ }
+
+
+ @Test
+ public void testCase() {
+ int[] a = {1, 2, 3, 4, 5};
+ int[] res = constructArr(a);
+
+ System.out.println(Arrays.toString(res));
+ }
+
+
+}
diff --git a/src/main/java/com/chen/algorithm/jianzhi/test67/Solution.java b/src/main/java/com/chen/algorithm/jianzhi/test67/Solution.java
new file mode 100644
index 0000000..ba83585
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/jianzhi/test67/Solution.java
@@ -0,0 +1,45 @@
+package com.chen.algorithm.jianzhi.test67;
+
+import org.junit.Test;
+
+/**
+ * @author : chen weijie
+ * @Date: 2020-09-12 19:02
+ */
+public class Solution {
+
+
+ public int strToInt(String str) {
+ char[] c = str.trim().toCharArray();
+ if (c.length == 0) {
+ return 0;
+ }
+ int res = 0, bndry = Integer.MAX_VALUE / 10;
+ int i = 1, sign = 1;
+ if (c[0] == '-') {
+ sign = -1;
+ } else if (c[0] != '+') {
+ i = 0;
+ }
+ for (int j = i; j < c.length; j++) {
+ if (c[j] < '0' || c[j] > '9') {
+ break;
+ }
+ if (res > bndry || res == bndry && c[j] > '7') {
+ return sign == 1 ? Integer.MAX_VALUE : Integer.MIN_VALUE;
+ }
+ res = res * 10 + (c[j] - '0');
+ }
+ return sign * res;
+
+ }
+
+
+ @Test
+ public void testCase() {
+
+ String str = "2147483646";
+ System.out.println(strToInt(str));
+ }
+
+}
diff --git a/src/main/java/com/chen/algorithm/jumpFloor/JumpFloor.java b/src/main/java/com/chen/algorithm/jumpFloor/JumpFloor.java
new file mode 100644
index 0000000..e5627db
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/jumpFloor/JumpFloor.java
@@ -0,0 +1,44 @@
+package com.chen.algorithm.jumpFloor;
+
+/**
+ * @author : chen weijie
+ * @Date: 2020-04-28 19:28
+ */
+public class JumpFloor {
+
+
+ public int solution(int num) {
+ if (num < 1) {
+ return 0;
+ }
+ if (num == 1) {
+ return 1;
+ }
+
+ if (num == 2) {
+ return 2;
+ }
+ int first = 1, second = 2, third = 0;
+ for (int i = 3; i <= num; i++) {
+ third = first + second;
+ first = second;
+ second = third;
+ }
+ return third;
+ }
+
+
+ public int solution2(int n) {
+
+ if (n == 1) {
+ return 1;
+ }
+ if (n == 2) {
+ return 2;
+ }
+ return solution2(n - 1) + solution2(n - 2);
+ }
+
+
+
+}
diff --git a/src/main/java/com/chen/algorithm/linklist/LinkList.java b/src/main/java/com/chen/algorithm/linklist/LinkList.java
new file mode 100644
index 0000000..fa30e77
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/linklist/LinkList.java
@@ -0,0 +1,48 @@
+package com.chen.algorithm.linklist;
+
+/**
+ * 链表中第k个节点
+ *
+ * 两个指针第一个指针p1先开始跑,指针p1跑到k-1个节点后,另一个节点p2开始跑,当p1跑到最后时,p2所指向的指针就是第k个节点
+ *
+ * @author : chen weijie
+ * @Date: 2020-04-28 18:46
+ */
+public class LinkList {
+
+ public static class Node {
+
+ private int value;
+
+ private Node next;
+
+ public Node(int value) {
+ this.value = value;
+ }
+ }
+
+
+ public Node solution(Node head, int k) {
+
+ Node p = head;
+ Node pre = head;
+ int tempK = k;
+ int count = 0;
+
+ while (p != null) {
+ p = p.next;
+ if (k < 1) {
+ pre = pre.next;
+ }
+ count++;
+ k--;
+ }
+
+ if (count < tempK) {
+ return null;
+ }
+ return pre;
+ }
+
+
+}
diff --git a/src/main/java/com/chen/algorithm/linklist/LinkedHashMapSample.java b/src/main/java/com/chen/algorithm/linklist/LinkedHashMapSample.java
new file mode 100644
index 0000000..7a08fe4
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/linklist/LinkedHashMapSample.java
@@ -0,0 +1,42 @@
+package com.chen.algorithm.linklist;
+
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+/**
+ * @author : chen weijie
+ * @Date: 2020-06-01 17:24
+ */
+public class LinkedHashMapSample {
+
+ public static void main(String[] args) {
+ LinkedHashMap accessOrderedMap = new LinkedHashMap(16, 0.75F, false) {
+ // 实现自定义删除策略,否则行为就和普遍 Map 没有区别
+ @Override
+ protected boolean removeEldestEntry(Map.Entry entry) {
+ return size() > 3;
+ }
+ };
+ accessOrderedMap.put("Project1", "Valhalla");
+ accessOrderedMap.put("Project2", "Panama");
+ accessOrderedMap.put("Project3", "Loom");
+ accessOrderedMap.forEach((k, v) -> {
+ System.out.println(k + ":" + v);
+ });
+ // 模拟访问
+ accessOrderedMap.get("Project1");
+ accessOrderedMap.get("Project2");
+ accessOrderedMap.get("Project1");
+ System.out.println("Iterate over should be not affected:");
+ accessOrderedMap.forEach((k, v) -> {
+ System.out.println(k + ":" + v);
+ });
+ // 触发删除
+ accessOrderedMap.put("Project4", "Mission Control");
+ System.out.println("Oldest entry should be removed:");
+ // 遍历顺序不变
+ accessOrderedMap.forEach((k, v) -> {
+ System.out.println(k + ":" + v);
+ });
+ }
+}
diff --git a/src/main/java/com/chen/algorithm/lru/CacheMap.java b/src/main/java/com/chen/algorithm/lru/CacheMap.java
new file mode 100644
index 0000000..1639636
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/lru/CacheMap.java
@@ -0,0 +1,43 @@
+package com.chen.algorithm.lru;
+
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+/**
+ * @author : chen weijie
+ * @Date: 2020-05-15 21:14
+ */
+public class CacheMap extends LinkedHashMap {
+
+ private static final int MAX_NODE_NUM = 100;
+
+ private int limit;
+
+ public CacheMap() {
+ this(MAX_NODE_NUM);
+ }
+
+ public CacheMap(int limit) {
+ super(limit, 0.75f, true);
+ this.limit = limit;
+ }
+
+ public V save(K key, V val) {
+ return put(key, val);
+ }
+
+ public V getOne(K key) {
+ return get(key);
+ }
+
+ public boolean exists(K key) {
+ return containsKey(key);
+ }
+
+
+ @Override
+ protected boolean removeEldestEntry(Map.Entry eldest) {
+ return size() > limit;
+ }
+
+}
diff --git a/src/main/java/com/chen/algorithm/lru/LRUCache.java b/src/main/java/com/chen/algorithm/lru/LRUCache.java
new file mode 100644
index 0000000..c287c46
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/lru/LRUCache.java
@@ -0,0 +1,96 @@
+package com.chen.algorithm.lru;
+
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * * LRU缓存算法的实现
+ * * https://blog.csdn.net/qq_26440803/article/details/83795122
+ *
+ * @author : chen weijie
+ * @Date: 2020-04-29 23:04
+ */
+public class LRUCache {
+
+
+ class Node {
+ private K key;
+ private V value;
+ private Node prev;
+ private Node next;
+ }
+
+
+ private int capacity = 1024;
+
+ private Map> table = new ConcurrentHashMap<>();
+
+ private Node head;
+
+ private Node tail;
+
+ public LRUCache(int capacity) {
+ this();
+ this.capacity = capacity;
+ }
+
+ public LRUCache() {
+ head = new Node<>();
+ tail = new Node<>();
+ head.next = tail;
+ head.prev = null;
+ tail.prev = head;
+ tail.next = null;
+ }
+
+ public V get(String key) {
+
+ Node node = table.get(key);
+ //如果Node不在表中,代表缓存中并没有
+ if (node == null) {
+ return null;
+ }
+ //如果存在,则需要移动Node节点到表头
+ //截断链表,node.prev -> node -> node.next ====> node.prev -> node.next
+ // node.prev <- node <- node.next ====> node.prev <- node.next
+ node.prev.next = node.next;
+ node.next.prev = node.prev;
+
+ //移动节点到表头
+ node.next = head.next;
+ head.next.prev = node;
+ node.prev = head;
+ head.next = node;
+ //存在缓存表
+ table.put(key, node);
+ return node.value;
+ }
+
+ public void put(String key, V value) {
+ Node node = table.get(key);
+ //如果Node不在表中,代表缓存中并没有
+ if (node == null) {
+ if (table.size() == capacity) {
+ //超过容量了 ,首先移除尾部的节点
+ table.remove(tail.prev.key);
+ tail.prev = tail.next;
+ tail.next = null;
+ tail = tail.prev;
+
+ }
+ node = new Node<>();
+ node.key = key;
+ node.value = value;
+ table.put(key, node);
+ }
+ //如果存在,则需要移动Node节点到表头
+ node.next = head.next;
+ head.next.prev = node;
+ node.prev = head;
+ head.next = node;
+
+
+ }
+
+
+}
diff --git a/src/main/java/com/chen/algorithm/lru/LRUCacheMap.java b/src/main/java/com/chen/algorithm/lru/LRUCacheMap.java
new file mode 100644
index 0000000..6242479
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/lru/LRUCacheMap.java
@@ -0,0 +1,33 @@
+package com.chen.algorithm.lru;
+
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+/**
+ * @author : chen weijie
+ * @Date: 2020-08-03 10:38
+ */
+public class LRUCacheMap extends LinkedHashMap {
+
+ private int limit;
+
+ public LRUCacheMap(int capcity) {
+ super(capcity, 0.75f, true);
+ this.limit = capcity;
+ }
+
+ public V getValue(K key) {
+ return super.get(key);
+ }
+
+ public void putVal(K key, V value) {
+ super.put(key, value);
+ }
+
+
+ @Override
+ protected boolean removeEldestEntry(Map.Entry oldEntry) {
+ return super.size() > limit;
+ }
+
+}
diff --git a/src/main/java/com/chen/algorithm/mergeArray/ArraySort.java b/src/main/java/com/chen/algorithm/mergeArray/ArraySort.java
index c7e7f03..2c0cac4 100644
--- a/src/main/java/com/chen/algorithm/mergeArray/ArraySort.java
+++ b/src/main/java/com/chen/algorithm/mergeArray/ArraySort.java
@@ -15,9 +15,7 @@ public static int[] mergeList(int[] a, int[] b) {
int result[];
if (checkSort(a) && checkSort(b)) {
-
result = new int[a.length + b.length];
-
//i:用于标示a数组 j:用来标示b数组 k:用来标示传入的数组
int i = 0, j = 0, k = 0;
while (i < a.length && j < b.length) {
@@ -26,7 +24,6 @@ public static int[] mergeList(int[] a, int[] b) {
} else {
result[k++] = b[j++];
}
-
}
// 后面连个while循环是用来保证两个数组比较完之后剩下的一个数组里的元素能顺利传入
diff --git a/src/main/java/com/chen/algorithm/mergeArray/MergeTowLinkList.java b/src/main/java/com/chen/algorithm/mergeArray/MergeTowLinkList.java
new file mode 100644
index 0000000..941bee4
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/mergeArray/MergeTowLinkList.java
@@ -0,0 +1,52 @@
+package com.chen.algorithm.mergeArray;
+
+
+/**
+ * 合并两个有序链表
+ *
+ * @author : chen weijie
+ * @Date: 2020-05-01 23:39
+ */
+public class MergeTowLinkList {
+
+ class ListNode {
+
+ int val;
+ ListNode next;
+
+ ListNode(int x) {
+ val = x;
+ next = null;
+ }
+ }
+
+
+ public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
+
+ ListNode preHead = new ListNode(-1);
+ ListNode prev = preHead;
+
+ while (l1 != null && l2 != null) {
+
+ if (l1.val <= l2.val) {
+ prev.next = l1;
+ l1 = l1.next;
+ } else {
+ prev.next = l2;
+ l2 = l2.next;
+ }
+ prev = prev.next;
+ }
+
+ if (l1 != null) {
+ prev.next = l1;
+ }
+
+ if (l2 != null) {
+ prev.next = l2;
+ }
+ return preHead.next;
+ }
+
+
+}
diff --git a/src/main/java/com/chen/algorithm/permutations/Permutations.java b/src/main/java/com/chen/algorithm/permutations/Permutations.java
index b653513..95d7ba5 100644
--- a/src/main/java/com/chen/algorithm/permutations/Permutations.java
+++ b/src/main/java/com/chen/algorithm/permutations/Permutations.java
@@ -13,33 +13,33 @@ public class Permutations {
//字符数组组成的所有字符串
@Test
- public void test(){
+ public void test() {
//char[] cs = {'a','b','c','d','e'};
- char[] cs = {'a','b','c'};
+ char[] cs = {'a', 'b', 'c'};
int length = cs.length;
- recursionSwap(cs,0,length);
+ recursionSwap(cs, 0, length);
}
- public void swap(char[] cs,int index1,int index2){
+ public void swap(char[] cs, int index1, int index2) {
char temp = cs[index1];
- cs[index1]=cs[index2];
- cs[index2]=temp;
+ cs[index1] = cs[index2];
+ cs[index2] = temp;
}
- public void recursionSwap(char[] cs,int start,int length){
- if(start>=length-1){
+ public void recursionSwap(char[] cs, int start, int length) {
+ if (start >= length - 1) {
print(cs);
return;
}
- for(int i=start;i= length - 1) {
+ print(arr);
+ } else {
+ //将length-n个数分别放在第n个位置
+ for (int i = n; i < length; i++) {
+ //以交换位置的方式实现
+ {
+ int temp = arr[n];
+ arr[n] = arr[i];
+ arr[i] = temp;
+ }
+ //对剩下的length-n-1个数全排列
+ solution(arr, n + 1);
+ //恢复原来的顺序,进行下一次交换
+ {
+ int temp = arr[n];
+ arr[n] = arr[i];
+ arr[i] = temp;
+ }
+ }
+ }
+ }
+
+
+ public void swap(int[] cs, int index1, int index2) {
+ int temp = cs[index1];
+ cs[index1] = cs[index2];
+ cs[index2] = temp;
+ }
+
+ public static void print(int[] cs) {
+ for (int i = 0; i < cs.length; i++) {
+ System.out.print(cs[i]);
+ }
+ System.out.println();
+ }
+
+ public static void main(String[] args) {
+ int[] arr = {1, 2, 3, 4};
+ solution(arr, 0);
+ }
+
+}
diff --git a/src/main/java/com/chen/algorithm/rectangle/RingDemo.java b/src/main/java/com/chen/algorithm/rectangle/RingDemo.java
deleted file mode 100644
index fb4c65a..0000000
--- a/src/main/java/com/chen/algorithm/rectangle/RingDemo.java
+++ /dev/null
@@ -1,99 +0,0 @@
-package com.chen.algorithm.rectangle;
-
-/**
- * User: chenweijie
- * Date: 11/6/17
- * Time: 9:52 PM
- * Description: http://blog.csdn.net/terry84fun/article/details/4807521
- */
-public class RingDemo {
- /**
- * @param n
- * 打印螺旋举矩阵
- */
- public static void setArray(int n) {
- int intA = 1;//初始化
- int[][] array = new int[n][n];
- int intB;
- if (n % 2 != 0) {
- intB = n / 2 + 1;//奇数时i循环次数
- } else
- intB = n / 2;//偶数时i循环次数
- for (int i = 0; i < intB; i++) {//从外到里循环
- //从左到右横的开始
- for (int j = i; j < n - i; j++) {
- array[i][j] = intA;
- intA++;
- }
- //从上到下纵
- for (int k = i + 1; k < n - i; k++) {
- array[k][n - i - 1] = intA;
- intA++;
- }
- //从右到左横
- for (int l = n - i - 2; l >= i; l--) {
- array[n - i - 1][l] = intA;
- intA++;
- }
- //从下到上纵
- for (int m = n - i - 2; m > i; m--) {
- array[m][i] = intA;
- intA++;
- }
- }
- //输出数组
- for (int i = 0; i < n; i++) {
- for (int j = 0; j < n; j++) {
- System.out.print(array[i][j] + " ");
- }
- System.out.println();
- }
- }
- public static void setArray(int n,int m) {
- int intA=1;
- int array[][] = new int[n][m];
- int intB;
- if (n % 2 != 0) {
- intB = n / 2 + 1;//奇数时i循环次数
- } else
- intB = n / 2;//偶数时i循环次数
- for(int i = 0;i < intB; i++){//从外到里循环
- //从左到右横的开始
- for(int j = i; j=i;l--)
- {
- array[n-i-1][l]=intA;
- intA++;
- }
- //从下到上
- for(int o=n-i-2;o>i;o--)
- {
- array[o][i]=intA;
- intA++;
- }
- }
- //输出数组
- for (int i = 0; i < n; i++) {
- for (int j = 0; j < n; j++) {
- System.out.print(array[i][j] + " ");
- }
- System.out.println();
- }
- }
- public static void main(String[] args) {
- // TODO Auto-generated method stub
- setArray(5);
-// setArray(5,6);
- }
-}
diff --git a/src/main/java/com/chen/algorithm/rectangle/Test.java b/src/main/java/com/chen/algorithm/rectangle/Test.java
new file mode 100644
index 0000000..7e850d8
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/rectangle/Test.java
@@ -0,0 +1,62 @@
+package com.chen.algorithm.rectangle;
+
+/**
+ * @author : chen weijie
+ * @Date: 2020-06-26 00:57
+ */
+public class Test {
+
+ @org.junit.Test
+ public void test() {
+ int[][] num = new int[4][4];
+ int n = 4;
+ int count = 1;
+ for (int i = 0; i < n; i++) {
+ for (int j = 0; j < n; j++) {
+ num[i][j] = count++;
+ }
+ }
+ spiralOrder(num);
+ }
+
+ public int[] spiralOrder(int[][] matrix) {
+
+ int left = 0, right = matrix[0].length, ceil = 0, floor = matrix.length;
+ int[] n = new int[right * floor];
+ int x = 0;
+
+ print(matrix, n, left, right, ceil, floor, x);
+ return n;
+ }
+
+ public void print(int[][] matrix, int[] n, int left, int right, int ceil, int floor, int x) {
+ if (left > right || ceil > floor) {
+ return;
+ }
+
+ for (int i = left; i < right; i++) {
+ n[x++] = matrix[ceil][i];
+ }
+
+ for (int j = ceil + 1; j < floor; j++) {
+ n[x++] = matrix[j][right - 1];
+ }
+
+ if (left != right) {
+ for (int k = right - 2; k >= left; k--) {
+ n[x++] = matrix[floor - 1][k];
+ }
+ }
+ if (ceil != floor) {
+ for (int z = floor - 2; z > ceil; z--) {
+ n[x++] = matrix[z][left];
+ }
+ }
+
+ left++;
+ right--;
+ ceil++;
+ floor--;
+ print(matrix, n, left, right, ceil, floor, x);
+ }
+}
diff --git a/src/main/java/com/chen/algorithm/rectangle/TestClockwiseOutput.java b/src/main/java/com/chen/algorithm/rectangle/TestClockwiseOutput.java
index 063d2fa..c0ba721 100644
--- a/src/main/java/com/chen/algorithm/rectangle/TestClockwiseOutput.java
+++ b/src/main/java/com/chen/algorithm/rectangle/TestClockwiseOutput.java
@@ -2,6 +2,8 @@
import org.junit.Test;
+import java.util.ArrayList;
+
/**
* User: chenweijie
* Date: 10/16/17
@@ -14,42 +16,50 @@ public class TestClockwiseOutput {
@Test
public void test() {
- int[][] num = new int[100][100];
- int n = 3;
+ int[][] num = new int[4][4];
+ int n = 4;
int count = 1;
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
num[i][j] = count++;
}
}
- output(num, 0, n - 1);
+ printMatrix(num);
}
- public void output(int[][] num, int start, int end) {
-
- if (start > end || end <= 0) {
- return;
- }
-
- for (int i = start; i <= end; i++) {
- System.out.println(num[start][i]);
- }
-
- for (int i = start + 1; i <= end; i++) {
- System.out.println(num[i][end]);
- }
-
- for (int i = end - 1; i >= start; i--) {
- System.out.println(num[end][i]);
+ public ArrayList printMatrix(int[][] matrix) {
+ int row = matrix.length;
+ int col = matrix[0].length;
+ if (row == 0 || col == 0) {
+ return null;
}
-
- for (int i = end - 1; i > start; i--) {
- System.out.println(num[i][start]);
+ ArrayList list = new ArrayList<>();
+ int left = 0, top = 0, bottom = row - 1, right = col - 1;
+ while (left <= right && top <= bottom) {
+ for (int i = left; i <= right; i++) {
+ list.add(matrix[top][i]);
+ }
+ for (int j = top + 1; j <= bottom; j++) {
+ list.add(matrix[j][right]);
+ }
+ if (top != bottom) {
+ for (int t = right - 1; t >= left; t--) {
+ list.add(matrix[bottom][t]);
+ }
+ }
+ if (left != right) {
+ for (int k = bottom - 1; k > top; k--) {
+ list.add(matrix[k][left]);
+ }
+ }
+ top++;
+ left++;
+ right--;
+ bottom--;
}
-
- output(num, start + 1, end - 1);
-
+ return list;
}
+
}
diff --git a/src/main/java/com/chen/algorithm/rectangle/TestSnakeCircle.java b/src/main/java/com/chen/algorithm/rectangle/TestSnakeCircle.java
deleted file mode 100644
index a07d5b0..0000000
--- a/src/main/java/com/chen/algorithm/rectangle/TestSnakeCircle.java
+++ /dev/null
@@ -1,64 +0,0 @@
-package com.chen.algorithm.rectangle;
-
-import org.junit.Test;
-
-import java.util.ArrayList;
-import java.util.Iterator;
-
-/**
- * User: chenweijie
- * Date: 11/6/17
- * Time: 9:46 PM
- * Description: http://www.cnblogs.com/flamebird/p/6840382.html
- */
-public class TestSnakeCircle {
-
- //判断N是偶数还是奇数,N为偶数时num=count,为奇数时num = count-1
- public static void getArray(int num,int count){
- ArrayList listAll = new ArrayList(count);//二维Arraylist
- if(num != count){//奇数时先构建最核心的1
- ArrayList start = new ArrayList(count);
- start.add(1);
- listAll.add(start);
- }
- for(int i=0;i numbers[j + 1]) {
-
- temp = numbers[j];
- numbers[j] = numbers[j + 1];
- numbers[j + 1] = temp;
- }
-
- }
-
- }
-
- }
-
-
-}
diff --git a/src/main/java/com/chen/algorithm/sort/BubbleSort2.java b/src/main/java/com/chen/algorithm/sort/BubbleSort2.java
deleted file mode 100644
index dd6beab..0000000
--- a/src/main/java/com/chen/algorithm/sort/BubbleSort2.java
+++ /dev/null
@@ -1,51 +0,0 @@
-package com.chen.algorithm.sort;
-
-/**
- * @author : chen weijie
- * @Date: 2019-02-26 11:29 PM
- */
-public class BubbleSort2 {
-
-
- public static int[] sort(int[] intArray) {
-
-
- if (intArray.length == 0) {
- return new int[0];
- }
- //这里for循环表示总共需要比较多少轮
- for (int i = 0; i < intArray.length; i++) {
- //这里for循环表示每轮比较参与的元素下标
- for (int j = 1; j < intArray.length; j++) {
- if (intArray[j - 1] > intArray[j]) {
- int temp;
- temp = intArray[j - 1];
- intArray[j - 1] = intArray[j];
- intArray[j] = temp;
- }
-
- }
- System.out.println("第" + i + "次排序完为:");
- display(intArray);
- }
- return intArray;
- }
-
- /// 遍历显示数组
- public static void display(int[] array) {
- for (int anArray : array) {
- System.out.print(anArray + " ");
- }
- System.out.println();
- }
-
-
- public static void main(String[] args) {
- int[] array = {3, 0, 1, 90, 2, -1, 4};
- sort(array);
- System.out.println("最后的结果为:");
- display(array);
- }
-
-
-}
diff --git a/src/main/java/com/chen/algorithm/sort/QuickSort.java b/src/main/java/com/chen/algorithm/sort/QuickSort.java
deleted file mode 100644
index f2d1807..0000000
--- a/src/main/java/com/chen/algorithm/sort/QuickSort.java
+++ /dev/null
@@ -1,57 +0,0 @@
-package com.chen.algorithm.sort;
-
-import org.junit.Test;
-
-/**
- * 快速排序
- * create by chewj1103
- */
-public class QuickSort {
-
-
- @Test
- public void quickSort() {
-
- int[] nums = {3, 7, 2, 10, -1, 4};
- quickSort(nums);
- for (int num : nums) {
- System.out.println(num);
- }
- }
-
- /**
- * 快速排序的方法入口
- *
- * @param arr 要排序的数组
- */
- public static void quickSort(int[] arr) {
- qSort(arr, 0, arr.length - 1);
- }
-
- private static void qSort(int[] arr, int low, int high) {
- if (low < high) {
- int pivot = partition(arr, low, high); //将数组分为两部分
- qSort(arr, low, pivot - 1); //递归排序左子数组
- qSort(arr, pivot + 1, high); //递归排序右子数组
- }
- }
-
- private static int partition(int[] arr, int low, int high) {
- int pivotValue = arr[low]; //枢轴记录
- while (low < high) {
- while (low < high && arr[high] >= pivotValue) {
- --high;
- }
- arr[low] = arr[high]; //交换比枢轴小的记录到左端
- while (low < high && arr[low] <= pivotValue) {
- ++low;
- }
- arr[high] = arr[low]; //交换比枢轴小的记录到右端
- }
- //扫描完成,枢轴到位
- arr[low] = pivotValue;
- //返回的是枢轴的下标
- return low;
- }
-
-}
diff --git a/src/main/java/com/chen/algorithm/sort/QuickSortTest.java b/src/main/java/com/chen/algorithm/sort/QuickSortTest.java
deleted file mode 100644
index e36d688..0000000
--- a/src/main/java/com/chen/algorithm/sort/QuickSortTest.java
+++ /dev/null
@@ -1,62 +0,0 @@
-package com.chen.algorithm.sort;
-
-import org.junit.Test;
-
-/**
- * 快速排序练习
- *
- * @author Chen Weijie
- */
-public class QuickSortTest {
-
-
- public static int partiton(int[] arr, int low, int high) {
-
- int pivotValue = arr[low]; //获取第一个元素为数轴
-
- while (low < high) {
- //从high位置往左移动,当arr[high]的元素小于数轴元素,则将arr[high]赋值给arr[low]
- while (low < high && arr[high] >= pivotValue) {
- high--;
- }
- arr[low] = arr[high];
- //从low位置往右移动,当arr[low]的元素大于数轴元素,则将arr[low]赋值给arr[high]
- while (low < high && arr[low] <= pivotValue) {
- low++;
- }
- arr[high] = arr[low];
- }
-
- arr[low] = pivotValue;//将数轴元素赋值给arr[low]
- return low;
- }
-
-
- public static void quickSort(int arr[], int low, int high) {
-
- if (low < high) {
- int pivot = partiton(arr, low, high);
- partiton(arr, pivot + 1, high);
- partiton(arr, low, pivot - 1);
- }
-
- }
-
-
- public static void quick() {
- int[] arr = {9, 2, 58, -10, 40};
- quickSort(arr, 0, arr.length - 1);
- for (int n : arr) {
- System.out.println(n);
- }
-
- }
-
-
- @Test
- public void testMain() {
- quick();
- }
-
-
-}
diff --git a/src/main/java/com/chen/algorithm/sort/Test.java b/src/main/java/com/chen/algorithm/sort/Test.java
new file mode 100644
index 0000000..8e0b3b4
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/sort/Test.java
@@ -0,0 +1,60 @@
+package com.chen.algorithm.sort;
+
+/**
+ * @author : chen weijie
+ * @Date: 2020-06-16 20:28
+ */
+public class Test {
+
+
+ public static void main(String[] args) {
+ int[] i1 = {4, 1, 2};
+ int[] i2 = {1, 3, 4, 2};
+ int[] res = nextGreaterElement(i1, i2);
+ for (int i : res) {
+ System.out.println(i);
+ }
+
+ System.out.println("Hello World!");
+ }
+
+
+ public static int[] nextGreaterElement(int[] nums1, int[] nums2) {
+
+ if (nums1 == null || nums1.length == 0) {
+ return null;
+ }
+
+
+ for (int i = 0; i < nums1.length; i++) {
+ int start = 0;
+ for (int j = 0; j < nums2.length; j++) {
+ if (nums2[j] == nums1[i]) {
+ start = j;
+ System.out.println("===" + start);
+ break;
+ }
+ }
+
+ if (start == nums2.length - 1) {
+ nums1[i] = -1;
+ continue;
+ }
+
+ for (int j = start + 1; j < nums2.length; j++) {
+
+ if (nums2[j] > nums1[i]) {
+ nums1[i] = nums2[j];
+ break;
+ } else {
+ nums1[i] = -1;
+ }
+ }
+
+ }
+
+ return nums1;
+ }
+
+
+}
diff --git a/src/main/java/com/chen/algorithm/sort/standrd/BubbleSort.java b/src/main/java/com/chen/algorithm/sort/standrd/BubbleSort.java
new file mode 100644
index 0000000..c6bc1c9
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/sort/standrd/BubbleSort.java
@@ -0,0 +1,42 @@
+package com.chen.algorithm.sort.standrd;
+
+import org.junit.Test;
+
+/**
+ * 冒泡排序算法 O(n平方)
+ * Created by Chen Weijie on 2017/8/17.
+ */
+public class BubbleSort {
+
+
+ @Test
+ public void bubbleSort1() {
+
+ int[] numbers = {1, 4, 7, 2, 10};
+
+ int length = numbers.length;
+ boolean flag = false;
+ for (int i = 0; i < length; i++) {
+ for (int j = 0; j < length - i - 1; j++) {
+ if (numbers[j] > numbers[j + 1]) {
+ int temp = numbers[j];
+ numbers[j] = numbers[j + 1];
+ numbers[j + 1] = temp;
+ flag = true;
+ }
+ }
+ if (!flag) {
+ break;
+ }
+
+ }
+
+
+ for (int i = 0; i < numbers.length; i++) {
+ System.out.println(numbers[i]);
+ }
+
+ }
+
+
+}
diff --git a/src/main/java/com/chen/algorithm/sort/ChoiceSort.java b/src/main/java/com/chen/algorithm/sort/standrd/ChoiceSort.java
similarity index 64%
rename from src/main/java/com/chen/algorithm/sort/ChoiceSort.java
rename to src/main/java/com/chen/algorithm/sort/standrd/ChoiceSort.java
index d92e9d6..41e3c91 100644
--- a/src/main/java/com/chen/algorithm/sort/ChoiceSort.java
+++ b/src/main/java/com/chen/algorithm/sort/standrd/ChoiceSort.java
@@ -1,13 +1,11 @@
-package com.chen.algorithm.sort;
+package com.chen.algorithm.sort.standrd;
/**
- *
* 选择排序是每一次从待排序的数据元素中选出最小的一个元素,存放在序列的起始位置,直到全部待排序的数据元素排完。
- 分为三步:
- ①、从待排序序列中,找到关键字最小的元素
- ②、如果最小元素不是待排序序列的第一个元素,将其和第一个元素互换
- ③、从余下的 N - 1 个元素中,找出关键字最小的元素,重复(1)、(2)步,直到排序结束
- *
+ * 分为三步:
+ * ①、从待排序序列中,找到关键字最小的元素
+ * ②、如果最小元素不是待排序序列的第一个元素,将其和第一个元素互换
+ * ③、从余下的 N - 1 个元素中,找出关键字最小的元素,重复(1)、(2)步,直到排序结束
*
* @author : chen weijie
* @Date: 2019-02-28 12:25 AM
@@ -18,7 +16,7 @@ public class ChoiceSort {
public static int[] sort(int[] array) {
//总共进行n-1轮比较
- for (int i = 0; i < array.length - 1; i++) {
+ for (int i = 0; i < array.length; i++) {
int min = i;
//每轮需要比较的次数
for (int j = i + 1; j < array.length; j++) {
@@ -57,13 +55,31 @@ public static void main(String[] args) {
System.out.println("未排序数组顺序为:");
display(array);
System.out.println("-----------------------");
- array = sort(array);
+ array = sort2(array);
System.out.println("-----------------------");
System.out.println("经过选择排序后的数组顺序为:");
display(array);
}
+ public static int[] sort2(int[] array) {
+
+ for (int i = 0; i < array.length; i++) {
+ int min = i;
+ for (int j = i+1; j 0 && temp < array[j - 1]) {
+ while (leftIndex >= 0 && temp < array[leftIndex]) {
//向后挪动
- array[j] = array[j - 1];
- j--;
+ array[leftIndex + 1] = array[leftIndex];
+ leftIndex--;
}
//存在比其小的数,插入
- array[j] = temp;
+ array[leftIndex + 1] = temp;
}
- return array;
}
//遍历显示数组
@@ -36,15 +34,30 @@ public static void display(int[] array) {
}
public static void main(String[] args) {
- int[] array = {4, 2, 8, 9, 5, 7, 6, 1, 3};
+ int[] array = {6, 8, 1, 2, 4};
//未排序数组顺序为
System.out.println("未排序数组顺序为:");
display(array);
System.out.println("-----------------------");
- array = sort(array);
+ sort2(array);
System.out.println("-----------------------");
System.out.println("经过插入排序后的数组顺序为:");
display(array);
}
+
+ public static void sort2(int[] array) {
+
+ for (int i = 1; i < array.length; i++) {
+ int left = i - 1;
+ int temp = array[i];
+ while (left >= 0 && array[left] > temp) {
+ array[left + 1] = array[left];
+ left--;
+ }
+ array[left + 1] = temp;
+ }
+
+ }
+
}
diff --git a/src/main/java/com/chen/algorithm/sort/standrd/MergeSort.java b/src/main/java/com/chen/algorithm/sort/standrd/MergeSort.java
new file mode 100644
index 0000000..b4409e6
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/sort/standrd/MergeSort.java
@@ -0,0 +1,64 @@
+package com.chen.algorithm.sort.standrd;
+
+import org.junit.Test;
+
+import java.util.Arrays;
+
+/**
+ * @author : chen weijie
+ * @Date: 2020-07-27 17:07
+ */
+public class MergeSort {
+
+
+ public void merge(int[] a, int low, int mid, int high) {
+
+ int i = low;
+ int j = mid + 1;
+ int k = 0;
+
+ int[] temp = new int[high - low + 1];
+
+ while (i <= mid && j <= high) {
+
+ if (a[i] <= a[j]) {
+ temp[k++] = a[i++];
+ } else {
+ temp[k++] = a[j++];
+ }
+ }
+
+ while (i <= mid) {
+ temp[k++] = a[i++];
+ }
+
+ while (j <= high) {
+ temp[k++] = a[j++];
+ }
+
+ for (int l = 0; l < temp.length; l++) {
+ a[low + l] = temp[l];
+ }
+ }
+
+
+ public void sort(int[] a, int low, int high) {
+
+ int mid = (high - low) / 2 + low;
+ if (low < high) {
+ sort(a, low, mid);
+ sort(a, mid + 1, high);
+ merge(a, low, mid, high);
+ }
+ System.out.println(Arrays.toString(a));
+ }
+
+ @Test
+ public void testCase() {
+ int[] a = {4, 1, 3, 10, 13, 232, -1};
+ sort(a, 0, a.length - 1);
+ System.out.println("result=" + Arrays.toString(a));
+ }
+
+
+}
diff --git a/src/main/java/com/chen/algorithm/sort/standrd/QuickSort.java b/src/main/java/com/chen/algorithm/sort/standrd/QuickSort.java
new file mode 100644
index 0000000..89a81f7
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/sort/standrd/QuickSort.java
@@ -0,0 +1,96 @@
+package com.chen.algorithm.sort.standrd;
+
+import org.junit.Test;
+
+/**
+ * 如果要排序数组中下标从 p 到 r 之间的一组数据,我们选择 p 到 r 之间的任意一个数据作为 pivot(分区点)。
+ * 我们遍历 p 到 r 之间的数据,将小于 pivot 的放到左边,将大于 pivot 的放到右边,将 pivot 放到中间。经过这一步骤之后,数组 p 到 r 之间的数据就被分成了三个部分,
+ * 前面 p 到 q-1 之间都是小于 pivot 的,中间是 pivot,后面的 q+1 到 r 之间是大于 pivot 的。
+ * 根据分治、递归的处理思想,我们可以用递归排序下标从 p 到 q-1 之间的数据和下标从 q+1 到 r 之间的数据,直到区间缩小为 1,就说明所有的数据都有序了
+ *
+ * 快速排序
+ * create by chewj1103
+ */
+public class QuickSort {
+
+
+ @Test
+ public void quickSort() {
+
+ int[] nums = {3, 7, 2, 10, -1, 4};
+ sort(0, nums.length - 1, nums);
+ for (int num : nums) {
+ System.out.println(num);
+ }
+ }
+
+
+ private static void qSort(int[] arr, int low, int high) {
+ if (low < high) {
+ //将数组分为两部分
+ int pivot = partition(arr, low, high);
+ //递归排序左子数组
+ qSort(arr, low, pivot - 1);
+ //递归排序右子数组
+ qSort(arr, pivot + 1, high);
+ }
+ }
+
+
+ private static int partition(int[] arr, int low, int high) {
+ //枢轴记录
+ int pivotValue = arr[low];
+ while (low < high) {
+ while (low < high && arr[high] >= pivotValue) {
+ --high;
+ }
+ //交换比枢轴小的记录到左端
+ arr[low] = arr[high];
+ while (low < high && arr[low] <= pivotValue) {
+ ++low;
+ }
+ //交换比枢轴小的记录到右端
+ arr[high] = arr[low];
+ }
+ //扫描完成,枢轴到位
+ arr[low] = pivotValue;
+ //返回的是枢轴的下标
+ return low;
+ }
+
+
+ public static void sort(int left, int right, int[] nums) {
+ if (left < right) {
+ int pivot = partSort(left, right, nums);
+ sort(left, pivot - 1, nums);
+ sort(pivot + 1, right, nums);
+ }
+ }
+
+
+ public static int partSort(int left, int right, int[] nums) {
+
+ int pivotValue = nums[left];
+ while (left < right) {
+ while (left < right && pivotValue <= nums[right]) {
+ right--;
+ }
+ nums[left] = nums[right];
+
+ while (left < right && pivotValue >= nums[left]) {
+ left++;
+ }
+ nums[right] = nums[left];
+
+ }
+ nums[left] = pivotValue;
+ return left;
+ }
+
+
+}
+
+
+
+
+
diff --git a/src/main/java/com/chen/algorithm/sort/study/BinInsertSort.java b/src/main/java/com/chen/algorithm/sort/study/BinInsertSort.java
new file mode 100644
index 0000000..bcf323e
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/sort/study/BinInsertSort.java
@@ -0,0 +1,48 @@
+package com.chen.algorithm.sort.study;
+
+/**
+ * @author : chen weijie
+ * @Date: 2019-11-27 00:51
+ */
+public class BinInsertSort {
+
+
+ public static int[] binInsertSort(int[] a) {
+
+ int low, mid, high;
+ int temp;
+ for (int i = 1; i < a.length; i++) {
+ temp = a[i];
+ low = 0;
+ high = i - 1;
+
+ while (low <= high) {
+ mid = (low + high) / 2;
+ if (temp < a[mid]) {
+ high = mid - 1;
+ } else {
+ low = mid + 1;
+ }
+ }
+ //将a[low]--a[i-1]的数都想后移一位
+ for (int j = i; j > low; j--) {
+ a[j] = a[j - 1];
+ }
+ //最后将a[i]插入a[low]
+ a[low] = temp;
+ }
+ return a;
+ }
+
+ public static void main(String[] args) {
+ int[] array = {6, 8, 1, 2, 4};
+ //未排序数组顺序为
+ System.out.println("未排序数组顺序为:");
+ System.out.println("-----------------------");
+ binInsertSort(array);
+ System.out.println("-----------------------");
+ System.out.println("经过插入排序后的数组顺序为:");
+ }
+
+
+}
diff --git a/src/main/java/com/chen/algorithm/sort/study/InsertSort.java b/src/main/java/com/chen/algorithm/sort/study/InsertSort.java
new file mode 100644
index 0000000..802ad94
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/sort/study/InsertSort.java
@@ -0,0 +1,31 @@
+package com.chen.algorithm.sort.study;
+
+/**
+ * @author : chen weijie
+ * @Date: 2019-11-27 00:21
+ */
+public class InsertSort {
+
+
+ public void solution(int[] array) {
+
+ int leftIndex;
+ //从下标为1的元素开始选择合适的位置插入,因为下标为0的只有一个元素,默认是有序的
+ for (int i = 1; i < array.length; i++) {
+ //记录要插入的数据
+ int temp = array[i];
+ leftIndex = i - 1;
+ //从已经排序的序列最右边的开始比较,找到比其小的数
+ while (leftIndex >= 0 && temp < array[leftIndex]) {
+ //向后挪动
+ array[leftIndex + 1] = array[leftIndex];
+ leftIndex--;
+ }
+ //存在比其小的数,插入
+ array[leftIndex + 1] = temp;
+ }
+
+ }
+
+
+}
diff --git a/src/main/java/com/chen/algorithm/sort/study/InsertSort2.java b/src/main/java/com/chen/algorithm/sort/study/InsertSort2.java
new file mode 100644
index 0000000..c712260
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/sort/study/InsertSort2.java
@@ -0,0 +1,28 @@
+package com.chen.algorithm.sort.study;
+
+/**
+ * @author Chen WeiJie
+ * @date 2020-04-02 15:09:24
+ **/
+public class InsertSort2 {
+
+
+ private void sort(int[] array) {
+
+ int leftIndex;
+
+ for (int i = 1; i < array.length - 1; i++) {
+
+ int temp = array[i];
+ leftIndex = i - 1;
+
+ while (leftIndex >= 0 && temp < array[leftIndex]) {
+ array[leftIndex + 1] = array[leftIndex];
+ leftIndex--;
+ }
+ array[leftIndex + 1] = temp;
+ }
+
+ }
+
+}
diff --git a/src/main/java/com/chen/algorithm/sort/study/MergeSortAll.java b/src/main/java/com/chen/algorithm/sort/study/MergeSortAll.java
new file mode 100644
index 0000000..0b891e4
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/sort/study/MergeSortAll.java
@@ -0,0 +1,71 @@
+package com.chen.algorithm.sort.study;
+
+import org.junit.Test;
+
+import java.util.Arrays;
+
+/**
+ * https://blog.csdn.net/jianyuerensheng/article/details/51262984
+ *
+ * @author : chen weijie
+ * @Date: 2020-07-27 16:19
+ */
+public class MergeSortAll {
+
+
+ public void merge(int[] a, int low, int high, int mid) {
+
+ int[] temp = new int[high - low + 1];
+
+ int i = low;
+ int j = mid + 1;
+ int k = 0;
+
+ while (i <= mid && j <= high) {
+
+ if (a[i] < a[j]) {
+ temp[k++] = a[i++];
+ } else {
+ temp[k++] = a[j++];
+ }
+ }
+
+ while (i <= mid) {
+ temp[k++] = a[i++];
+ }
+ while (j <= high) {
+ temp[k++] = a[j++];
+ }
+
+ for (int l = 0; l < temp.length; l++) {
+ a[l + low] = temp[l];
+ }
+
+ }
+
+ public void mergeSort(int[] a, int low, int high) {
+
+ int mid = (high + low) / 2;
+ if (high > low) {
+ // 左边
+ mergeSort(a, low, mid);
+ // 右边
+ mergeSort(a, mid + 1, high);
+ merge(a, low, high, mid);
+ System.out.println("===" + Arrays.toString(a));
+ }
+
+ }
+
+ @Test
+ public void testCase() {
+
+ int a[] = {51, 46, 20, 18, 65, 97, 82, 30, 77, 50};
+ mergeSort(a, 0, a.length - 1);
+ System.out.println("排序结果:" + Arrays.toString(a));
+
+
+ }
+
+
+}
diff --git a/src/main/java/com/chen/algorithm/recursion/MergeSort.java b/src/main/java/com/chen/algorithm/sort/study/MergeTwoArray.java
similarity index 65%
rename from src/main/java/com/chen/algorithm/recursion/MergeSort.java
rename to src/main/java/com/chen/algorithm/sort/study/MergeTwoArray.java
index 37dbd99..931e840 100644
--- a/src/main/java/com/chen/algorithm/recursion/MergeSort.java
+++ b/src/main/java/com/chen/algorithm/sort/study/MergeTwoArray.java
@@ -1,14 +1,34 @@
-package com.chen.algorithm.recursion;
+package com.chen.algorithm.sort.study;
/**
+ *
+ *
+ // 归并排序算法, A是数组,n表示数组大小
+ merge_sort(A, n) {
+ merge_sort_c(A, 0, n-1)
+ }
+
+ // 递归调用函数
+ merge_sort_c(A, p, r) {
+ // 递归终止条件
+ if p >= r then return
+
+ // 取p到r之间的中间位置q
+ q = (p+r) / 2
+ // 分治递归
+ merge_sort_c(A, p, q)
+ merge_sort_c(A, q+1, r)
+ // 将A[p...q]和A[q+1...r]合并为A[p...r]
+ merge(A[p...r], A[p...q], A[q+1...r])
+ }
* 归并排序
*
- * 归并算法的中心是归并两个已经有序的数组。归并两个有序数组A和B,就生成了第三个有序数组C。数组C包含数组A和B的所有数据项。
+ * 如果要排序一个数组,我们先把数组从中间分成前后两部分,然后对前后两部分分别排序,再将排好序的两部分合并在一起,这样整个数组就都有序了。
*
* @author : chen weijie
* @Date: 2019-03-25 11:31 PM
*/
-public class MergeSort {
+public class MergeTwoArray {
public static int[] sort(int[] a, int[] b) {
diff --git a/src/main/java/com/chen/algorithm/sort/test1/BubberSort.java b/src/main/java/com/chen/algorithm/sort/test1/BubberSort.java
new file mode 100644
index 0000000..a2e185d
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/sort/test1/BubberSort.java
@@ -0,0 +1,52 @@
+package com.chen.algorithm.sort.test1;
+
+/**
+ * @author : chen weijie
+ * @Date: 2020-07-04 18:24
+ */
+public class BubberSort {
+
+
+ public static void sort(int[] array) {
+
+ if (array == null || array.length == 0) {
+ return;
+ }
+
+ boolean flag = false;
+ for (int i = 0; i < array.length; i++) {
+ for (int j = 0; j < array.length - i - 1; j++) {
+ if (array[j + 1] < array[j]) {
+ int temp = array[j + 1];
+ array[j + 1] = array[j];
+ array[j] = temp;
+ flag = true;
+ }
+
+ if (!flag) {
+ break;
+ }
+ }
+ System.out.println("第" + i + "次排序完为:");
+ display(array);
+ }
+ }
+
+ /// 遍历显示数组
+ public static void display(int[] array) {
+ for (int anArray : array) {
+ System.out.print(anArray + " ");
+ }
+ System.out.println();
+ }
+
+
+ public static void main(String[] args) {
+ int[] array = {3, 0, 1, 90, 2, -1, 4};
+ sort(array);
+ System.out.println("最后的结果为:");
+ display(array);
+ }
+
+
+}
diff --git a/src/main/java/com/chen/algorithm/sort/test1/ChoiceSort.java b/src/main/java/com/chen/algorithm/sort/test1/ChoiceSort.java
new file mode 100644
index 0000000..e70b222
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/sort/test1/ChoiceSort.java
@@ -0,0 +1,50 @@
+package com.chen.algorithm.sort.test1;
+
+/**
+ * @author : chen weijie
+ * @Date: 2020-07-04 18:47
+ */
+public class ChoiceSort {
+
+
+ public static void sort(int[] nums) {
+
+ if (nums == null || nums.length == 0) {
+ return;
+ }
+
+ for (int i = 0; i < nums.length; i++) {
+ int min = i;
+ for (int j = i + 1; j < nums.length; j++) {
+ if (nums[min] > nums[j]) {
+ min = j;
+ }
+ }
+ if (min != i) {
+ int temp = nums[min];
+ nums[min] = nums[i];
+ nums[i] = temp;
+ }
+
+ }
+ }
+
+ /// 遍历显示数组
+ public static void display(int[] array) {
+ for (int anArray : array) {
+ System.out.print(anArray + " ");
+ }
+ System.out.println();
+ }
+
+
+ public static void main(String[] args) {
+
+ int[] array = {3, 0, 1, 90, 2, -1, 4};
+ sort(array);
+ System.out.println("最后的结果为:");
+ display(array);
+ }
+
+
+}
diff --git a/src/main/java/com/chen/algorithm/sort/test1/InsertSort.java b/src/main/java/com/chen/algorithm/sort/test1/InsertSort.java
new file mode 100644
index 0000000..2100153
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/sort/test1/InsertSort.java
@@ -0,0 +1,48 @@
+package com.chen.algorithm.sort.test1;
+
+/**
+ * @author : chen weijie
+ * @Date: 2020-07-04 18:48
+ */
+public class InsertSort {
+
+
+ public static void insertSort(int[] nums) {
+
+
+ if (nums == null || nums.length == 0) {
+ return;
+ }
+
+
+ for (int i = 1; i < nums.length; i++) {
+ int temp = nums[i];
+ int leftIndex = i - 1;
+
+ while (leftIndex >= 0 && temp < nums[leftIndex]) {
+ nums[leftIndex + 1] = nums[leftIndex];
+ leftIndex--;
+ }
+ nums[leftIndex + 1] = temp;
+ }
+ }
+
+ /// 遍历显示数组
+ public static void display(int[] array) {
+ for (int anArray : array) {
+ System.out.print(anArray + " ");
+ }
+ System.out.println();
+ }
+
+
+ public static void main(String[] args) {
+
+ int[] array = {3, 0, 1, 90, 2, -1, 4};
+ insertSort(array);
+ System.out.println("最后的结果为:");
+ display(array);
+ }
+
+
+}
diff --git a/src/main/java/com/chen/algorithm/sort/test1/MergeSort.java b/src/main/java/com/chen/algorithm/sort/test1/MergeSort.java
new file mode 100644
index 0000000..7627926
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/sort/test1/MergeSort.java
@@ -0,0 +1,54 @@
+package com.chen.algorithm.sort.test1;
+
+/**
+ * @author : chen weijie
+ * @Date: 2020-07-04 20:10
+ */
+public class MergeSort {
+
+
+ public static int[] mergeSort(int[] aArray, int[] bArray) {
+ int pointA = 0;
+ int pointB = 0;
+
+ int aLength = aArray.length;
+ int bLength = bArray.length;
+ int resultPoint = 0;
+ int[] result = new int[aLength + bLength];
+
+ while (pointA < aLength && pointB < bLength) {
+ if (aArray[pointA] > bArray[pointB]) {
+ result[resultPoint++] = bArray[pointB++];
+ } else {
+ result[resultPoint++] = aArray[pointA++];
+ }
+ }
+
+ while (pointA < aLength) {
+ result[resultPoint++] = aArray[pointA++];
+ }
+
+ while (pointB < bLength) {
+ result[resultPoint++] = bArray[pointB++];
+ }
+ return result;
+ }
+
+ public static void main(String[] args) {
+
+ int[] a = {2, 5, 7, 8, 9, 10};
+ int[] b = {1, 2, 3, 5, 6, 10, 29};
+
+
+ int[] c = mergeSort(a, b);
+
+ for (int i = 0; i < c.length - 1; i++) {
+ System.out.println(c[i]);
+ }
+ System.out.println();
+
+
+ }
+
+
+}
diff --git a/src/main/java/com/chen/algorithm/sort/test1/QuickSort.java b/src/main/java/com/chen/algorithm/sort/test1/QuickSort.java
new file mode 100644
index 0000000..c08c33c
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/sort/test1/QuickSort.java
@@ -0,0 +1,64 @@
+package com.chen.algorithm.sort.test1;
+
+/**
+ * @author : chen weijie
+ * @Date: 2020-07-04 19:36
+ */
+public class QuickSort {
+
+
+ public static void quickSort(int[] nums, int low, int high) {
+
+
+ if (nums == null || nums.length == 0) {
+ return;
+ }
+
+ if (low < high) {
+ int pivot = partSort(low, high, nums);
+ quickSort(nums, low, pivot - 1);
+ quickSort(nums, pivot + 1, high);
+ }
+ }
+
+
+ private static int partSort(int low, int high, int[] nums) {
+
+ int pivotValue = nums[low];
+
+ while (low < high) {
+ while (low < high && nums[high] > pivotValue) {
+ --high;
+ }
+ nums[low] = nums[high];
+
+ while (low < high && nums[low] < pivotValue) {
+ ++low;
+ }
+ nums[high] = nums[low];
+ }
+
+ nums[low] = pivotValue;
+ return low;
+ }
+
+
+ /// 遍历显示数组
+ public static void display(int[] array) {
+ for (int anArray : array) {
+ System.out.print(anArray + " ");
+ }
+ System.out.println();
+ }
+
+
+ public static void main(String[] args) {
+
+ int[] array = {3, 0, 1, 90, 2, -1, 4};
+ int low = 0, high = array.length - 1;
+ quickSort(array, low, high);
+ System.out.println("最后的结果为:");
+ display(array);
+ }
+
+}
diff --git a/src/main/java/com/chen/algorithm/sort/test2/BubberSort.java b/src/main/java/com/chen/algorithm/sort/test2/BubberSort.java
new file mode 100644
index 0000000..0bd2394
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/sort/test2/BubberSort.java
@@ -0,0 +1,45 @@
+package com.chen.algorithm.sort.test2;
+
+import org.junit.Test;
+
+/**
+ * @author : chen weijie
+ * @Date: 2020-07-21 10:42
+ */
+public class BubberSort {
+
+ public void sort(int[] array) {
+
+ if (array == null || array.length == 0) {
+ return;
+ }
+
+ boolean flag = false;
+ for (int i = 0; i < array.length; i++) {
+ for (int j = 0; j < array.length - i - 1; j++) {
+ if (array[j] > array[j + 1]) {
+ int temp = array[j];
+ array[j] = array[j + 1];
+ array[j + 1] = temp;
+ flag = true;
+ }
+ }
+ if (!flag) {
+ break;
+ }
+ }
+
+
+ }
+
+ @Test
+ public void testCase() {
+ int[] array = {4, 2, 1, 5, 10, -1};
+ sort(array);
+ for (int i = 0; i < array.length; i++) {
+ System.out.println(array[i]);
+ }
+ }
+
+
+}
diff --git a/src/main/java/com/chen/algorithm/sort/test2/ChoiceSort.java b/src/main/java/com/chen/algorithm/sort/test2/ChoiceSort.java
new file mode 100644
index 0000000..ee44dff
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/sort/test2/ChoiceSort.java
@@ -0,0 +1,66 @@
+package com.chen.algorithm.sort.test2;
+
+import org.junit.Test;
+
+import java.util.Arrays;
+
+/**
+ * @author : chen weijie
+ * @Date: 2020-07-21 10:58
+ */
+public class ChoiceSort {
+
+ public void sort(int[] array) {
+
+ if (array == null || array.length == 0) {
+ return;
+ }
+
+ for (int i = 0; i < array.length; i++) {
+ int min = i;
+ for (int j = i + 1; j < array.length; j++) {
+ if (array[j] < array[min]) {
+ min = j;
+ }
+ }
+
+ if (min != i) {
+ int temp = array[min];
+ array[min] = array[i];
+ array[i] = temp;
+ }
+ }
+ }
+
+ @Test
+ public void testCase() {
+ int[] array = {4, 2, 1, 5, 10, -1};
+ sort2(array);
+ System.out.println(Arrays.toString(array));
+ }
+
+
+ public void sort2(int[] nums) {
+
+
+ for (int i = 0; i < nums.length; i++) {
+ int min = i;
+ for (int j = i + 1; j < nums.length; j++) {
+ if (nums[j] < nums[min]) {
+ min = j;
+ }
+ }
+
+ if (min != i) {
+ int tem = nums[min];
+ nums[min] = nums[i];
+ nums[i] = tem;
+ }
+
+ }
+
+
+ }
+
+
+}
diff --git a/src/main/java/com/chen/algorithm/sort/test2/InsertSort.java b/src/main/java/com/chen/algorithm/sort/test2/InsertSort.java
new file mode 100644
index 0000000..d328c02
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/sort/test2/InsertSort.java
@@ -0,0 +1,59 @@
+package com.chen.algorithm.sort.test2;
+
+import org.junit.Test;
+
+import java.util.Arrays;
+
+/**
+ * @author : chen weijie
+ * @Date: 2020-07-21 11:12
+ */
+public class InsertSort {
+
+
+ public void sort(int[] array) {
+
+ if (array == null || array.length == 0) {
+ return;
+ }
+
+ for (int i = 1; i < array.length; i++) {
+ int leftIndex = i - 1;
+ int temp = array[i];
+ while (leftIndex >= 0 && temp < array[leftIndex]) {
+ array[leftIndex + 1] = array[leftIndex];
+ leftIndex--;
+ }
+ array[leftIndex + 1] = temp;
+ }
+ }
+
+
+ @Test
+ public void testCase() {
+ int[] array = {4, 2, 1, 5, 10, -1};
+ sort2(array);
+ System.out.println(Arrays.toString(array));
+ }
+
+ public void sort2(int[] nums) {
+
+
+ for (int i = 1; i < nums.length; i++) {
+
+ int leftIndex = i - 1;
+ int temp = nums[i];
+
+ while (leftIndex >= 0 && nums[leftIndex] > temp) {
+ nums[leftIndex + 1] = nums[leftIndex];
+ leftIndex--;
+ }
+ nums[leftIndex + 1] = temp;
+
+ }
+
+
+ }
+
+
+}
diff --git a/src/main/java/com/chen/algorithm/sort/test2/MergeSort.java b/src/main/java/com/chen/algorithm/sort/test2/MergeSort.java
new file mode 100644
index 0000000..b4bbfc5
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/sort/test2/MergeSort.java
@@ -0,0 +1,125 @@
+package com.chen.algorithm.sort.test2;
+
+import org.junit.Test;
+
+import java.util.Arrays;
+
+/**
+ * @author : chen weijie
+ * @Date: 2020-08-03 10:52
+ */
+public class MergeSort {
+
+
+ public void merge(int[] a,int low, int high, int mid){
+
+ int i = low, j = mid + 1, k = 0;
+ int [] temp = new int[high - low + 1];
+
+ while (i <= mid || j <= high) {
+
+ if (i <= mid && j <= high) {
+ if (a[i] < a[j]) {
+ temp[k++] = a[i++];
+ } else {
+ temp[k++] = a[j++];
+ }
+ } else if (i <= mid) {
+ temp[k++] = a[i++];
+ } else {
+ temp[k++] = a[j++];
+ }
+ }
+
+ System.arraycopy(temp, 0, a, low, temp.length);
+ }
+
+
+ public void mergeSort(int low, int high, int[] a) {
+
+ if (low < high) {
+ int mid = (high - low) / 2 + low;
+ mergeSort(low, mid, a);
+ mergeSort(mid + 1, high, a);
+ merge(a, low, high, mid);
+ }
+ }
+
+ public void merge2(int left, int right, int mid, int[] nums) {
+
+ int i = left, j = mid + 1, k = 0;
+ int[] temp = new int[right - left + 1];
+
+ while (i <= mid && j <= right) {
+ if (nums[i] < nums[j]) {
+ temp[k++] = nums[i++];
+ } else {
+ temp[k++] = nums[j++];
+ }
+ }
+
+ while (i <= mid) {
+ temp[k++] = nums[i++];
+ }
+
+ while (j <= right) {
+ temp[k++] = nums[j++];
+ }
+
+ System.arraycopy(temp, 0, nums, left, temp.length);
+ }
+
+
+ public void mergeSort2(int left, int right, int[] nums) {
+
+ if (right > left) {
+ int mid = (left + right) / 2;
+ mergeSort2(left, mid, nums);
+ mergeSort2(mid + 1, right, nums);
+ merge2(left, right, mid, nums);
+ }
+ }
+
+ @Test
+ public void testCase() {
+ int[] a = {4, 1, 3, 10, 13, 232, -1};
+ mergeSort2(0, a.length - 1, a);
+ System.out.println("result=" + Arrays.toString(a));
+ }
+
+ @Test
+ public void testCase2() {
+ int[] a = {1, 3, 4};
+ int[] b = {2, 5, 9, 10, 23,};
+ int[] res = mergeArray(a, b);
+ System.out.println("result=" + Arrays.toString(res));
+ }
+
+
+ public static int[] mergeArray(int[] aArray, int[] bArray) {
+
+ int[] res = new int[aArray.length + bArray.length];
+ int pA = 0, pB = 0;
+ int pC = 0;
+
+ while (pA < aArray.length || pB < bArray.length) {
+
+ if (pA < aArray.length && pB < bArray.length) {
+ if (aArray[pA] < bArray[pB]) {
+ res[pC++] = aArray[pA++];
+ } else {
+ res[pC++] = bArray[pB++];
+ }
+
+ } else if (pA < aArray.length) {
+ res[pC++] = aArray[pA++];
+ } else if (pB < bArray.length) {
+ res[pC++] = bArray[pB++];
+ }
+ }
+
+ return res;
+ }
+
+
+}
diff --git a/src/main/java/com/chen/algorithm/sort/test2/QuickSort.java b/src/main/java/com/chen/algorithm/sort/test2/QuickSort.java
new file mode 100644
index 0000000..60a34e0
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/sort/test2/QuickSort.java
@@ -0,0 +1,57 @@
+package com.chen.algorithm.sort.test2;
+
+import org.junit.Test;
+
+/**
+ * @author : chen weijie
+ * @Date: 2020-07-21 11:27
+ */
+public class QuickSort {
+
+
+ public void sort(int[] array) {
+ int low = 0, high = array.length - 1;
+ sort(low, high, array);
+ }
+
+
+ public void sort(int low, int high, int[] array) {
+ if (high > low) {
+ int pivot = partSort(low, high, array);
+ sort(pivot + 1, high, array);
+ sort(low, pivot - 1, array);
+ }
+ }
+
+
+ public int partSort(int low, int high, int[] array) {
+
+ int pivotValue = array[low];
+
+ while (low < high) {
+ while (low < high && array[high] > pivotValue) {
+ high--;
+ }
+ array[low] = array[high];
+
+
+ while (low < high && array[low] < pivotValue) {
+ low++;
+ }
+ array[high] = array[low];
+ }
+ array[low] = pivotValue;
+ return low;
+ }
+
+
+ @Test
+ public void testCase() {
+ int[] array = {4, 2, 1, 5, 10, -1};
+ sort(array);
+ for (int i = 0; i < array.length; i++) {
+ System.out.println(array[i]);
+ }
+ }
+
+}
diff --git a/src/main/java/com/chen/algorithm/stackForQueen/StackForQueen.java b/src/main/java/com/chen/algorithm/stackForQueen/StackForQueen.java
new file mode 100644
index 0000000..a5d4c88
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/stackForQueen/StackForQueen.java
@@ -0,0 +1,41 @@
+package com.chen.algorithm.stackForQueen;
+
+import java.util.Stack;
+
+/**
+ * @author : chen weijie
+ * @Date: 2020-04-28 18:29
+ */
+public class StackForQueen {
+
+
+ private Stack stack1 = new Stack<>();
+
+ private Stack stack2 = new Stack<>();
+
+
+ public void push(Integer value) {
+ stack1.push(value);
+ }
+
+
+ public Integer pop() {
+
+ if (stack2.isEmpty() && stack1.isEmpty()) {
+ return null;
+ }
+
+
+ if (stack2.isEmpty()) {
+ while (!stack1.isEmpty()) {
+ stack2.push(stack1.pop());
+ }
+ }
+
+ return stack2.pop();
+
+
+ }
+
+
+}
diff --git a/src/main/java/com/chen/algorithm/study/X/x.md b/src/main/java/com/chen/algorithm/study/X/x.md
new file mode 100644
index 0000000..4e1dfeb
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/study/X/x.md
@@ -0,0 +1,13 @@
+# 常用的链表操作
+- 单链表反转 206
+- 链表中环的检测
+- 两个有序的链表合并
+- 删除链表倒数第 n 个结点
+- 求链表的中间结点
+
+# 栈
+
+leetcode上关于栈的题目大家可以先做20,155,232,844,224,682,496.
+
+
+#
\ No newline at end of file
diff --git "a/src/main/java/com/chen/algorithm/study/X/\344\272\214\345\210\206\346\237\245\346\211\276.md" "b/src/main/java/com/chen/algorithm/study/X/\344\272\214\345\210\206\346\237\245\346\211\276.md"
new file mode 100644
index 0000000..1a8dc11
--- /dev/null
+++ "b/src/main/java/com/chen/algorithm/study/X/\344\272\214\345\210\206\346\237\245\346\211\276.md"
@@ -0,0 +1,52 @@
+
+
+> 假设我们有 1000 万个整数数据,每个数据占 8 个字节,如何设计数据结构和算法,快速判断某个整数是否出现在这 1000 万数据中?
+> 我们希望这个功能不要占用太多的内存空间,最多不要超过 100MB,你会怎么做呢?
+
+### 二分查找应用场景的局限性
+
+1.有序;
+2.线性结构,也就是数组存储;
+3.数据量太小,二分查找的优势体现不出来;
+4.太大也不合适,二分查找的底层需要依赖数组这种数据结构,而数组为了支持随机访问的特性
+
+### 二分查找的总结
+
+> 二分查找,它的时间复杂度是 O(logn)。
+
+> 二分查找的核心思想理解起来非常简单,有点类似分治思想。即每次都通过跟区间中的中间元素对比,将待查找的区间缩小为一半,直到找到要查找的元素,或者区间被缩小为 0。
+
+> 但是二分查找的代码实现比较容易写错。你需要着重掌握它的三个容易出错的地方:循环退出条件、mid 的取值,low 和 high 的更新。
+
+> 二分查找虽然性能比较优秀,但应用场景也比较有限。底层必须依赖数组,并且还要求数据是有序的。对于较小规模的数据查找,我们直接使用顺序遍历就可以了,
+
+> 二分查找的优势并不明显。二分查找更适合处理静态数据,也就是没有频繁的数据插入、删除操作。
+
+### 二分查找的特殊情况
+
+二分查找中有序的数组中有重复的元素
+
+假如查找的值是有重复元素,则查找重复元素的第一个元素
+````
+
+public int bsearch(int[] a, int n, int value) {
+ int low = 0;
+ int high = n - 1;
+ while (low <= high) {
+ int mid = low + ((high - low) >> 1);
+ if (a[mid] > value) {
+ high = mid - 1;
+ } else if (a[mid] < value) {
+ low = mid + 1;
+ } else {
+ if ((mid == 0) || (a[mid - 1] != value)) {
+ return mid;
+ }else{
+ else high = mid - 1;
+ }
+ }
+ }
+ return -1;
+}
+````
+
diff --git "a/src/main/java/com/chen/algorithm/study/X/\345\210\206\346\262\273\347\256\227\346\263\225.md" "b/src/main/java/com/chen/algorithm/study/X/\345\210\206\346\262\273\347\256\227\346\263\225.md"
new file mode 100644
index 0000000..92ecc2e
--- /dev/null
+++ "b/src/main/java/com/chen/algorithm/study/X/\345\210\206\346\262\273\347\256\227\346\263\225.md"
@@ -0,0 +1,27 @@
+### 含义
+
+分治算法(divide and conquer)的核心思想其实就是四个字,分而治之 ,也就是将原问题划分成n个规模较小,并且结构与原问题相似的子问题,递归地解决这些子问题,然后再合并其结果,就得到原问题的解。
+
+
+### 分治和递归的区别
+
+这个定义看起来有点类似递归的定义。关于分治和递归的区别,分治算法是一种处理问题的思想,递归是一种编程技巧。实际上,分治算法一般都比较适合用递归来实现。分治算法的递归实现中,每一层递归都会涉及这样三个操作:
+
+分解:将原问题分解成一系列子问题;
+
+解决:递归地求解各个子问题,若子问题足够小,则直接求解;
+
+合并:将子问题的结果合并成原问题。
+
+### 适合场景
+
+分治算法能解决的问题,一般需要满足下面这几个条件:
+
+原问题与分解成的小问题具有相同的模式;
+
+原问题分解成的子问题可以独立求解,子问题之间没有相关性,这一点是分治算法跟动态规划的明显区别,等我们讲到动态规划的时候,会详细对比这两种算法;
+
+具有分解终止条件,也就是说,当问题足够小时,可以直接求解;
+
+可以将子问题合并成原问题,而这个合并操作的复杂度不能太高,否则就起不到减小算法总体复杂度的效果了。
+
diff --git "a/src/main/java/com/chen/algorithm/study/X/\345\212\250\346\200\201\350\247\204\345\210\222.md" "b/src/main/java/com/chen/algorithm/study/X/\345\212\250\346\200\201\350\247\204\345\210\222.md"
new file mode 100644
index 0000000..1d11b78
--- /dev/null
+++ "b/src/main/java/com/chen/algorithm/study/X/\345\212\250\346\200\201\350\247\204\345\210\222.md"
@@ -0,0 +1,72 @@
+# 什么样的问题可以用动态规划解决
+
+## 最优子结构
+
+最优子结构指的是,问题的最优解包含子问题的最优解。反过来说就是,我们可以通过子问题的最优解,推导出问题的最优解。如果我们把最优子结构,
+对应到我们前面定义的动态规划问题模型上,那我们也可以理解为,后面阶段的状态可以通过前面阶段的状态推导出来。
+
+## 无后效性
+
+无后效性有两层含义,第一层含义是,在推导后面阶段的状态的时候,我们只关心前面阶段的状态值,不关心这个状态是怎么一步一步推导出来的。
+
+第二层含义是,某阶段状态一旦确定,就不受之后阶段的决策影响。无后效性是一个非常“宽松”的要求。只要满足前面提到的动态规划问题模型,其实基本上都会满足无后效性
+
+## 重复子问题
+
+这个概念比较好理解。前面一节,我已经多次提过。如果用一句话概括一下,那就是,不同的决策序列,到达某个相同的阶段时,可能会产生重复的状态。
+
+
+# 解决动态规划问题的一般思考过程是什么样的
+
+## 状态转移表法
+
+一般能用动态规划解决的问题,都可以使用回溯算法的暴力搜索解决。所以,当我们拿到问题的时候,我们可以先用简单的回溯算法解决,然后定义状态,每个状态表示一个节点,
+
+然后对应画出递归树。从递归树中,我们很容易可以看出来,是否存在重复子问题,以及重复子问题是如何产生的。以此来寻找规律,看是否能用动态规划解决。
+
+### 状态转移法的步骤
+我们先画出一个状态表。状态表一般都是二维的,所以你可以把它想象成二维数组。其中,每个状态包含三个变量,行、列、数组值。我们根据决策的先后过程,从前往后,根据递推关系,
+
+分阶段填充状态表中的每个状态。最后,我们将这个递推填表的过程,翻译成代码,就是动态规划代码了
+
+具体步骤:
+
+回溯算法实现-定义状态-画递归树-找重复子问题-画状态转移表-根据递推关系填表-将填表过程翻译成代码
+
+## 状态转移方程法
+
+状态转移方程法有点类似递归的解题思路。我们需要分析,某个问题如何通过子问题来递归求解,也就是所谓的最优子结构。根据最优子结构,写出递归公式,
+
+也就是所谓的状态转移方程。有了状态转移方程,代码实现就非常简单了。一般情况下,我们有两种代码实现方法,一种是递归加“备忘录”,另一种是迭代递推。
+
+
+
+# 四种算法的比较
+
+那贪心、回溯、动态规划可以归为一类,而分治单独可以作为一类,因为它跟其他三个都不大一样。
+
+前三个算法解决问题的模型,都可以抽象成我们今天讲的那个多阶段决策最优解模型,而分治算法解决的问题尽管大部分也是最优解问题,但是,大部分都不能抽象成多阶段决策模型。
+
+## 回溯算法
+
+回溯算法是个“万金油”。基本上能用的动态规划、贪心解决的问题,我们都可以用回溯算法解决。回溯算法相当于穷举搜索。穷举所有的情况,
+
+然后对比得到最优解。不过,回溯算法的时间复杂度非常高,是指数级别的,只能用来解决小规模数据的问题。对于大规模数据的问题,用回溯算法解决的执行效率就很低了。
+
+## 动态规划
+
+尽管动态规划比回溯算法高效,但是,并不是所有问题,都可以用动态规划来解决。能用动态规划解决的问题,需要满足三个特征,最优子结构、无后效性和重复子问题。
+
+在重复子问题这一点上,动态规划和分治算法的区分非常明显。分治算法要求分割成的子问题,不能有重复子问题,而动态规划正好相反,动态规划之所以高效,就是因为回溯算法实现中存在大量的重复子问题。
+
+## 贪心算法
+
+贪心算法实际上是动态规划算法的一种特殊情况。它解决问题起来更加高效,代码实现也更加简洁。不过,它可以解决的问题也更加有限。它能解决的问题需要满足三个条件,最优子结构、无后效性和贪心选择性(这里我们不怎么强调重复子问题)。
+
+其中,最优子结构、无后效性跟动态规划中的无异。“贪心选择性”的意思是,通过局部最优的选择,能产生全局的最优选择。每一个阶段,我们都选择当前看起来最优的决策,所有阶段的决策完成之后,最终由这些局部最优解构成全局最优解。
+
+
+
+
+
+
diff --git "a/src/main/java/com/chen/algorithm/study/X/\345\233\236\346\272\257\347\256\227\346\263\225.md" "b/src/main/java/com/chen/algorithm/study/X/\345\233\236\346\272\257\347\256\227\346\263\225.md"
new file mode 100644
index 0000000..a7be5a5
--- /dev/null
+++ "b/src/main/java/com/chen/algorithm/study/X/\345\233\236\346\272\257\347\256\227\346\263\225.md"
@@ -0,0 +1,18 @@
+# 回溯算法应用场景
+
+正则表达式匹配、编译原理中的语法分析
+
+数学问题都可以用回溯算法解决,比如数独、八皇后、0-1背包、图的着色、旅行商问题、全排列
+
+# 回溯算法的思想
+
+我们可以借助前面学过的贪心算法,在每次面对岔路口的时候,都做出看起来最优的选择,期望这一组选择可以使得我们的人生达到“最优”。但是,我们前面也讲过,贪心算法并不一定能得到最优解
+
+回溯的处理思想,有点类似枚举搜索。我们枚举所有的解,找到满足期望的解。为了有规律地枚举所有可能的解,避免遗漏和重复,我们把问题求解的过程分为多个阶段。每个阶段,我们都会面对一个岔路口,我们先随意选一条路走,当发现这条路走不通的时候(不符合期望的解),就回退到上一个岔路口,另选一种走法继续走。
+
+
+# 总结
+
+回溯算法的思想非常简单,大部分情况下,都是用来解决广义的搜索问题,也就是,从一组可能的解中,选择出一个满足要求的解。回溯算法非常适合用递归来实现,
+
+在实现的过程中,剪枝操作是提高回溯效率的一种技巧。利用剪枝,我们并不需要穷举搜索所有的情况,从而提高搜索效率。
\ No newline at end of file
diff --git "a/src/main/java/com/chen/algorithm/study/X/\345\233\276.md" "b/src/main/java/com/chen/algorithm/study/X/\345\233\276.md"
new file mode 100644
index 0000000..70e5bb6
--- /dev/null
+++ "b/src/main/java/com/chen/algorithm/study/X/\345\233\276.md"
@@ -0,0 +1,6 @@
+### 图
+
+今天我们学习了图这种非线性表数据结构,关于图,你需要理解这样几个概念:无向图、有向图、带权图、顶点、边、度、入度、出度。除此之外,我们还学习了图的两个主要的存储方式:邻接矩阵和邻接表。
+
+邻接矩阵存储方法的缺点是比较浪费空间,但是优点是查询效率高,而且方便矩阵运算。邻接表存储方法中每个顶点都对应一个链表,存储与其相连接的其他顶点。尽管邻接表的存储方式比较节省存储空间,但链表不方便查找,所以查询效率没有邻接矩阵存储方式高。针对这个问题,邻接表还有改进升级版,即将链表换成更加高效的动态数据结构,比如平衡二叉查找树、跳表、散列表等。
+
diff --git "a/src/main/java/com/chen/algorithm/study/X/\345\240\206.md" "b/src/main/java/com/chen/algorithm/study/X/\345\240\206.md"
new file mode 100644
index 0000000..74a818d
--- /dev/null
+++ "b/src/main/java/com/chen/algorithm/study/X/\345\240\206.md"
@@ -0,0 +1,153 @@
+# 堆的定义
+
+- 堆是一个完全二叉树;
+- 堆中每一个节点的值都必须大于等于(或小于等于)其子树中每个节点的值。
+
+
+
+# 如何实现一个堆
+
+```java
+private int[] a; // 数组,从下标1开始存储数据
+ private int n; // 堆可以存储的最大数据个数
+ private int count; // 堆中已经存储的数据个数
+
+ public Heap(int capacity) {
+ a = new int[capacity + 1];
+ n = capacity;
+ count = 0;
+ }
+
+ public void insert(int data) {
+ if (count >= n) {
+ return; // 堆满了
+ }
+ ++count;
+ a[count] = data;
+ int i = count;
+ while (i / 2 > 0 && a[i] > a[i / 2]) { // 自下往上堆化
+ swap(a, i, i / 2); // swap()函数作用:交换下标为i和i/2的两个元素
+ i = i / 2;
+ }
+ }
+
+
+ /**
+ * 我们把最后一个节点放到堆顶,然后利用同样的父子节点对比方法。对于不满足父子节点大小关系的,
+ * 互换两个节点,并且重复进行这个过程,直到父子节点之间满足大小关系为止。这就是从上往下的堆化方法
+ */
+ public void removeMax() {
+ if (count == 0) {
+ // 堆中没有数据
+ return;
+ }
+ a[1] = a[count];
+ --count;
+ heapify(a, count, 1);
+ }
+
+
+ /**
+ * 建堆
+ *
+ * @param a
+ * @param n
+ */
+ private void buildHeap(int[] a, int n) {
+ for (int i = n / 2; i >= 1; --i) {
+ heapify(a, n, i);
+ }
+ }
+
+ /**
+ * 堆排序
+ *
+ * @param a
+ * @param n
+ */
+ public static void sort(int[] a, int n) {
+ buildHeap(a, n);
+ int k = n;
+ while (k > 1) {
+ swap(a, 1, k);
+ --k;
+ heapify(a, k, 1);
+ }
+ }
+
+
+
+
+ private void heapify(int[] a, int n, int i) { // 自上往下堆化
+ while (true) {
+ int maxPos = i;
+ if (i * 2 <= n && a[i] < a[i * 2]) {
+ maxPos = i * 2;
+ }
+ if (i * 2 + 1 <= n && a[maxPos] < a[i * 2 + 1]) {
+ maxPos = i * 2 + 1;
+ }
+ if (maxPos == i) {
+ break;
+ }
+ swap(a, i, maxPos);
+ i = maxPos;
+ }
+ }
+
+
+ /**
+ *
+ * @param a
+ * @param i
+ * @param j
+ */
+ public static void swap(int[] a, int i, int j) {
+ int tem = a[i];
+ a[i] = a[j];
+ a[j] = tem;
+ }
+```
+
+
+
+### 总结1
+
+每个节点的值都大于等于(或小于等于)其子树节点的值。因此,堆被分成了两类,大顶堆和小顶堆。
+
+堆中比较重要的两个操作是插入一个数据和删除堆顶元素。这两个操作都要用到堆化。插入一个数据的时候,我们把新插入的数据放到数组的最后,然后从下往上堆化;删除堆顶数据的时候,我们把数组中的最后一个元素放到堆顶,然后从上往下堆化。这两个操作时间复杂度都是O(log n)。
+
+除此之外,我们还讲了堆的一个经典应用,堆排序。堆排序包含两个过程,建堆和排序。我们将下标从frac{n}{2}到1的节点,依次进行从上到下的堆化操作,然后就可以将数组中的数据组织成堆这种数据结构。接下来,我们迭代地将堆顶的元素放到堆的末尾,并将堆的大小减一,然后再堆化,重复这个过程,直到堆中只剩下一个元素,整个数组中的数据就都有序排列了。
+
+
+
+### 堆的应用
+
+- 优先级队列,大顶堆 O(nlogn)
+- 求Top K,维护一个小顶堆 O(nlogn)
+- 求中位数。我们需要维护两个堆,一个大顶堆,一个小顶堆。大顶堆中存储前半部分数据,小顶堆中存储后半部分数据,且小顶堆中的数据都大于大顶堆中的数据;
+
+
+
+
+
+- **假设现在我们有一个包含10亿个搜索关键词的日志文件,如何能快速获取到热门榜Top 10的搜索关键词呢?**
+
+假设我们选用散列表。我们就顺序扫描这10亿个搜索关键词。当扫描到某个关键词时,我们去散列表中查询。如果存在,我们就将对应的次数加一;如果不存在,我们就将它插入到散列表,并记录次数为1。以此类推,等遍历完这10亿个搜索关键词之后,散列表中就存储了不重复的搜索关键词以及出现的次数。
+
+然后,我们再根据前面讲的用堆求Top K的方法,建立一个大小为10的小顶堆,遍历散列表,依次取出每个搜索关键词及对应出现的次数,然后与堆顶的搜索关键词对比。如果出现次数比堆顶搜索关键词的次数多,那就删除堆顶的关键词,将这个出现次数更多的关键词加入到堆中。
+
+以此类推,当遍历完整个散列表中的搜索关键词之后,堆中的搜索关键词就是出现次数最多的Top 10搜索关键词了。
+
+
+
+### 总结2
+
+优先级队列是一种特殊的队列,优先级高的数据先出队,而不再像普通的队列那样,先进先出。实际上,堆就可以看作优先级队列,只是称谓不一样罢了。
+
+求Top K问题又可以分为针对静态数据和针对动态数据,只需要利用一个堆,就可以做到非常高效率的查询Top K的数据。
+
+求中位数实际上还有很多变形,比如求99百分位数据、90百分位数据等,处理的思路都是一样的,即利用两个堆,一个大顶堆,一个小顶堆,随着数据的动态添加,动态调整两个堆中的数据,最后大顶堆的堆顶元素就是要求的数据。
+
+
+
diff --git "a/src/main/java/com/chen/algorithm/study/X/\345\271\263\350\241\241\344\272\214\345\210\206\346\237\245\346\211\276\346\240\221.md" "b/src/main/java/com/chen/algorithm/study/X/\345\271\263\350\241\241\344\272\214\345\210\206\346\237\245\346\211\276\346\240\221.md"
new file mode 100644
index 0000000..1014cc3
--- /dev/null
+++ "b/src/main/java/com/chen/algorithm/study/X/\345\271\263\350\241\241\344\272\214\345\210\206\346\237\245\346\211\276\346\240\221.md"
@@ -0,0 +1,67 @@
+
+
+
+
+红黑树是一种平衡二叉查找树
+
+- 散列表:插入删除查找都是O(1), 是最常用的,但其缺点是不能顺序遍历以及扩容缩容的性能损耗。适用于那些不需要顺序遍历,数据更新不那么频繁的。
+
+- 跳表:插入删除查找都是O(logn), 并且能顺序遍历。缺点是空间复杂度O(n)。适用于不那么在意内存空间的,其顺序遍历和区间查找非常方便。
+
+- 红黑树:插入删除查找都是O(logn), 中序遍历即是顺序遍历,稳定。缺点是难以实现,去查找不方便。其实跳表更佳,但红黑树已经用于很多地方了
+
+
+## 红黑树
+
+- 根节点是黑色的;
+
+- 每个叶子节点都是黑色的空节点(NIL),也就是说,叶子节点不存储数据;
+
+- 任何相邻的节点都不能同时为红色,也就是说,红色节点是被黑色节点隔开的;
+
+- 每个节点,从该节点到达其可达叶子节点的所有路径,都包含相同数目的黑色节点。
+
+## 插入操作
+
+红黑树规定,插入的节点必须是红色的。而且,二叉查找树中新插入的节点都是放在叶子节点上。所以,关于插入操作的平衡调整,有这样两种特殊情况,但是也都非常好处理。
+
+- 如果插入节点的父节点是黑色的,那我们什么都不用做,它仍然满足红黑树的定义。
+
+- 如果插入的节点是根节点,那我们直接改变它的颜色,把它变成黑色就可以了。
+
+### 需要调整的
+
+1. 如果关注节点是a,它的叔叔节点d是红色
+
+- 将关注节点a的父节点b、叔叔节点d的颜色都设置成黑色;
+
+- 将关注节点a的祖父节点c的颜色设置成红色;
+
+- 关注节点变成a的祖父节点c;
+
+- 跳到CASE 2或者CASE 3。
+
+
+2. 如果关注节点是a,它的叔叔节点d是黑色,关注节点a是其父节点b的右子节点,
+
+- 关注节点变成节点a的父节点b;
+
+- 围绕新的关注节点b左旋;
+
+
+3. 如果关注节点是a,它的叔叔节点d是黑色,关注节点a是其父节点b的左子节点
+
+- 围绕关注节点a的祖父节点c右旋;
+
+- 将关注节点a的父节点b、兄弟节点c的颜色互换。
+
+- 调整结束。
+
+
+
+
+
+
+
+
+
diff --git "a/src/main/java/com/chen/algorithm/study/X/\346\216\222\345\272\2171.md" "b/src/main/java/com/chen/algorithm/study/X/\346\216\222\345\272\2171.md"
new file mode 100644
index 0000000..bfa36f3
--- /dev/null
+++ "b/src/main/java/com/chen/algorithm/study/X/\346\216\222\345\272\2171.md"
@@ -0,0 +1,45 @@
+总结:
+一、几种经典排序算法及其时间复杂度级别
+冒泡、插入、选择 O(n^2) 基于比较
+快排、归并 O(nlogn) 基于比较
+计数、基数、桶 O(n) 不基于比较
+二、如何分析一个排序算法?
+1.学习排序算法的思路?明确原理、掌握实现以及分析性能。
+2.如何分析排序算法性能?从执行效率、内存消耗以及稳定性3个方面分析排序算法的性能。
+3.执行效率:从以下3个方面来衡量
+1)最好情况、最坏情况、平均情况时间复杂度
+2)时间复杂度的系数、常数、低阶:排序的数据量比较小时考虑
+3)比较次数和交换(或移动)次数
+4.内存消耗:通过空间复杂度来衡量。针对排序算法的空间复杂度,引入原地排序的概念,原地排序算法就是指空间复杂度为O(1)的排序算法。
+5.稳定性:如果待排序的序列中存在值等的元素,经过排序之后,相等元素之间原有的先后顺序不变,就说明这个排序算法时稳定的。
+三、冒泡排序
+1.排序原理
+1)冒泡排序只会操作相邻的两个数据。
+2)对相邻两个数据进行比较,看是否满足大小关系要求,若不满足让它俩互换。
+3)一次冒泡会让至少一个元素移动到它应该在的位置,重复n次,就完成了n个数据的排序工作。
+4)优化:若某次冒泡不存在数据交换,则说明已经达到完全有序,所以终止冒泡。
+2.代码实现(见下一条留言)
+3.性能分析
+1)执行效率:最小时间复杂度、最大时间复杂度、平均时间复杂度
+最小时间复杂度:数据完全有序时,只需进行一次冒泡操作即可,时间复杂度是O(n)。
+最大时间复杂度:数据倒序排序时,需要n次冒泡操作,时间复杂度是O(n^2)。
+平均时间复杂度:通过有序度和逆序度来分析。
+什么是有序度?
+有序度是数组中具有有序关系的元素对的个数,比如[2,4,3,1,5,6]这组数据的有序度就是11,分别是[2,4][2,3][2,5][2,6][4,5][4,6][3,5][3,6][1,5][1,6][5,6]。同理,对于一个倒序数组,比如[6,5,4,3,2,1],有序度是0;对于一个完全有序的数组,比如[1,2,3,4,5,6],有序度为n*(n-1)/2,也就是15,完全有序的情况称为满有序度。
+什么是逆序度?逆序度的定义正好和有序度相反。核心公式:逆序度=满有序度-有序度。
+排序过程,就是有序度增加,逆序度减少的过程,最后达到满有序度,就说明排序完成了。
+冒泡排序包含两个操作原子,即比较和交换,每交换一次,有序度加1。不管算法如何改进,交换的次数总是确定的,即逆序度。
+对于包含n个数据的数组进行冒泡排序,平均交换次数是多少呢?最坏的情况初始有序度为0,所以要进行n*(n-1)/2交换。最好情况下,初始状态有序度是n*(n-1)/2,就不需要进行交互。我们可以取个中间值n*(n-1)/4,来表示初始有序度既不是很高也不是很低的平均情况。
+换句话说,平均情况下,需要n*(n-1)/4次交换操作,比较操作可定比交换操作多,而复杂度的上限是O(n^2),所以平均情况时间复杂度就是O(n^2)。
+以上的分析并不严格,但很实用,这就够了。
+2)空间复杂度:每次交换仅需1个临时变量,故空间复杂度为O(1),是原地排序算法。
+3)算法稳定性:如果两个值相等,就不会交换位置,故是稳定排序算法。
+四、插入排序
+1.算法原理
+首先,我们将数组中的数据分为2个区间,即已排序区间和未排序区间。初始已排序区间只有一个元素,就是数组的第一个元素。插入算法的核心思想就是取未排序区间中的元素,在已排序区间中找到合适的插入位置将其插入,并保证已排序区间中的元素一直有序。重复这个过程,直到未排序中元素为空,算法结束。
+2.代码实现(见下一条留言)
+3.性能分析
+1)时间复杂度:最好、最坏、平均情况
+如果要排序的数组已经是有序的,我们并不需要搬移任何数据。只需要遍历一遍数组即可,所以时间复杂度是O(n)。如果数组是倒序的,每次插入都相当于在数组的第一个位置插入新的数据,所以需要移动大量的数据,因此时间复杂度是O(n^2)。而在一个数组中插入一个元素的平均时间复杂都是O(n),插入排序需要n次插入,所以平均时间复杂度是O(n^2)。
+2)空间复杂度:从上面的代码可以看出,插入排序算法的运行并不需要额外的存储空间,所以空间复杂度是O(1),是原地排序算法。
+3)算法稳定性:在插入排序中,对于值相同的元素,我们可以选择将后面出现的元素,插入到前面出现的元素的后面,这样就保持原有的顺序不变,所以是稳定的。
diff --git "a/src/main/java/com/chen/algorithm/study/X/\346\216\222\345\272\2172.md" "b/src/main/java/com/chen/algorithm/study/X/\346\216\222\345\272\2172.md"
new file mode 100644
index 0000000..66b4954
--- /dev/null
+++ "b/src/main/java/com/chen/algorithm/study/X/\346\216\222\345\272\2172.md"
@@ -0,0 +1,29 @@
+三、快速排序
+1.算法原理
+快排的思想是这样的:如果要排序数组中下标从p到r之间的一组数据,我们选择p到r之间的任意一个数据作为pivot(分区点)。然后遍历p到r之间的数据,将小于pivot的放到左边,将大于pivot的放到右边,将povit放到中间。经过这一步之后,数组p到r之间的数据就分成了3部分,前面p到q-1之间都是小于povit的,中间是povit,后面的q+1到r之间是大于povit的。根据分治、递归的处理思想,我们可以用递归排序下标从p到q-1之间的数据和下标从q+1到r之间的数据,直到区间缩小为1,就说明所有的数据都有序了。
+递推公式:quick_sort(p…r) = quick_sort(p…q-1) + quick_sort(q+1, r)
+终止条件:p >= r
+2.代码实现(参见下一条留言)
+3.性能分析
+1)算法稳定性:
+因为分区过程中涉及交换操作,如果数组中有两个8,其中一个是pivot,经过分区处理后,后面的8就有可能放到了另一个8的前面,先后顺序就颠倒了,所以快速排序是不稳定的排序算法。比如数组[1,2,3,9,8,11,8],取后面的8作为pivot,那么分区后就会将后面的8与9进行交换。
+2)时间复杂度:最好、最坏、平均情况
+快排也是用递归实现的,所以时间复杂度也可以用递推公式表示。
+如果每次分区操作都能正好把数组分成大小接近相等的两个小区间,那快排的时间复杂度递推求解公式跟归并的相同。
+T(1) = C; n=1 时,只需要常量级的执行时间,所以表示为 C。
+T(n) = 2*T(n/2) + n; n>1
+所以,快排的时间复杂度也是O(nlogn)。
+如果数组中的元素原来已经有序了,比如1,3,5,6,8,若每次选择最后一个元素作为pivot,那每次分区得到的两个区间都是不均等的,需要进行大约n次的分区,才能完成整个快排过程,而每次分区我们平均要扫描大约n/2个元素,这种情况下,快排的时间复杂度就是O(n^2)。
+前面两种情况,一个是分区及其均衡,一个是分区极不均衡,它们分别对应了快排的最好情况时间复杂度和最坏情况时间复杂度。那快排的平均时间复杂度是多少呢?T(n)大部分情况下是O(nlogn),只有在极端情况下才是退化到O(n^2),而且我们也有很多方法将这个概率降低。
+3)空间复杂度:快排是一种原地排序算法,空间复杂度是O(1)
+四、归并排序与快速排序的区别
+归并和快排用的都是分治思想,递推公式和递归代码也非常相似,那它们的区别在哪里呢?
+1.归并排序,是先递归调用,再进行合并,合并的时候进行数据的交换。所以它是自下而上的排序方式。何为自下而上?就是先解决子问题,再解决父问题。
+2.快速排序,是先分区,在递归调用,分区的时候进行数据的交换。所以它是自上而下的排序方式。何为自上而下?就是先解决父问题,再解决子问题。
+五、思考
+1.O(n)时间复杂度内求无序数组中第K大元素,比如4,2,5,12,3这样一组数据,第3大元素是4。
+我们选择数组区间A[0...n-1]的最后一个元素作为pivot,对数组A[0...n-1]进行原地分区,这样数组就分成了3部分,A[0...p-1]、A[p]、A[p+1...n-1]。
+如果如果p+1=K,那A[p]就是要求解的元素;如果K>p+1,说明第K大元素出现在A[p+1...n-1]区间,我们按照上面的思路递归地在A[p+1...n-1]这个区间查找。同理,如果K= 32, 采用归并排序,归并的核心是分区(Run)
+3 找连续升或降的序列作为分区,分区最终被调整为升序后压入栈
+4 如果分区长度太小,通过二分插入排序扩充分区长度到分区最小阙值
+5 每次压入栈,都要检查栈内已存在的分区是否满足合并条件,满足则进行合并
+6 最终栈内的分区被全部合并,得到一个排序好的数组
+
+Timsort的合并算法非常巧妙:
+
+1 找出左分区最后一个元素(最大)及在右分区的位置
+2 找出右分区第一个元素(最小)及在左分区的位置
+3 仅对这两个位置之间的元素进行合并,之外的元素本身就是有序的
\ No newline at end of file
diff --git "a/src/main/java/com/chen/algorithm/study/X/\346\216\222\345\272\217\346\227\266\351\227\264\345\244\215\346\235\202\345\272\246.jpg" "b/src/main/java/com/chen/algorithm/study/X/\346\216\222\345\272\217\346\227\266\351\227\264\345\244\215\346\235\202\345\272\246.jpg"
new file mode 100644
index 0000000..810ad6d
Binary files /dev/null and "b/src/main/java/com/chen/algorithm/study/X/\346\216\222\345\272\217\346\227\266\351\227\264\345\244\215\346\235\202\345\272\246.jpg" differ
diff --git "a/src/main/java/com/chen/algorithm/study/X/\346\225\260\347\273\204.md" "b/src/main/java/com/chen/algorithm/study/X/\346\225\260\347\273\204.md"
new file mode 100644
index 0000000..93e1f66
--- /dev/null
+++ "b/src/main/java/com/chen/algorithm/study/X/\346\225\260\347\273\204.md"
@@ -0,0 +1,85 @@
+文章结构:
+数组看起来简单基础,但是很多人没有理解这个数据结构的精髓。带着为什么数组要从0开始编号,而不是从1开始的问题,进入主题。
+1. 数组如何实现随机访问
+1) 数组是一种线性数据结构,用连续的存储空间存储相同类型数据
+I) 线性表:数组、链表、队列、栈 非线性表:树 图
+II) 连续的内存空间、相同的数据,所以数组可以随机访问,但对数组进行删除插入,为了保证数组的连续性,就要做大量的数据搬移工作
+a) 数组如何实现下标随机访问。
+引入数组再内存种的分配图,得出寻址公式
+b) 纠正数组和链表的错误认识。数组的查找操作时间复杂度并不是O(1)。即便是排好的数组,用二分查找,时间复杂度也是O(logn)。
+正确表述:数组支持随机访问,根据下标随机访问的时间复杂度为O(1)
+2. 低效的插入和删除
+1) 插入:从最好O(1) 最坏O(n) 平均O(n)
+2) 插入:数组若无序,插入新的元素时,可以将第K个位置元素移动到数组末尾,把心的元素,插入到第k个位置,此处复杂度为O(1)。作者举例说明
+3) 删除:从最好O(1) 最坏O(n) 平均O(n)
+4) 多次删除集中在一起,提高删除效率
+记录下已经被删除的数据,每次的删除操作并不是搬移数据,只是记录数据已经被删除,当数组没有更多的存储空间时,再触发一次真正的删除操作。即JVM标记清除垃圾回收算法。
+3. 警惕数组的访问越界问题
+用C语言循环越界访问的例子说明访问越界的bug。此例在《C陷阱与缺陷》出现过,很惭愧,看过但是现在也只有一丢丢印象。翻了下书,替作者加上一句话:如果用来编译这段程序的编译器按照内存地址递减的方式给变量分配内存,那么内存中的i将会被置为0,则为死循环永远出不去。
+4. 容器能否完全替代数组
+相比于数字,java中的ArrayList封装了数组的很多操作,并支持动态扩容。一旦超过村塾容量,扩容时比较耗内存,因为涉及到内存申请和数据搬移。
+数组适合的场景:
+1) Java ArrayList 的使用涉及装箱拆箱,有一定的性能损耗,如果特别管柱性能,可以考虑数组
+2) 若数据大小事先已知,并且涉及的数据操作非常简单,可以使用数组
+3) 表示多维数组时,数组往往更加直观。
+4) 业务开发容器即可,底层开发,如网络框架,性能优化。选择数组。
+5. 解答开篇问题
+1) 从偏移角度理解a[0] 0为偏移量,如果从1计数,会多出K-1。增加cpu负担。为什么循环要写成for(int i = 0;i<3;i++) 而不是for(int i = 0 ;i<=2;i++)。第一个直接就可以算出3-0 = 3 有三个数据,而后者 2-0+1个数据,多出1个加法运算,很恼火。
+2) 也有一定的历史原因
+
+
+如何优雅的写出链表代码?6大学习技巧
+
+一、理解指针或引用的含义
+1.含义:将某个变量(对象)赋值给指针(引用),实际上就是就是将这个变量(对象)的地址赋值给指针(引用)。
+2.示例:
+p—>next = q; 表示p节点的后继指针存储了q节点的内存地址。
+p—>next = p—>next—>next; 表示p节点的后继指针存储了p节点的下下个节点的内存地址。
+
+二、警惕指针丢失和内存泄漏(单链表)
+1.插入节点
+在节点a和节点b之间插入节点x,b是a的下一节点,,p指针指向节点a,则造成指针丢失和内存泄漏的代码:p—>next = x;x—>next = p—>next; 显然这会导致x节点的后继指针指向自身。
+正确的写法是2句代码交换顺序,即:x—>next = p—>next; p—>next = x;
+2.删除节点
+在节点a和节点b之间删除节点b,b是a的下一节点,p指针指向节点a:p—>next = p—>next—>next;
+
+三、利用“哨兵”简化实现难度
+1.什么是“哨兵”?
+链表中的“哨兵”节点是解决边界问题的,不参与业务逻辑。如果我们引入“哨兵”节点,则不管链表是否为空,head指针都会指向这个“哨兵”节点。我们把这种有“哨兵”节点的链表称为带头链表,相反,没有“哨兵”节点的链表就称为不带头链表。
+2.未引入“哨兵”的情况
+如果在p节点后插入一个节点,只需2行代码即可搞定:
+new_node—>next = p—>next;
+p—>next = new_node;
+但,若向空链表中插入一个节点,则代码如下:
+if(head == null){
+head = new_node;
+}
+如果要删除节点p的后继节点,只需1行代码即可搞定:
+p—>next = p—>next—>next;
+但,若是删除链表的最有一个节点(链表中只剩下这个节点),则代码如下:
+if(head—>next == null){
+head = null;
+}
+从上面的情况可以看出,针对链表的插入、删除操作,需要对插入第一个节点和删除最后一个节点的情况进行特殊处理。这样代码就会显得很繁琐,所以引入“哨兵”节点来解决这个问题。
+3.引入“哨兵”的情况
+“哨兵”节点不存储数据,无论链表是否为空,head指针都会指向它,作为链表的头结点始终存在。这样,插入第一个节点和插入其他节点,删除最后一个节点和删除其他节点都可以统一为相同的代码实现逻辑了。
+4.“哨兵”还有哪些应用场景?
+这个知识有限,暂时想不出来呀!但总结起来,哨兵最大的作用就是简化边界条件的处理。
+
+四、重点留意边界条件处理
+经常用来检查链表是否正确的边界4个边界条件:
+1.如果链表为空时,代码是否能正常工作?
+2.如果链表只包含一个节点时,代码是否能正常工作?
+3.如果链表只包含两个节点时,代码是否能正常工作?
+4.代码逻辑在处理头尾节点时是否能正常工作?
+
+五、举例画图,辅助思考
+核心思想:释放脑容量,留更多的给逻辑思考,这样就会感觉到思路清晰很多。
+
+六、多写多练,没有捷径
+5个常见的链表操作:
+1.单链表反转
+2.链表中环的检测
+3.两个有序链表合并
+4.删除链表倒数第n个节点
+5.求链表的中间节点
\ No newline at end of file
diff --git "a/src/main/java/com/chen/algorithm/study/X/\346\240\210.md" "b/src/main/java/com/chen/algorithm/study/X/\346\240\210.md"
new file mode 100644
index 0000000..9c3ad69
--- /dev/null
+++ "b/src/main/java/com/chen/algorithm/study/X/\346\240\210.md"
@@ -0,0 +1,47 @@
+一、什么是栈?
+1.后进者先出,先进者后出,这就是典型的“栈”结构。
+2.从栈的操作特性来看,是一种“操作受限”的线性表,只允许在端插入和删除数据。
+二、为什么需要栈?
+1.栈是一种操作受限的数据结构,其操作特性用数组和链表均可实现。
+2.但,任何数据结构都是对特定应用场景的抽象,数组和链表虽然使用起来更加灵活,但却暴露了几乎所有的操作,难免会引发错误操作的风险。
+3.所以,当某个数据集合只涉及在某端插入和删除数据,且满足后进者先出,先进者后出的操作特性时,我们应该首选栈这种数据结构。
+三、如何实现栈?
+1.栈的API
+public class Stack- {
+//压栈
+public void push(Item item){}
+//弹栈
+public Item pop(){}
+//是否为空
+public boolean isEmpty(){}
+//栈中数据的数量
+public int size(){}
+//返回栈中最近添加的元素而不删除它
+public Item peek(){}
+}
+2.数组实现(自动扩容)
+时间复杂度分析:根据均摊复杂度的定义,可以得数组实现(自动扩容)符合大多数情况是O(1)级别复杂度,个别情况是O(n)级别复杂度,比如自动扩容时,会进行完整数据的拷贝。
+空间复杂度分析:在入栈和出栈的过程中,只需要一两个临时变量存储空间,所以O(1)级别。我们说空间复杂度的时候,是指除了原本的数据存储空间外,算法运行还需要额外的存储空间。
+实现代码:(见另一条留言)
+
+3.链表实现
+时间复杂度分析:压栈和弹栈的时间复杂度均为O(1)级别,因为只需更改单个节点的索引即可。
+空间复杂度分析:在入栈和出栈的过程中,只需要一两个临时变量存储空间,所以O(1)级别。我们说空间复杂度的时候,是指除了原本的数据存储空间外,算法运行还需要额外的存储空间。
+实现代码:(见另一条留言)
+
+四、栈的应用
+1.栈在函数调用中的应用
+操作系统给每个线程分配了一块独立的内存空间,这块内存被组织成“栈”这种结构,用来存储函数调用时的临时变量。每进入一个函数,就会将其中的临时变量作为栈帧入栈,当被调用函数执行完成,返回之后,将这个函数对应的栈帧出栈。
+2.栈在表达式求值中的应用(比如:34+13*9+44-12/3)
+利用两个栈,其中一个用来保存操作数,另一个用来保存运算符。我们从左向右遍历表达式,当遇到数字,我们就直接压入操作数栈;当遇到运算符,就与运算符栈的栈顶元素进行比较,若比运算符栈顶元素优先级高,就将当前运算符压入栈,若比运算符栈顶元素的优先级低或者相同,从运算符栈中取出栈顶运算符,从操作数栈顶取出2个操作数,然后进行计算,把计算完的结果压入操作数栈,继续比较。
+3.栈在括号匹配中的应用(比如:{}{[()]()})
+用栈保存为匹配的左括号,从左到右一次扫描字符串,当扫描到左括号时,则将其压入栈中;当扫描到右括号时,从栈顶取出一个左括号,如果能匹配上,则继续扫描剩下的字符串。如果扫描过程中,遇到不能配对的右括号,或者栈中没有数据,则说明为非法格式。
+当所有的括号都扫描完成之后,如果栈为空,则说明字符串为合法格式;否则,说明未匹配的左括号为非法格式。
+4.如何实现浏览器的前进后退功能?
+我们使用两个栈X和Y,我们把首次浏览的页面依次压如栈X,当点击后退按钮时,再依次从栈X中出栈,并将出栈的数据一次放入Y栈。当点击前进按钮时,我们依次从栈Y中取出数据,放入栈X中。当栈X中没有数据时,说明没有页面可以继续后退浏览了。当Y栈没有数据,那就说明没有页面可以点击前进浏览了。
+五、思考
+1. 我们在讲栈的应用时,讲到用函数调用栈来保存临时变量,为什么函数调用要用“栈”来保存临时变量呢?用其他数据结构不行吗?
+答:因为函数调用的执行顺序符合后进者先出,先进者后出的特点。比如函数中的局部变量的生命周期的长短是先定义的生命周期长,后定义的生命周期短;还有函数中调用函数也是这样,先开始执行的函数只有等到内部调用的其他函数执行完毕,该函数才能执行结束。
+正是由于函数调用的这些特点,根据数据结构是特定应用场景的抽象的原则,我们优先考虑栈结构。
+2.我们都知道,JVM 内存管理中有个“堆栈”的概念。栈内存用来存储局部变量和方法调用,堆内存用来存储 Java 中的对象。那 JVM 里面的“栈”跟我们这里说的“栈”是不是一回事呢?如果不是,那它为什么又叫作“栈”呢?
+答:JVM里面的栈和我们这里说的是一回事,被称为方法栈。和前面函数调用的作用是一致的,用来存储方法中的局部变量。
\ No newline at end of file
diff --git "a/src/main/java/com/chen/algorithm/study/X/\350\264\252\345\277\203\347\256\227\346\263\225.md" "b/src/main/java/com/chen/algorithm/study/X/\350\264\252\345\277\203\347\256\227\346\263\225.md"
new file mode 100644
index 0000000..702116c
--- /dev/null
+++ "b/src/main/java/com/chen/algorithm/study/X/\350\264\252\345\277\203\347\256\227\346\263\225.md"
@@ -0,0 +1,34 @@
+### 贪心算法有很多经典的应用,
+
+1. 比如霍夫曼编码(Huffman Coding)、
+
+2. Prim和Kruskal最小生成树算法、
+
+3. 还有Dijkstra单源最短路径算法。
+
+4. 最小生成树算法和最短路径算法
+
+### 例子
+
+
+假设我们有一个可以容纳100kg物品的背包,可以装各种物品。我们有以下5种豆子,每种豆子的总量和总价值都各不相同。为了让背包中所装物品的总价值最大,我们如何选择在背包中装哪些豆子?每种豆子又该装多少呢?
+
+实际上,这个问题很简单,我估计你一下子就能想出来,没错,我们只要先算一算每个物品的单价,按照单价由高到低依次来装就好了。单价从高到低排列,依次是:黑豆、绿豆、红豆、青豆、黄豆,所以,我们可以往背包里装20kg黑豆、30kg绿豆、50kg红豆。
+
+这个问题的解决思路显而易见,它本质上借助的就是贪心算法。
+
+
+### 解决问题的步骤
+
+第一步,当我们看到这类问题的时候,首先要联想到贪心算法:针对一组数据,我们定义了限制值和期望值,希望从中选出几个数据,在满足限制值的情况下,期望值最大。
+
+类比到刚刚的例子,限制值就是重量不能超过100kg,期望值就是物品的总价值。这组数据就是5种豆子。我们从中选出一部分,满足重量不超过100kg,并且总价值最大。
+
+第二步,我们尝试看下这个问题是否可以用贪心算法解决:每次选择当前情况下,在对限制值同等贡献量的情况下,对期望值贡献最大的数据。
+
+类比到刚刚的例子,我们每次都从剩下的豆子里面,选择单价最高的,也就是重量相同的情况下,对价值贡献最大的豆子。
+
+#### 最短路径问题
+
+S->(2)B->(2)D->(2)T 与 S->(1)A->(4)E->(4)T,这种前面选择会影响后面选择的问题就不能完全按照贪心算法的步骤走
+
diff --git "a/src/main/java/com/chen/algorithm/study/X/\351\200\222\345\275\222.md" "b/src/main/java/com/chen/algorithm/study/X/\351\200\222\345\275\222.md"
new file mode 100644
index 0000000..29b92c8
--- /dev/null
+++ "b/src/main/java/com/chen/algorithm/study/X/\351\200\222\345\275\222.md"
@@ -0,0 +1,40 @@
+总结
+
+一、什么是递归?
+
+1.递归是一种非常高效、简洁的编码技巧,一种应用非常广泛的算法,比如DFS深度优先搜索、前中后序二叉树遍历等都是使用递归。
+2.方法或函数调用自身的方式称为递归调用,调用称为递,返回称为归。
+3.基本上,所有的递归问题都可以用递推公式来表示,比如
+f(n) = f(n-1) + 1;
+f(n) = f(n-1) + f(n-2);
+f(n)=n*f(n-1);
+
+二、为什么使用递归?递归的优缺点?
+
+1.优点:代码的表达力很强,写起来简洁。
+2.缺点:空间复杂度高、有堆栈溢出风险、存在重复计算、过多的函数调用会耗时较多等问题。
+
+三、什么样的问题可以用递归解决呢?
+
+一个问题只要同时满足以下3个条件,就可以用递归来解决:
+1.问题的解可以分解为几个子问题的解。何为子问题?就是数据规模更小的问题。
+2.问题与子问题,除了数据规模不同,求解思路完全一样
+3.存在递归终止条件
+
+四、如何实现递归?
+
+1.递归代码编写
+写递归代码的关键就是找到如何将大问题分解为小问题的规律,并且基于此写出递推公式,然后再推敲终止条件,最后将递推公式和终止条件翻译成代码。
+2.递归代码理解
+对于递归代码,若试图想清楚整个递和归的过程,实际上是进入了一个思维误区。
+那该如何理解递归代码呢?如果一个问题A可以分解为若干个子问题B、C、D,你可以假设子问题B、C、D已经解决。而且,你只需要思考问题A与子问题B、C、D两层之间的关系即可,不需要一层层往下思考子问题与子子问题,子子问题与子子子问题之间的关系。屏蔽掉递归细节,这样子理解起来就简单多了。
+因此,理解递归代码,就把它抽象成一个递推公式,不用想一层层的调用关系,不要试图用人脑去分解递归的每个步骤。
+
+五、递归常见问题及解决方案
+
+1.警惕堆栈溢出:可以声明一个全局变量来控制递归的深度,从而避免堆栈溢出。
+2.警惕重复计算:通过某种数据结构来保存已经求解过的值,从而避免重复计算。
+
+六、如何将递归改写为非递归代码?
+
+笼统的讲,所有的递归代码都可以改写为迭代循环的非递归写法。如何做?抽象出递推公式、初始值和边界条件,然后用迭代循环实现。
\ No newline at end of file
diff --git "a/src/main/java/com/chen/algorithm/study/X/\351\223\276\350\241\250.md" "b/src/main/java/com/chen/algorithm/study/X/\351\223\276\350\241\250.md"
new file mode 100644
index 0000000..1fce3b7
--- /dev/null
+++ "b/src/main/java/com/chen/algorithm/study/X/\351\223\276\350\241\250.md"
@@ -0,0 +1,36 @@
+一、什么是链表?
+1.和数组一样,链表也是一种线性表。
+2.从内存结构来看,链表的内存结构是不连续的内存空间,是将一组零散的内存块串联起来,从而进行数据存储的数据结构。
+3.链表中的每一个内存块被称为节点Node。节点除了存储数据外,还需记录链上下一个节点的地址,即后继指针next。
+二、为什么使用链表?即链表的特点
+1.插入、删除数据效率高O(1)级别(只需更改指针指向即可),随机访问效率低O(n)级别(需要从链头至链尾进行遍历)。
+2.和数组相比,内存空间消耗更大,因为每个存储数据的节点都需要额外的空间存储后继指针。
+三、常用链表:单链表、循环链表和双向链表
+1.单链表
+1)每个节点只包含一个指针,即后继指针。
+2)单链表有两个特殊的节点,即首节点和尾节点。为什么特殊?用首节点地址表示整条链表,尾节点的后继指针指向空地址null。
+3)性能特点:插入和删除节点的时间复杂度为O(1),查找的时间复杂度为O(n)。
+2.循环链表
+1)除了尾节点的后继指针指向首节点的地址外均与单链表一致。
+2)适用于存储有循环特点的数据,比如约瑟夫问题。
+3.双向链表
+1)节点除了存储数据外,还有两个指针分别指向前一个节点地址(前驱指针prev)和下一个节点地址(后继指针next)。
+2)首节点的前驱指针prev和尾节点的后继指针均指向空地址。
+3)性能特点:
+和单链表相比,存储相同的数据,需要消耗更多的存储空间。
+插入、删除操作比单链表效率更高O(1)级别。以删除操作为例,删除操作分为2种情况:给定数据值删除对应节点和给定节点地址删除节点。对于前一种情况,单链表和双向链表都需要从头到尾进行遍历从而找到对应节点进行删除,时间复杂度为O(n)。对于第二种情况,要进行删除操作必须找到前驱节点,单链表需要从头到尾进行遍历直到p->next = q,时间复杂度为O(n),而双向链表可以直接找到前驱节点,时间复杂度为O(1)。
+对于一个有序链表,双向链表的按值查询效率要比单链表高一些。因为我们可以记录上次查找的位置p,每一次查询时,根据要查找的值与p的大小关系,决定是往前还是往后查找,所以平均只需要查找一半的数据。
+4.双向循环链表:首节点的前驱指针指向尾节点,尾节点的后继指针指向首节点。
+四、选择数组还是链表?
+1.插入、删除和随机访问的时间复杂度
+数组:插入、删除的时间复杂度是O(n),随机访问的时间复杂度是O(1)。
+链表:插入、删除的时间复杂度是O(1),随机访问的时间复杂端是O(n)。
+2.数组缺点
+1)若申请内存空间很大,比如100M,但若内存空间没有100M的连续空间时,则会申请失败,尽管内存可用空间超过100M。
+2)大小固定,若存储空间不足,需进行扩容,一旦扩容就要进行数据复制,而这时非常费时的。
+3.链表缺点
+1)内存空间消耗更大,因为需要额外的空间存储指针信息。
+2)对链表进行频繁的插入和删除操作,会导致频繁的内存申请和释放,容易造成内存碎片,如果是Java语言,还可能会造成频繁的GC(自动垃圾回收器)操作。
+4.如何选择?
+数组简单易用,在实现上使用连续的内存空间,可以借助CPU的缓冲机制预读数组中的数据,所以访问效率更高,而链表在内存中并不是连续存储,所以对CPU缓存不友好,没办法预读。
+如果代码对内存的使用非常苛刻,那数组就更适合。
\ No newline at end of file
diff --git "a/src/main/java/com/chen/algorithm/study/X/\351\230\237\345\210\227.md" "b/src/main/java/com/chen/algorithm/study/X/\351\230\237\345\210\227.md"
new file mode 100644
index 0000000..0f7d7d7
--- /dev/null
+++ "b/src/main/java/com/chen/algorithm/study/X/\351\230\237\345\210\227.md"
@@ -0,0 +1,32 @@
+### 总结
+
+### 什么是队列?
+
+1.先进者先出,这就是典型的“队列”结构。
+2.支持两个操作:入队enqueue(),放一个数据到队尾;出队dequeue(),从队头取一个元素。
+3.所以,和栈一样,队列也是一种操作受限的线性表。
+二、如何实现队列?
+1.队列API
+public interface Queue {
+public void enqueue(T item); //入队
+public T dequeue(); //出队
+public int size(); //统计元素数量
+public boolean isNull(); //是否为空
+}
+2.数组实现(顺序队列):见下一条留言
+3.链表实现(链式队列):见下一条留言
+4.循环队列(基于数组):见下一条留言
+三、队列有哪些常见的应用?
+1.阻塞队列
+1)在队列的基础上增加阻塞操作,就成了阻塞队列。
+2)阻塞队列就是在队列为空的时候,从队头取数据会被阻塞,因为此时还没有数据可取,直到队列中有了数据才能返回;如果队列已经满了,那么插入数据的操作就会被阻塞,直到队列中有空闲位置后再插入数据,然后在返回。
+3)从上面的定义可以看出这就是一个“生产者-消费者模型”。这种基于阻塞队列实现的“生产者-消费者模型”可以有效地协调生产和消费的速度。当“生产者”生产数据的速度过快,“消费者”来不及消费时,存储数据的队列很快就会满了,这时生产者就阻塞等待,直到“消费者”消费了数据,“生产者”才会被唤醒继续生产。不仅如此,基于阻塞队列,我们还可以通过协调“生产者”和“消费者”的个数,来提高数据处理效率,比如配置几个消费者,来应对一个生产者。
+2.并发队列
+1)在多线程的情况下,会有多个线程同时操作队列,这时就会存在线程安全问题。能够有效解决线程安全问题的队列就称为并发队列。
+2)并发队列简单的实现就是在enqueue()、dequeue()方法上加锁,但是锁粒度大并发度会比较低,同一时刻仅允许一个存或取操作。
+3)实际上,基于数组的循环队列利用CAS原子操作,可以实现非常高效的并发队列。这也是循环队列比链式队列应用更加广泛的原因。
+3.线程池资源枯竭是的处理
+在资源有限的场景,当没有空闲资源时,基本上都可以通过“队列”这种数据结构来实现请求排队。
+四、思考
+1.除了线程池这种池结构会用到队列排队请求,还有哪些类似线程池结构或者场景中会用到队列的排队请求呢?
+2.今天讲到并发队列,关于如何实现无锁的并发队列,网上有很多讨论。对这个问题,你怎么看?
\ No newline at end of file
diff --git a/src/main/java/com/chen/algorithm/study/offer/test29/Solution.java b/src/main/java/com/chen/algorithm/study/offer/test29/Solution.java
new file mode 100644
index 0000000..bda3fd1
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/study/offer/test29/Solution.java
@@ -0,0 +1,87 @@
+package com.chen.algorithm.study.offer.test29;
+
+import java.util.Arrays;
+
+/**
+ * @Auther: zhunn
+ * @Date: 2020/10/10 13:58
+ * @Description: 顺时针从外往里打印矩阵(螺旋矩阵,力扣第54题)
+ */
+public class Solution {
+
+ public static int[] spiralOrder(int[][] matrix) {
+ if (matrix.length == 0) {
+ return new int[0];
+ }
+ int[] res = new int[matrix.length * matrix[0].length];
+ int u = 0, d = matrix.length - 1, l = 0, r = matrix[0].length - 1;
+ int idx = 0;
+ while (true) {
+ for (int i = l; i <= r; i++) {
+ res[idx++] = matrix[u][i];
+ }
+ if (++u > d) {
+ break;
+ }
+ for (int i = u; i <= d; i++) {
+ res[idx++] = matrix[i][r];
+ }
+ if (--r < l) {
+ break;
+ }
+ for (int i = r; i >= l; i--) {
+ res[idx++] = matrix[d][i];
+ }
+ if (--d < u) {
+ break;
+ }
+ for (int i = d; i >= u; i--) {
+ res[idx++] = matrix[i][l];
+ }
+ if (++l > r) {
+ break;
+ }
+ }
+ return res;
+ }
+
+ private static int[] spiralOrder1(int[][] matrix) {
+ if (matrix == null || matrix.length == 0) return new int[0];
+
+ int numEle = matrix.length * matrix[0].length;
+ int[] result = new int[numEle];
+ int idx = 0;
+ int left = 0, right = matrix[0].length - 1, top = 0, bottom = matrix.length - 1;
+
+ while (numEle >= 1) {
+ for (int i = left; i <= right && numEle >= 1; i++) {
+ result[idx++] = matrix[top][i];
+ numEle--;
+ }
+ top++;
+ for (int i = top; i <= bottom && numEle >= 1; i++) {
+ result[idx++] = matrix[i][right];
+ numEle--;
+ }
+ right--;
+ for (int i = right; i >= left && numEle >= 1; i--) {
+ result[idx++] = matrix[bottom][i];
+ numEle--;
+ }
+ bottom--;
+ for (int i = bottom; i >= top && numEle >= 1; i--) {
+ result[idx++] = matrix[i][left];
+ numEle--;
+ }
+ left++;
+ }
+ return result;
+ }
+
+ public static void main(String[] args) {
+ int[][] matrix = {{1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12}};
+ int[] res = spiralOrder1(matrix);
+ System.out.println(Arrays.toString(res));
+ }
+
+}
diff --git a/src/main/java/com/chen/algorithm/study/offer/test57/Solution.java b/src/main/java/com/chen/algorithm/study/offer/test57/Solution.java
new file mode 100644
index 0000000..9861e8f
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/study/offer/test57/Solution.java
@@ -0,0 +1,46 @@
+package com.chen.algorithm.study.offer.test57;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * https://leetcode-cn.com/problems/he-wei-sde-lian-xu-zheng-shu-xu-lie-lcof/solution/shi-yao-shi-hua-dong-chuang-kou-yi-ji-ru-he-yong-h/
+ *
+ * @author : chen weijie
+ * @Date: 2020-09-27 01:33
+ */
+public class Solution {
+
+ public int[][] findContinuousSequence(int target) {
+ int i = 1; // 滑动窗口的左边界
+ int j = 1; // 滑动窗口的右边界
+ int sum = 0; // 滑动窗口中数字的和
+ List res = new ArrayList<>();
+
+ while (i <= target / 2) {
+ if (sum < target) {
+ // 右边界向右移动
+ sum += j;
+ j++;
+ } else if (sum > target) {
+ // 左边界向右移动
+ sum -= i;
+ i++;
+ } else {
+ // 记录结果
+ int[] arr = new int[j - i];
+ for (int k = i; k < j; k++) {
+ arr[k - i] = k;
+ }
+ res.add(arr);
+ // 左边界向右移动
+ sum -= i;
+ i++;
+ }
+ }
+
+ return res.toArray(new int[res.size()][]);
+ }
+
+
+}
diff --git a/src/main/java/com/chen/algorithm/study/test1/Solution.java b/src/main/java/com/chen/algorithm/study/test1/Solution.java
index 36c5191..834ac07 100644
--- a/src/main/java/com/chen/algorithm/study/test1/Solution.java
+++ b/src/main/java/com/chen/algorithm/study/test1/Solution.java
@@ -6,10 +6,15 @@
* 正确
* @author : chen weijie
* @Date: 2019-09-02 23:52
+ * @Description: 两数之和
*/
public class Solution {
public int[] twoSum(int[] nums, int target) {
+ if (nums == null || nums.length == 0) {
+ return new int[0];
+ }
+
for (int i = 0; i < nums.length; i++) {
for (int j = i + 1; j < nums.length; j++) {
if (nums[i] + nums[j] == target) {
diff --git a/src/main/java/com/chen/algorithm/study/test1/Solution3.java b/src/main/java/com/chen/algorithm/study/test1/Solution3.java
new file mode 100644
index 0000000..59397b6
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/study/test1/Solution3.java
@@ -0,0 +1,42 @@
+package com.chen.algorithm.study.test1;
+
+import org.junit.Test;
+
+/**
+ * 正确
+ *
+ * @author : chen weijie
+ * @Date: 2019-09-02 23:52
+ */
+public class Solution3 {
+
+ public int[] twoSum(int[] nums, int target) {
+
+ for (int i = 0; i < nums.length; i++) {
+ for (int j = i; j < nums.length; j++) {
+ if (nums[i] == target - nums[j]) {
+ return new int[]{i, j};
+ }
+ }
+
+ }
+ throw new RuntimeException();
+ }
+
+
+ @Test
+ public void testCase() {
+
+ int[] array = {4, 5, 6, 7, 2};
+
+ int[] result = twoSum(array, 9);
+
+ for (int value : result) {
+ System.out.println(value);
+
+ }
+
+ }
+
+
+}
diff --git a/src/main/java/com/chen/algorithm/study/test1/Solution4.java b/src/main/java/com/chen/algorithm/study/test1/Solution4.java
new file mode 100644
index 0000000..d626044
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/study/test1/Solution4.java
@@ -0,0 +1,47 @@
+package com.chen.algorithm.study.test1;
+
+import com.alibaba.fastjson.JSON;
+import org.junit.Test;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * @Auther: zhunn
+ * @Date: 2020/10/22 19:00
+ * @Description: 两数之和
+ */
+public class Solution4 {
+
+ public int[] twoSum1(int[] nums, int target) {
+ int n = nums.length;
+ for (int i = 0; i < n; ++i) {
+ for (int j = i + 1; j < n; ++j) {
+ if (nums[i] + nums[j] == target) {
+ return new int[]{i, j};
+ }
+ }
+ }
+ return new int[0];
+ }
+
+ public int[] twoSum2(int[] nums, int target) {
+ Map hashtable = new HashMap<>();
+ for (int i = 0; i < nums.length; ++i) {
+ if (hashtable.containsKey(target - nums[i])) {
+ return new int[]{hashtable.get(target - nums[i]), i};
+ }
+ hashtable.put(nums[i], i);
+ }
+ return new int[0];
+ }
+
+ @Test
+ public void testCase() {
+ int[] array = {4, 5, 6, 7, 2};
+
+ int[] result = twoSum1(array, 9);
+ System.out.println(JSON.toJSONString(result));
+
+ }
+}
diff --git a/src/main/java/com/chen/algorithm/study/test101/Solution.java b/src/main/java/com/chen/algorithm/study/test101/Solution.java
new file mode 100644
index 0000000..6cdecc2
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/study/test101/Solution.java
@@ -0,0 +1,62 @@
+package com.chen.algorithm.study.test101;
+
+import org.junit.Test;
+
+/**
+ * https://leetcode-cn.com/problems/symmetric-tree/solution/dui-cheng-er-cha-shu-by-leetcode/
+ *
+ * @author : chen weijie
+ * @Date: 2019-11-01 00:02
+ */
+public class Solution {
+
+
+ public boolean isSymmetric(TreeNode root) {
+ return isMirror(root, root);
+ }
+
+
+ private boolean isMirror(TreeNode t1, TreeNode t2) {
+
+ if ((t1 == null) && (t2 == null)) {
+ return true;
+ }
+
+ if ((t1 == null) || (t2 == null)) {
+ return false;
+ }
+
+ return (t1.val == t2.val)
+ && (isMirror(t1.left, t2.right))
+ && (isMirror(t1.right, t2.left));
+ }
+
+
+ @Test
+ public void testCase() {
+
+ TreeNode root = new TreeNode(1);
+ TreeNode left2 = new TreeNode(2);
+ TreeNode right2 = new TreeNode(2);
+
+
+ TreeNode left3 = new TreeNode(3);
+ TreeNode right4 = new TreeNode(4);
+
+ TreeNode left3_3 = new TreeNode(3);
+ TreeNode right4_4 = new TreeNode(4);
+
+ root.setLeft(left2);
+ root.setRight(right2);
+ left2.setLeft(left3);
+ left2.setRight(right4);
+ right2.setLeft(right4_4);
+ right2.setRight(left3_3);
+
+ System.out.println(isSymmetric(root));
+
+
+ }
+
+
+}
diff --git a/src/main/java/com/chen/algorithm/study/test101/TreeNode.java b/src/main/java/com/chen/algorithm/study/test101/TreeNode.java
new file mode 100644
index 0000000..2f3db1c
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/study/test101/TreeNode.java
@@ -0,0 +1,45 @@
+package com.chen.algorithm.study.test101;
+
+/**
+ * @author : chen weijie
+ * @Date: 2019-11-01 00:03
+ */
+public class TreeNode {
+
+ int val;
+
+ TreeNode left;
+
+ TreeNode right;
+
+ public TreeNode() {
+ }
+
+ public TreeNode(int val) {
+ this.val = val;
+ }
+
+ public int getVal() {
+ return val;
+ }
+
+ public void setVal(int val) {
+ this.val = val;
+ }
+
+ public TreeNode getLeft() {
+ return left;
+ }
+
+ public void setLeft(TreeNode left) {
+ this.left = left;
+ }
+
+ public TreeNode getRight() {
+ return right;
+ }
+
+ public void setRight(TreeNode right) {
+ this.right = right;
+ }
+}
diff --git a/src/main/java/com/chen/algorithm/study/test102/Solution.java b/src/main/java/com/chen/algorithm/study/test102/Solution.java
new file mode 100644
index 0000000..137fb63
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/study/test102/Solution.java
@@ -0,0 +1,54 @@
+package com.chen.algorithm.study.test102;
+
+import java.util.ArrayList;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Queue;
+
+/**
+ * @author : chen weijie
+ * @Date: 2019-12-03 00:47
+ */
+public class Solution {
+
+
+ class TreeNode {
+ int val;
+ TreeNode left;
+ TreeNode right;
+
+ TreeNode(int x) {
+ val = x;
+ }
+ }
+
+
+ public List
> levelOrder(TreeNode root) {
+ if (root == null) {
+ return new ArrayList<>();
+ }
+
+ List> result = new ArrayList<>();
+ Queue queue = new LinkedList<>();
+ queue.add(root);
+ while (!queue.isEmpty()) {
+ int size = queue.size();
+ ArrayList arrayList = new ArrayList<>();
+
+ for (int i = 0; i < size; i++) {
+ TreeNode temp = queue.poll();
+ arrayList.add(temp.val);
+ if (temp.left != null) {
+ queue.add(temp.left);
+ }
+ if (temp.right != null) {
+ queue.add(temp.right);
+ }
+ }
+ result.add(arrayList);
+ }
+ return result;
+ }
+
+
+}
diff --git a/src/main/java/com/chen/algorithm/study/test102/Solution2.java b/src/main/java/com/chen/algorithm/study/test102/Solution2.java
new file mode 100644
index 0000000..63a7cce
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/study/test102/Solution2.java
@@ -0,0 +1,37 @@
+package com.chen.algorithm.study.test102;
+
+import java.util.List;
+
+/**
+ * @author : chen weijie
+ * @Date: 2020-05-11 23:01
+ */
+public class Solution2 {
+
+
+ public class TreeNode {
+ int val;
+ TreeNode left;
+ TreeNode right;
+
+ TreeNode(int x) {
+ val = x;
+ }
+ }
+
+
+ public List> levelOrder(TreeNode root) {
+
+
+
+ return null;
+ }
+
+
+
+
+
+
+
+
+}
diff --git a/src/main/java/com/chen/algorithm/study/test103.java b/src/main/java/com/chen/algorithm/study/test103.java
new file mode 100644
index 0000000..50e80e5
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/study/test103.java
@@ -0,0 +1,68 @@
+package com.chen.algorithm.study;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Stack;
+
+/**
+ * https://leetcode-cn.com/problems/binary-tree-zigzag-level-order-traversal/solution/jiao-ti-shi-yong-zhan-jian-dan-shi-xian-ju-chi-xin/
+ *
+ * @author : chen weijie
+ * @Date: 2020-08-23 17:01
+ */
+public class test103 {
+
+ class TreeNode {
+ int val;
+ TreeNode left;
+ TreeNode right;
+ TreeNode(int x) {
+ val = x;
+ }
+ }
+
+
+ public List> zigzagLevelOrder(TreeNode root) {
+
+ List> res = new ArrayList<>();
+ if (root == null){
+ return res;
+ }
+
+ Stack stack1 = new Stack<>();
+ Stack stack2 = new Stack<>();
+
+ stack1.push(root);
+
+ while (!stack1.isEmpty() ||!stack2.isEmpty()){
+
+ List list = new ArrayList<>();
+ res.add(list);
+ if (!stack1.isEmpty()){
+ while (!stack1.isEmpty()){
+ TreeNode node = stack1.pop();
+ list.add(node.val);
+ if (node.left !=null){
+ stack2.push(node.left);
+ }
+ if (node.right != null){
+ stack2.push(node.right);
+ }
+ }
+ }else {
+ while (!stack2.isEmpty()){
+ TreeNode node = stack1.pop();
+ list.add(node.val);
+ if (node.right !=null){
+ stack1.push(node.right);
+ }
+ if (node.left != null){
+ stack1.push(node.left);
+ }
+ }
+ }
+ }
+ return res;
+ }
+
+}
diff --git a/src/main/java/com/chen/algorithm/study/test104/Solution.java b/src/main/java/com/chen/algorithm/study/test104/Solution.java
new file mode 100644
index 0000000..eaa53d9
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/study/test104/Solution.java
@@ -0,0 +1,44 @@
+package com.chen.algorithm.study.test104;
+
+import org.junit.Test;
+
+/**
+ * https://leetcode-cn.com/problems/maximum-depth-of-binary-tree/solution/javasan-chong-jie-fa-xun-huan-ban-bfs-xun-huan-ban/
+ *
+ * 深度优先遍历和广度优先遍历
+ *
+ * @author : chen weijie
+ * @Date: 2019-11-01 00:25
+ */
+public class Solution {
+
+
+ public int maxDepth(TreeNode root) {
+ return root == null ? 0 : Math.max(maxDepth(root.left), maxDepth(root.right)) + 1;
+ }
+
+
+ @Test
+ public void testCase() {
+
+ TreeNode root = new TreeNode(1);
+ TreeNode left2 = new TreeNode(2);
+ TreeNode right2 = new TreeNode(2);
+
+
+ TreeNode left3_3 = new TreeNode(3);
+ TreeNode right4_4 = new TreeNode(4);
+
+ root.setLeft(left2);
+ root.setRight(right2);
+
+ right2.setLeft(right4_4);
+ right2.setRight(left3_3);
+
+ System.out.println(maxDepth(root));
+
+
+ }
+
+
+}
diff --git a/src/main/java/com/chen/algorithm/study/test104/Solution2.java b/src/main/java/com/chen/algorithm/study/test104/Solution2.java
new file mode 100644
index 0000000..52fcf00
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/study/test104/Solution2.java
@@ -0,0 +1,41 @@
+package com.chen.algorithm.study.test104;
+
+import java.util.LinkedList;
+import java.util.Queue;
+
+/**
+ * @author : chen weijie
+ * @Date: 2020-05-17 01:09
+ */
+public class Solution2 {
+
+
+ public int maxDepth(TreeNode root) {
+
+ if (root == null) {
+ return 0;
+ }
+
+ Queue queue = new LinkedList<>();
+ queue.add(root);
+
+ int maxDepth = 0;
+ while (!queue.isEmpty()) {
+ maxDepth++;
+
+ int length = queue.size();
+ for (int i = 0; i < length; i++) {
+ TreeNode node = queue.poll();
+
+ if (node.left != null) {
+ queue.add(node.left);
+ }
+
+ if (node.right != null) {
+ queue.add(node.right);
+ }
+ }
+ }
+ return maxDepth;
+ }
+}
diff --git a/src/main/java/com/chen/algorithm/study/test104/TreeNode.java b/src/main/java/com/chen/algorithm/study/test104/TreeNode.java
new file mode 100644
index 0000000..8e54edb
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/study/test104/TreeNode.java
@@ -0,0 +1,45 @@
+package com.chen.algorithm.study.test104;
+
+/**
+ * @author : chen weijie
+ * @Date: 2019-11-01 00:03
+ */
+public class TreeNode {
+
+ int val;
+
+ TreeNode left;
+
+ TreeNode right;
+
+ public TreeNode() {
+ }
+
+ public TreeNode(int val) {
+ this.val = val;
+ }
+
+ public int getVal() {
+ return val;
+ }
+
+ public void setVal(int val) {
+ this.val = val;
+ }
+
+ public TreeNode getLeft() {
+ return left;
+ }
+
+ public void setLeft(TreeNode left) {
+ this.left = left;
+ }
+
+ public TreeNode getRight() {
+ return right;
+ }
+
+ public void setRight(TreeNode right) {
+ this.right = right;
+ }
+}
diff --git a/src/main/java/com/chen/algorithm/study/test107/Solution.java b/src/main/java/com/chen/algorithm/study/test107/Solution.java
new file mode 100644
index 0000000..e122859
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/study/test107/Solution.java
@@ -0,0 +1,46 @@
+package com.chen.algorithm.study.test107;
+
+import java.util.*;
+
+/**
+ * @author : chen weijie
+ * @Date: 2020-09-16 14:57
+ */
+public class Solution {
+
+ public List> levelOrderBottom(TreeNode root) {
+ List> res = new ArrayList<>();
+
+ if (root == null) {
+ return res;
+ }
+
+ Queue queue = new LinkedList<>();
+ queue.add(root);
+ Stack> stack = new Stack<>();
+
+ while (!queue.isEmpty()) {
+ int size = queue.size();
+ List list = new ArrayList<>();
+ // res.add(list);
+ stack.push(list);
+ for (int i = 0; i < size; i++) {
+ TreeNode node = queue.remove();
+ list.add(node.val);
+
+ if (node.left != null) {
+ queue.add(node.left);
+ }
+ if (node.right != null) {
+ queue.add(node.right);
+ }
+ }
+ }
+ // res = new ArrayList<>();
+ while (!stack.isEmpty()) {
+ res.add(stack.pop());
+ }
+
+ return res;
+ }
+}
diff --git a/src/main/java/com/chen/algorithm/study/test107/TreeNode.java b/src/main/java/com/chen/algorithm/study/test107/TreeNode.java
new file mode 100644
index 0000000..8e9e7a9
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/study/test107/TreeNode.java
@@ -0,0 +1,45 @@
+package com.chen.algorithm.study.test107;
+
+/**
+ * @author : chen weijie
+ * @Date: 2019-11-01 00:03
+ */
+public class TreeNode {
+
+ int val;
+
+ TreeNode left;
+
+ TreeNode right;
+
+ public TreeNode() {
+ }
+
+ public TreeNode(int val) {
+ this.val = val;
+ }
+
+ public int getVal() {
+ return val;
+ }
+
+ public void setVal(int val) {
+ this.val = val;
+ }
+
+ public TreeNode getLeft() {
+ return left;
+ }
+
+ public void setLeft(TreeNode left) {
+ this.left = left;
+ }
+
+ public TreeNode getRight() {
+ return right;
+ }
+
+ public void setRight(TreeNode right) {
+ this.right = right;
+ }
+}
diff --git a/src/main/java/com/chen/algorithm/study/test11/Solution.java b/src/main/java/com/chen/algorithm/study/test11/Solution.java
new file mode 100644
index 0000000..a9a2afc
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/study/test11/Solution.java
@@ -0,0 +1,43 @@
+package com.chen.algorithm.study.test11;
+
+import org.junit.Test;
+
+/**
+ * @author : chen weijie
+ * @Date: 2019-11-08 23:19
+ */
+public class Solution {
+
+ public int maxArea(int[] height) {
+
+ int max = 0;
+
+ int i = 0, j = height.length - 1;
+
+ while (i < j) {
+
+ int d = Math.min(height[i], height[j]);
+ max = Math.max((j - i) * d, max);
+ if (height[i] < height[j]) {
+ i++;
+ } else {
+ j--;
+ }
+ }
+
+
+ return max;
+ }
+
+
+ @Test
+ public void testCase() {
+
+ int[] n = {1, 8, 6, 2, 5, 4, 8, 3, 7};
+
+ System.out.println(maxArea(n));
+
+ }
+
+
+}
diff --git a/src/main/java/com/chen/algorithm/study/test11/Solution1.java b/src/main/java/com/chen/algorithm/study/test11/Solution1.java
new file mode 100644
index 0000000..ca20b34
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/study/test11/Solution1.java
@@ -0,0 +1,36 @@
+package com.chen.algorithm.study.test11;
+
+import org.junit.Test;
+
+/**
+ * @author : chen weijie
+ * @Date: 2019-11-08 23:37
+ */
+public class Solution1 {
+
+
+ public int maxArea(int[] height) {
+ int maxArea = 0, l = 0, r = height.length - 1;
+ while (r > l) {
+ maxArea = Math.max((r - l) * Math.min(height[l], height[r]), maxArea);
+ if (height[l] < height[r]) {
+ l++;
+ } else {
+ r--;
+ }
+ }
+ return maxArea;
+ }
+
+
+ @Test
+ public void testCase() {
+
+ int[] n = {1, 8, 6, 2, 5, 4, 8, 3, 7};
+
+ System.out.println(maxArea(n));
+
+ }
+
+
+}
diff --git a/src/main/java/com/chen/algorithm/study/test11/Solution2.java b/src/main/java/com/chen/algorithm/study/test11/Solution2.java
new file mode 100644
index 0000000..294f911
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/study/test11/Solution2.java
@@ -0,0 +1,40 @@
+package com.chen.algorithm.study.test11;
+
+import org.junit.Test;
+
+/**
+ * @author : chen weijie
+ * @Date: 2019-11-08 23:37
+ */
+public class Solution2 {
+
+
+ public int maxArea(int[] height) {
+
+ int maxArea = 0;
+
+ int i = 0, j = height.length - 1;
+
+ while (i < j){
+ maxArea = Math.max((j - i) * Math.min(height[i], height[j]), maxArea);
+ if (height[i] < height[j]) {
+ i++;
+ } else {
+ j--;
+ }
+ }
+ return maxArea;
+ }
+
+
+ @Test
+ public void testCase() {
+
+ int[] n = {1, 8, 6, 2, 5, 4, 8, 3, 7};
+
+ System.out.println(maxArea(n));
+
+ }
+
+
+}
diff --git a/src/main/java/com/chen/algorithm/study/test111/Solution.java b/src/main/java/com/chen/algorithm/study/test111/Solution.java
new file mode 100644
index 0000000..7809644
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/study/test111/Solution.java
@@ -0,0 +1,46 @@
+package com.chen.algorithm.study.test111;
+
+import java.util.LinkedList;
+import java.util.Queue;
+
+/**
+ * @author : chen weijie
+ * @Date: 2020-05-17 01:17
+ */
+public class Solution {
+
+ public int minDepth(TreeNode root) {
+
+ if (root == null) {
+ return 0;
+ }
+
+ Queue queue = new LinkedList<>();
+ queue.add(root);
+
+ int minDepth = 0;
+ while (!queue.isEmpty()) {
+ minDepth++;
+
+ int length = queue.size();
+ for (int i = 0; i < length; i++) {
+ TreeNode node = queue.poll();
+
+ if (node.left != null) {
+ queue.add(node.left);
+ }
+
+ if (node.right != null) {
+ queue.add(node.right);
+ }
+
+ if (node.left == null && node.right == null) {
+ return minDepth;
+ }
+ }
+ }
+ return minDepth;
+ }
+
+
+}
diff --git a/src/main/java/com/chen/algorithm/study/test111/Solution2.java b/src/main/java/com/chen/algorithm/study/test111/Solution2.java
new file mode 100644
index 0000000..2d59b66
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/study/test111/Solution2.java
@@ -0,0 +1,21 @@
+package com.chen.algorithm.study.test111;
+
+
+/**
+ * @author : chen weijie
+ * @Date: 2020-05-17 01:09
+ */
+public class Solution2 {
+
+
+ public int minDepth(TreeNode root) {
+
+ if (root == null) {
+ return 0;
+ }
+ int left = minDepth(root.left);
+ int right = minDepth(root.right);
+
+ return (left == 0 || right == 0) ? 1 : Math.min(left, right) + 1;
+ }
+}
diff --git a/src/main/java/com/chen/algorithm/study/test111/TreeNode.java b/src/main/java/com/chen/algorithm/study/test111/TreeNode.java
new file mode 100644
index 0000000..aa9514c
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/study/test111/TreeNode.java
@@ -0,0 +1,45 @@
+package com.chen.algorithm.study.test111;
+
+/**
+ * @author : chen weijie
+ * @Date: 2019-11-01 00:03
+ */
+public class TreeNode {
+
+ int val;
+
+ TreeNode left;
+
+ TreeNode right;
+
+ public TreeNode() {
+ }
+
+ public TreeNode(int val) {
+ this.val = val;
+ }
+
+ public int getVal() {
+ return val;
+ }
+
+ public void setVal(int val) {
+ this.val = val;
+ }
+
+ public TreeNode getLeft() {
+ return left;
+ }
+
+ public void setLeft(TreeNode left) {
+ this.left = left;
+ }
+
+ public TreeNode getRight() {
+ return right;
+ }
+
+ public void setRight(TreeNode right) {
+ this.right = right;
+ }
+}
diff --git a/src/main/java/com/chen/algorithm/study/test120/Solution.java b/src/main/java/com/chen/algorithm/study/test120/Solution.java
new file mode 100644
index 0000000..5d0ba71
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/study/test120/Solution.java
@@ -0,0 +1,50 @@
+package com.chen.algorithm.study.test120;
+
+import org.junit.Test;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * @author : chen weijie
+ * @Date: 2020-05-17 20:07
+ */
+public class Solution {
+
+ public int minimumTotal(List> triangle) {
+ if (triangle == null || triangle.size() == 0) {
+ return 0;
+ }
+ int n = triangle.size();
+ int m = triangle.get(n-1).size();
+
+ // 由于存储最高层的数据,所以需要数值上加1
+ int [][] dp = new int[n+1][m+1];
+
+ for (int i = triangle.size() - 1; i >= 0; i--) {
+ List rows = triangle.get(i);
+ for (int j = 0; j < rows.size(); j++) {
+ dp[i][j] = Math.min(dp[i + 1][j], dp[i + 1][j + 1]) + rows.get(j);
+ }
+ }
+ return dp[0][0];
+ }
+
+
+
+ @Test
+ public void testCase(){
+
+ List> triangle = new ArrayList<>();
+
+ triangle.add(Arrays.asList(2));
+ triangle.add(Arrays.asList(3, 4));
+ triangle.add(Arrays.asList(6, 5, 7));
+ triangle.add(Arrays.asList(4, 1, 8, 3));
+
+ System.out.println(minimumTotal(triangle));
+
+ }
+
+}
diff --git a/src/main/java/com/chen/algorithm/study/test120/Solution1.java b/src/main/java/com/chen/algorithm/study/test120/Solution1.java
new file mode 100644
index 0000000..563defb
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/study/test120/Solution1.java
@@ -0,0 +1,44 @@
+package com.chen.algorithm.study.test120;
+
+import org.junit.Test;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * @author : chen weijie
+ * @Date: 2020-05-17 20:07
+ */
+public class Solution1 {
+
+ public int minimumTotal(List> triangle) {
+
+ int m = triangle.size();
+ int n = triangle.get(m-1).size();
+ int[][] dp = new int[m + 1][n + 1];
+
+ for (int i = m - 1; i >= 0; i--) {
+ for (int j = 0; j < triangle.get(i).size(); j++) {
+ dp[i][j] = Math.min(dp[i+1][j], dp[i + 1][j + 1]) + triangle.get(i).get(j);
+ }
+ }
+ return dp[0][0];
+ }
+
+
+ @Test
+ public void testCase() {
+
+ List> triangle = new ArrayList<>();
+
+ triangle.add(Arrays.asList(2));
+ triangle.add(Arrays.asList(3, 4));
+ triangle.add(Arrays.asList(6, 5, 7));
+ triangle.add(Arrays.asList(4, 1, 8, 3));
+
+ System.out.println(minimumTotal(triangle));
+
+ }
+
+}
diff --git a/src/main/java/com/chen/algorithm/study/test121/Solution.java b/src/main/java/com/chen/algorithm/study/test121/Solution.java
new file mode 100644
index 0000000..ff96722
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/study/test121/Solution.java
@@ -0,0 +1,34 @@
+package com.chen.algorithm.study.test121;
+
+import org.junit.Test;
+
+/**
+ * @author : chen weijie
+ * @Date: 2019-11-01 23:54
+ */
+public class Solution {
+
+
+ public int maxProfit(int[] prices) {
+ int max = 0;
+ for (int i = 0; i < prices.length; i++) {
+ for (int j = prices.length - 1; j > 0; j--) {
+ if (i > j) {
+ continue;
+ }
+ max = Math.max(max, prices[j] - prices[i]);
+ }
+ }
+ return max;
+ }
+
+
+ @Test
+ public void testCase() {
+
+ int[] n = {7, 6, 4, 3, 1};
+
+ System.out.println(maxProfit(n));
+ }
+
+}
diff --git a/src/main/java/com/chen/algorithm/study/test121/Solution0.java b/src/main/java/com/chen/algorithm/study/test121/Solution0.java
new file mode 100644
index 0000000..847c10a
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/study/test121/Solution0.java
@@ -0,0 +1,37 @@
+package com.chen.algorithm.study.test121;
+
+import org.junit.Test;
+
+/**
+ * @author : chen weijie
+ * @Date: 2020-08-05 15:27
+ */
+public class Solution0 {
+
+
+ public int max(int[] prices) {
+
+ if (prices == null || prices.length == 0) {
+ return 0;
+ }
+
+ int min = prices[0], max = 0;
+ for (int i = 1; i < prices.length; i++) {
+ if (prices[i] < min) {
+ min = prices[i];
+ }
+ max = Math.max(max, prices[i] - min);
+ }
+
+ return max;
+ }
+
+
+ @Test
+ public void testCase() {
+ int[] n = {4, 1, 6, 10, 3, 1, 18};
+ System.out.println(max(n));
+ }
+
+
+}
diff --git a/src/main/java/com/chen/algorithm/study/test121/Solution2.java b/src/main/java/com/chen/algorithm/study/test121/Solution2.java
new file mode 100644
index 0000000..c89e799
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/study/test121/Solution2.java
@@ -0,0 +1,35 @@
+package com.chen.algorithm.study.test121;
+
+import org.junit.Test;
+
+/**
+ * 双指针算法
+ *
+ * @author : chen weijie
+ * @Date: 2019-11-01 23:54
+ */
+public class Solution2 {
+
+
+ public int maxProfit(int[] prices) {
+
+
+ int min = Integer.MAX_VALUE;
+ int max = 0;
+ for (int price : prices) {
+ min = Math.min(price, min);
+ max = Math.max(max, price - min);
+ }
+ return max;
+ }
+
+
+ @Test
+ public void testCase() {
+
+ int[] n = {7, 6, 4, 3, 1};
+
+ System.out.println(maxProfit(n));
+ }
+
+}
diff --git a/src/main/java/com/chen/algorithm/study/test121/Solution3.java b/src/main/java/com/chen/algorithm/study/test121/Solution3.java
new file mode 100644
index 0000000..5f6d87b
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/study/test121/Solution3.java
@@ -0,0 +1,40 @@
+package com.chen.algorithm.study.test121;
+
+import org.junit.Test;
+
+/**
+ * 双指针算法
+ *
+ * https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock/solution/yi-ge-fang-fa-tuan-mie-6-dao-gu-piao-wen-ti-by-l-3/
+ *
+ * @author : chen weijie
+ * @Date: 2019-11-01 23:54
+ */
+public class Solution3 {
+
+
+ public int maxProfit(int[] prices) {
+
+ if (prices == null || prices.length == 0) {
+ return 0;
+ }
+
+ int min = Integer.MAX_VALUE;
+ int max = 0;
+ for (int price : prices) {
+ min = Math.min(price, min);
+ max = Math.max(max, price - min);
+ }
+ return max;
+ }
+
+
+ @Test
+ public void testCase() {
+
+ int[] n = {7, 6, 4, 3, 1};
+
+ System.out.println(maxProfit(n));
+ }
+
+}
diff --git a/src/main/java/com/chen/algorithm/study/test122/Solution.java b/src/main/java/com/chen/algorithm/study/test122/Solution.java
new file mode 100644
index 0000000..e6ca12a
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/study/test122/Solution.java
@@ -0,0 +1,30 @@
+package com.chen.algorithm.study.test122;
+
+/**
+ * @author : chen weijie
+ * @Date: 2020-05-16 23:36
+ */
+public class Solution {
+
+
+ public static int maxProfit(int[] prices) {
+
+ int max = 0;
+
+ for (int i = 1; i < prices.length; i++) {
+ if (prices[i] > prices[i - 1]) {
+ max = max + (prices[i] - prices[i - 1]);
+ }
+ }
+ return max;
+ }
+
+
+ public static void main(String[] args) {
+ int[] n = {7, 1, 5, 3, 6, 4};
+ System.out.println(maxProfit(n));
+
+ }
+
+
+}
diff --git a/src/main/java/com/chen/algorithm/study/test122/Solution2.java b/src/main/java/com/chen/algorithm/study/test122/Solution2.java
new file mode 100644
index 0000000..c554bb8
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/study/test122/Solution2.java
@@ -0,0 +1,34 @@
+package com.chen.algorithm.study.test122;
+
+/**
+ * @author : chen weijie
+ * @Date: 2020-05-16 23:36
+ */
+public class Solution2 {
+
+
+ public static int maxProfit(int[] prices) {
+
+ if (prices == null || prices.length == 0) {
+ return 0;
+ }
+
+
+ int sum = 0;
+ for (int i = 1; i < prices.length; i++) {
+ if (prices[i - 1] < prices[i]) {
+ sum = sum + (prices[i] - prices[i - 1]);
+ }
+ }
+ return sum;
+ }
+
+
+ public static void main(String[] args) {
+ int[] n = {7, 1, 5, 3, 6, 4};
+ System.out.println(maxProfit(n));
+
+ }
+
+
+}
diff --git a/src/main/java/com/chen/algorithm/study/test123/Solution.java b/src/main/java/com/chen/algorithm/study/test123/Solution.java
new file mode 100644
index 0000000..8b70900
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/study/test123/Solution.java
@@ -0,0 +1,54 @@
+package com.chen.algorithm.study.test123;
+
+/**
+ * https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock-iii/solution/dong-tai-gui-hua-by-liweiwei1419-7/
+ *
+ * 参考test188
+ *
+ * @author : chen weijie
+ * @Date: 2020-09-06 01:02
+ */
+public class Solution {
+
+ public int maxProfit(int[] prices) {
+
+ if (prices == null || prices.length == 0) {
+ return 0;
+ }
+
+ int len = prices.length;
+
+ // dp[i][j] ,表示 [0, i] 区间里,状态为 j 的最大收益
+ // j = 0:什么都不操作
+ // j = 1:第 1 次买入一支股票
+ // j = 2:第 1 次卖出一支股票
+ // j = 3:第 2 次买入一支股票
+ // j = 4:第 2 次卖出一支股票
+
+ int[][] dp = new int[len][5];
+
+ dp[0][0] = 0;
+ dp[0][1] = -prices[0];
+
+ // 3 状态都还没有发生,因此应该赋值为一个不可能的数
+ for (int i = 0; i < len; i++) {
+ dp[i][3] = Integer.MIN_VALUE;
+ }
+
+ // 状态转移只有 2 种情况:
+ // 情况 1:什么都不做
+ // 情况 2:由上一个状态转移过来
+ for (int i = 1; i < len; i++) {
+ // j = 0 的值永远是 0
+ dp[i][0] = 0;
+ dp[i][1] = Math.max(dp[i - 1][1], dp[i - 1][0] - prices[i]);
+ dp[i][2] = Math.max(dp[i - 1][2], dp[i - 1][1] + prices[i]);
+ dp[i][3] = Math.max(dp[i - 1][3], dp[i - 1][2] - prices[i]);
+ dp[i][4] = Math.max(dp[i - 1][4], dp[i - 1][3] + prices[i]);
+ }
+
+ // 最大值只发生在不持股的时候,因此来源有 3 个:j = 0 ,j = 2, j = 4
+ return Math.max(0, Math.max(dp[len - 1][2], dp[len - 1][4]));
+ }
+
+}
diff --git a/src/main/java/com/chen/algorithm/study/test136/Solution.java b/src/main/java/com/chen/algorithm/study/test136/Solution.java
new file mode 100644
index 0000000..238e2e7
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/study/test136/Solution.java
@@ -0,0 +1,30 @@
+package com.chen.algorithm.study.test136;
+
+import org.junit.Test;
+
+/**
+ * @author : chen weijie
+ * @Date: 2019-11-02 00:36
+ */
+public class Solution {
+
+
+ public int singleNumber(int[] nums) {
+
+ int ans = 0;
+ for(int num: nums) {
+ ans ^= num;
+ }
+ return ans;
+
+ }
+
+ @Test
+ public void testCase() {
+
+ int[] n = {4, 3, 4, 3, 1};
+
+ System.out.println(singleNumber(n));
+ }
+
+}
diff --git a/src/main/java/com/chen/algorithm/study/test139/Solution.java b/src/main/java/com/chen/algorithm/study/test139/Solution.java
new file mode 100644
index 0000000..8dadf46
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/study/test139/Solution.java
@@ -0,0 +1,48 @@
+package com.chen.algorithm.study.test139;
+
+import org.junit.Test;
+
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * @author : chen weijie
+ * @Date: 2019-12-04 23:26
+ */
+public class Solution {
+
+
+ public boolean wordBreak(String s, List wordDict) {
+
+ Set wordDictSet = new HashSet<>(wordDict);
+
+ boolean[] dp = new boolean[s.length() + 1];
+ dp[0] = true;
+ for (int i = 1; i <= s.length(); i++) {
+ for (int j = 0; j < i; j++) {
+
+ if (dp[j] && wordDictSet.contains(s.substring(j, i))) {
+ dp[i] = true;
+ break;
+ }
+ }
+ }
+ return dp[s.length()];
+ }
+
+
+ @Test
+ public void testCase() {
+
+ String s = "catsandog";
+ List wordDict = Arrays.asList("cats", "dog", "sand", "and", "cat");
+
+ System.out.println(wordBreak(s, wordDict));
+
+
+ }
+
+
+}
diff --git a/src/main/java/com/chen/algorithm/study/test14/Solution3.java b/src/main/java/com/chen/algorithm/study/test14/Solution3.java
new file mode 100644
index 0000000..feaf523
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/study/test14/Solution3.java
@@ -0,0 +1,54 @@
+package com.chen.algorithm.study.test14;
+
+import org.junit.Test;
+
+/**
+ * @author : chen weijie
+ * @Date: 2020-05-11 00:34
+ */
+public class Solution3 {
+
+ public String longestCommonPrefix(String[] strs) {
+ if (strs == null || strs.length == 0) {
+ return "";
+ }
+
+ String prex = strs[0];
+ for (int i = 1; i < strs.length; i++) {
+
+ while (!strs[i].startsWith(prex)) {
+ prex = prex.substring(0, prex.length() - 1);
+ if (prex.isEmpty()) {
+ return "";
+ }
+ }
+ }
+ return prex;
+ }
+
+ @Test
+ public void testCase() {
+ String[] strings = {"flower", "flow", "flight"};
+
+ System.out.println(longestCommonPrefix(strings));
+
+
+ }
+
+
+ public static void main(String[] args) {
+ String[] stringArr = {"flower", "flow", "flight"};
+ String pre = stringArr[0];
+ for (int i = 0; i map = new HashMap<>();
+
+ int n = 0;
+ while (head != null) {
+ if (map.containsValue(head)) {
+ return true;
+ } else {
+ map.put(n, head);
+ n++;
+ head = head.next;
+ }
+ }
+ return false;
+ }
+
+
+}
+
diff --git a/src/main/java/com/chen/algorithm/study/test141/Solution1.java b/src/main/java/com/chen/algorithm/study/test141/Solution1.java
new file mode 100644
index 0000000..7cf5ddf
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/study/test141/Solution1.java
@@ -0,0 +1,45 @@
+package com.chen.algorithm.study.test141;
+
+/**
+ * https://leetcode-cn.com/problems/linked-list-cycle/solution/huan-xing-lian-biao-by-leetcode/
+ *
+ * @author : chen weijie
+ * @Date: 2019-11-02 15:58
+ */
+public class Solution1 {
+
+
+ class ListNode {
+ int val;
+ ListNode next;
+
+ ListNode(int x) {
+ val = x;
+ next = null;
+ }
+ }
+
+
+ public boolean hasCycle(ListNode head) {
+
+ if (head == null || head.next == null) {
+ return false;
+ }
+
+ ListNode slow = head;
+ ListNode fast = head.next;
+
+ while (slow != fast) {
+
+ if (fast == null || fast.next == null) {
+ return false;
+ }
+ slow = slow.next;
+ fast = fast.next.next;
+ }
+ return true;
+ }
+
+
+}
+
diff --git a/src/main/java/com/chen/algorithm/study/test141/Solution2.java b/src/main/java/com/chen/algorithm/study/test141/Solution2.java
new file mode 100644
index 0000000..d09ad63
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/study/test141/Solution2.java
@@ -0,0 +1,38 @@
+package com.chen.algorithm.study.test141;
+
+/**
+ * @author : chen weijie
+ * @Date: 2020-05-03 15:23
+ */
+public class Solution2 {
+
+ class ListNode {
+ int val;
+ ListNode next;
+
+ ListNode(int x) {
+ val = x;
+ next = null;
+ }
+ }
+
+
+ public boolean hasCycle(ListNode head) {
+
+ if (head == null || head.next == null) {
+ return false;
+ }
+
+ ListNode slow = head, fast = head.next;
+
+ while (fast != null && fast.next != null) {
+ slow = slow.next;
+ fast = fast.next.next;
+ if (slow == fast) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+}
diff --git a/src/main/java/com/chen/algorithm/study/test141/Solution3.java b/src/main/java/com/chen/algorithm/study/test141/Solution3.java
new file mode 100644
index 0000000..75c18d8
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/study/test141/Solution3.java
@@ -0,0 +1,87 @@
+package com.chen.algorithm.study.test141;
+
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * @Auther: zhunn
+ * @Date: 2020/10/23 16:26
+ * @Description: 环形链表一:判断链表是否有环
+ * 方法:1-哈希表,2-快慢指针
+ */
+public class Solution3 {
+ class ListNode {
+ int val;
+ ListNode next;
+
+ ListNode(int x) {
+ val = x;
+ next = null;
+ }
+ }
+
+
+ /**
+ * 2-快慢指针
+ * @param head
+ * @return
+ */
+ public boolean hasCycle1(ListNode head) {
+ if (head == null || head.next == null) {
+ return false;
+ }
+
+ ListNode slow = head;
+ ListNode fast = head;
+
+ while (fast != null && fast.next != null) {
+ slow = slow.next;
+ fast = fast.next.next;
+
+ if (slow == fast) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * 1-哈希表
+ * @param head
+ * @return
+ */
+ public boolean hasCycle2(ListNode head) {
+ if (head == null || head.next == null) {
+ return false;
+ }
+
+ ListNode dummy = head;
+ Set visited = new HashSet<>();
+ while (dummy != null) {
+ if (visited.contains(dummy)) {
+ return true;
+ } else {
+ visited.add(dummy);
+ }
+ dummy = dummy.next;
+ }
+ return false;
+ }
+
+ /**
+ * 1-哈希表简易版
+ * @param head
+ * @return
+ */
+ public boolean hasCycle3(ListNode head) {
+ Set seen = new HashSet<>();
+ while (head != null) {
+ if (!seen.add(head)) {
+ return true;
+ }
+ head = head.next;
+ }
+ return false;
+ }
+
+}
diff --git a/src/main/java/com/chen/algorithm/study/test142/ListNode.java b/src/main/java/com/chen/algorithm/study/test142/ListNode.java
new file mode 100644
index 0000000..d297b64
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/study/test142/ListNode.java
@@ -0,0 +1,16 @@
+package com.chen.algorithm.study.test142;
+
+/**
+ * @author : chen weijie
+ * @Date: 2019-12-05 00:05
+ */
+public class ListNode {
+
+ int val;
+ ListNode next;
+
+ ListNode(int x) {
+ val = x;
+ next = null;
+ }
+}
diff --git a/src/main/java/com/chen/algorithm/study/test142/Solution.java b/src/main/java/com/chen/algorithm/study/test142/Solution.java
new file mode 100644
index 0000000..3225f8d
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/study/test142/Solution.java
@@ -0,0 +1,38 @@
+package com.chen.algorithm.study.test142;
+
+/**
+ * @author : chen weijie
+ * @Date: 2019-12-05 00:05
+ * https://leetcode-cn.com/problems/linked-list-cycle-ii/solution/linked-list-cycle-ii-kuai-man-zhi-zhen-shuang-zhi-/
+ */
+public class Solution {
+
+
+ public ListNode detectCycle(ListNode head) {
+
+ ListNode slow = head;
+ ListNode fast = head;
+
+ while (true) {
+ if (fast == null || fast.next == null) {
+ return null;
+ }
+
+ fast = fast.next.next;
+ slow = slow.next;
+ if (fast == slow) {
+ break;
+ }
+ }
+
+ fast = head;
+ while (slow != fast) {
+ slow = slow.next;
+ fast = fast.next;
+ }
+
+ return fast;
+ }
+
+
+}
diff --git a/src/main/java/com/chen/algorithm/study/test142/Solution2.java b/src/main/java/com/chen/algorithm/study/test142/Solution2.java
new file mode 100644
index 0000000..ae725c9
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/study/test142/Solution2.java
@@ -0,0 +1,77 @@
+package com.chen.algorithm.study.test142;
+
+/**
+ * @author : chen weijie
+ * @Date: 2019-12-05 00:16
+ */
+public class Solution2 {
+
+
+ public ListNode detectCycle(ListNode head) {
+
+ if (head == null) {
+ return head;
+ }
+
+ ListNode slow = head;
+ ListNode fast = head.next;
+
+ while (fast != null && fast.next != null) {
+ slow = slow.next;
+ fast = fast.next.next;
+ if (fast == slow) {
+ break;
+ }
+ }
+
+ if (fast == null) {
+ return null;
+ }
+ fast = head;
+
+ while (fast != slow) {
+ fast = fast.next;
+ slow = slow.next;
+ }
+ return fast;
+ }
+
+
+ public ListNode detectCycle2(ListNode head) {
+
+ if (head == null || head.next == null) {
+ return null;
+ }
+
+ ListNode slow = head;
+ ListNode fast = head.next;
+
+ while (true){
+ if (fast == null ||fast.next == null){
+ return null;
+ }
+
+ slow = slow.next;
+ fast = fast.next.next;
+
+ if (fast == slow){
+ break;
+ }
+ }
+
+ fast = head;
+ while (fast != slow) {
+ fast = fast.next;
+ slow = slow.next;
+ }
+
+ return fast;
+ }
+
+
+
+
+
+
+
+}
diff --git a/src/main/java/com/chen/algorithm/study/test142/Solution3.java b/src/main/java/com/chen/algorithm/study/test142/Solution3.java
new file mode 100644
index 0000000..e903edf
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/study/test142/Solution3.java
@@ -0,0 +1,41 @@
+package com.chen.algorithm.study.test142;
+
+/**
+ * @author : chen weijie
+ * @Date: 2020-05-03 15:47
+ */
+public class Solution3 {
+
+
+ public ListNode detectCycle(ListNode head) {
+
+ if (head == null || head.next == null) {
+ return null;
+ }
+
+ ListNode slow = head;
+ ListNode fast = head;
+
+ while (true){
+
+ if (fast == null || fast.next == null) {
+ return null;
+ }
+ slow = slow.next;
+ fast = fast.next.next;
+
+ if (slow==fast){
+ break;
+ }
+ }
+
+ fast = head;
+ while (fast != slow) {
+ slow = slow.next;
+ fast = fast.next;
+ }
+ return fast;
+ }
+
+
+}
diff --git a/src/main/java/com/chen/algorithm/study/test142/Solution4.java b/src/main/java/com/chen/algorithm/study/test142/Solution4.java
new file mode 100644
index 0000000..5d283c5
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/study/test142/Solution4.java
@@ -0,0 +1,65 @@
+package com.chen.algorithm.study.test142;
+
+
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * @Auther: zhunn
+ * @Date: 2020/10/23 16:10
+ * @Description: 环形链表二,找出入环点
+ * 方法:1-哈希表,2-快慢指针
+ */
+public class Solution4 {
+
+ /**
+ * 1-哈希表
+ * @param head
+ * @return
+ */
+ public ListNode detectCycle1(ListNode head) {
+ if (head == null || head.next == null) {
+ return null;
+ }
+ ListNode dummy = head;
+ Set visited = new HashSet<>();
+ while (dummy != null) {
+ if (visited.contains(dummy)) {
+ return dummy;
+ } else {
+ visited.add(dummy);
+ }
+ dummy = dummy.next;
+ }
+ return null;
+ }
+
+ /**
+ * 2-快慢指针
+ * @param head
+ * @return
+ */
+ public ListNode detectCycle2(ListNode head) {
+ if (head == null || head.next == null) {
+ return null;
+ }
+
+ ListNode slow = head;
+ ListNode fast = head;
+ while (fast != null && fast.next != null) {
+ slow = slow.next;
+ fast = fast.next.next;
+ if (slow == fast) {
+ break;
+ }
+ }
+
+ ListNode ptr = head;
+ while (slow != ptr) {
+ slow = slow.next;
+ ptr = ptr.next;
+ }
+ return slow;
+ }
+
+}
diff --git a/src/main/java/com/chen/algorithm/study/test144/Solution.java b/src/main/java/com/chen/algorithm/study/test144/Solution.java
new file mode 100644
index 0000000..1162974
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/study/test144/Solution.java
@@ -0,0 +1,43 @@
+package com.chen.algorithm.study.test144;
+
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Stack;
+
+/**
+ * @author : chen weijie
+ * @Date: 2020-05-11 23:21
+ */
+public class Solution {
+
+ public class TreeNode {
+ int val;
+ TreeNode left;
+ TreeNode right;
+
+ TreeNode(int x) {
+ val = x;
+ }
+ }
+
+ public List preorderTraversal(TreeNode root) {
+
+ List list = new ArrayList<>();
+ Stack stack = new Stack<>();
+ stack.push(root);
+ while (!stack.isEmpty()) {
+ TreeNode temp = stack.pop();
+ list.add(temp.val);
+
+ if (temp.right != null) {
+ stack.push(temp.right);
+ }
+ if (temp.left != null) {
+ stack.push(temp.left);
+ }
+ }
+ return list;
+ }
+
+}
diff --git a/src/main/java/com/chen/algorithm/study/test144/Solution1.java b/src/main/java/com/chen/algorithm/study/test144/Solution1.java
new file mode 100644
index 0000000..a649dc5
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/study/test144/Solution1.java
@@ -0,0 +1,37 @@
+package com.chen.algorithm.study.test144;
+
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @author : chen weijie
+ * @Date: 2020-05-11 23:21
+ */
+public class Solution1 {
+
+ public class TreeNode {
+ int val;
+ TreeNode left;
+ TreeNode right;
+
+ TreeNode(int x) {
+ val = x;
+ }
+ }
+
+ public List preorderTraversal(TreeNode root) {
+ List res = new ArrayList<>();
+
+ if (root == null) {
+ return res;
+ }
+
+ res.add(root.val);
+ preorderTraversal(root.left);
+ preorderTraversal(root.right);
+
+ return res;
+ }
+
+}
diff --git a/src/main/java/com/chen/algorithm/study/test145/Solution.java b/src/main/java/com/chen/algorithm/study/test145/Solution.java
new file mode 100644
index 0000000..db5205f
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/study/test145/Solution.java
@@ -0,0 +1,52 @@
+package com.chen.algorithm.study.test145;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Stack;
+
+/**
+ * https://leetcode-cn.com/problems/binary-tree-postorder-traversal/solution/er-cha-shu-de-hou-xu-bian-li-by-leetcode/
+ *
+ * @author : chen weijie
+ * @Date: 2020-05-12 00:06
+ */
+public class Solution {
+
+ class TreeNode {
+ int val;
+ TreeNode left;
+ TreeNode right;
+
+ TreeNode(int x) {
+ val = x;
+ }
+ }
+
+ public List postorderTraversal(TreeNode root) {
+
+ List result = new ArrayList<>();
+
+ if (root == null) {
+ return result;
+ }
+ Stack stack1 = new Stack<>();
+ Stack stack2 = new Stack<>();
+ stack1.push(root);
+ while (!stack1.isEmpty()) {
+ TreeNode node = stack1.pop();
+ stack2.push(node);
+ if (node.left != null) {
+ stack1.push(node.left);
+ }
+ if (node.right != null) {
+ stack1.push(node.right);
+ }
+ }
+ while (!stack2.isEmpty()) {
+ result.add(stack2.pop().val);
+ }
+
+ return result;
+ }
+
+}
diff --git a/src/main/java/com/chen/algorithm/study/test146/LRUCache.java b/src/main/java/com/chen/algorithm/study/test146/LRUCache.java
new file mode 100644
index 0000000..8b9a489
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/study/test146/LRUCache.java
@@ -0,0 +1,102 @@
+package com.chen.algorithm.study.test146;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * https://leetcode-cn.com/problems/lru-cache/solution/lru-ce-lue-xiang-jie-he-shi-xian-by-labuladong/
+ *
+ * @author : chen weijie
+ * @Date: 2019-12-05 23:11
+ */
+public class LRUCache {
+
+
+ class DLinkedNode {
+ int key;
+ int value;
+ DLinkedNode prev;
+ DLinkedNode next;
+
+ public DLinkedNode() {
+ }
+
+ public DLinkedNode(int _key, int _value) {
+ key = _key;
+ value = _value;
+ }
+ }
+
+ private Map cache = new HashMap<>();
+ private int size;
+ private int capacity;
+ private DLinkedNode head, tail;
+
+ public LRUCache(int capacity) {
+ this.size = 0;
+ this.capacity = capacity;
+ // 使用伪头部和伪尾部节点
+ head = new DLinkedNode();
+ tail = new DLinkedNode();
+ head.next = tail;
+ tail.prev = head;
+ }
+
+ public int get(int key) {
+ DLinkedNode node = cache.get(key);
+ if (node == null) {
+ return -1;
+ }
+ // 如果 key 存在,先通过哈希表定位,再移到头部
+ moveToHead(node);
+ return node.value;
+ }
+
+ public void put(int key, int value) {
+ DLinkedNode node = cache.get(key);
+ if (node == null) {
+ // 如果 key 不存在,创建一个新的节点
+ DLinkedNode newNode = new DLinkedNode(key, value);
+ // 添加进哈希表
+ cache.put(key, newNode);
+ // 添加至双向链表的头部
+ addToHead(newNode);
+ ++size;
+ if (size > capacity) {
+ // 如果超出容量,删除双向链表的尾部节点
+ DLinkedNode tail = removeTail();
+ // 删除哈希表中对应的项
+ cache.remove(tail.key);
+ --size;
+ }
+ } else {
+ // 如果 key 存在,先通过哈希表定位,再修改 value,并移到头部
+ node.value = value;
+ moveToHead(node);
+ }
+ }
+
+ private void addToHead(DLinkedNode node) {
+ node.prev = head;
+ node.next = head.next;
+ head.next.prev = node;
+ head.next = node;
+ }
+
+ private void removeNode(DLinkedNode node) {
+ node.prev.next = node.next;
+ node.next.prev = node.prev;
+ }
+
+ private void moveToHead(DLinkedNode node) {
+ removeNode(node);
+ addToHead(node);
+ }
+
+ private DLinkedNode removeTail() {
+ DLinkedNode res = tail.prev;
+ removeNode(res);
+ return res;
+ }
+
+}
diff --git a/src/main/java/com/chen/algorithm/study/test146/LRUCacheDemo.java b/src/main/java/com/chen/algorithm/study/test146/LRUCacheDemo.java
new file mode 100644
index 0000000..2731f84
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/study/test146/LRUCacheDemo.java
@@ -0,0 +1,79 @@
+package com.chen.algorithm.study.test146;
+
+import java.util.HashMap;
+
+/**
+ * https://leetcode-cn.com/problems/lru-cache/solution/lru-ce-lue-xiang-jie-he-shi-xian-by-labuladong/
+ *
+ * @author : chen weijie
+ * @Date: 2019-12-05 23:11
+ */
+public class LRUCacheDemo {
+
+ class DoubleLinkedListNode {
+ int k;
+ int v;
+ DoubleLinkedListNode pre;
+ DoubleLinkedListNode next;
+
+ public DoubleLinkedListNode() {
+ }
+
+ public DoubleLinkedListNode(int key, int value) {
+ this.k = key;
+ this.v = value;
+ }
+ }
+
+
+ private HashMap hashMap = new HashMap<>();
+ private int size;
+ private int capcity;
+ private DoubleLinkedListNode head, tail;
+
+ public LRUCacheDemo(int capcity, int value) {
+ this.size = 0;
+ this.capcity = capcity;
+ DoubleLinkedListNode head = new DoubleLinkedListNode();
+ DoubleLinkedListNode tail = new DoubleLinkedListNode();
+ head.next = tail;
+ tail.pre = head;
+ }
+
+
+ public int getValue(int key) {
+
+
+
+ return 0;
+
+ }
+
+ public void put() {
+
+
+ }
+
+
+ public void removeNode() {
+
+
+ }
+
+
+ public void moveToHead() {
+
+
+ }
+
+ public void addToHead() {
+
+
+ }
+
+ public void removeTail() {
+
+ }
+
+
+}
diff --git a/src/main/java/com/chen/algorithm/study/test146/Solution.java b/src/main/java/com/chen/algorithm/study/test146/Solution.java
new file mode 100644
index 0000000..fd4f262
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/study/test146/Solution.java
@@ -0,0 +1,38 @@
+package com.chen.algorithm.study.test146;
+
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+/**
+ * @author : chen weijie
+ * @Date: 2019-12-05 22:41
+ */
+public class Solution {
+
+
+ class LRUCache extends LinkedHashMap {
+
+
+ private int capacity;
+
+ public LRUCache(int capacity) {
+ super(capacity, 0.75F, true);
+ this.capacity = capacity;
+ }
+
+ public int get(int key) {
+ return super.getOrDefault(key, -1);
+ }
+
+ public void put(int key, int value) {
+ super.put(key, value);
+ }
+
+ @Override
+ protected boolean removeEldestEntry(Map.Entry eldest) {
+ return super.size() > capacity;
+ }
+ }
+
+
+}
diff --git a/src/main/java/com/chen/algorithm/study/test148/Solution.java b/src/main/java/com/chen/algorithm/study/test148/Solution.java
new file mode 100644
index 0000000..1938a24
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/study/test148/Solution.java
@@ -0,0 +1,67 @@
+package com.chen.algorithm.study.test148;
+
+/**
+ * @author : chen weijie
+ * @Date: 2019-12-05 23:57
+ */
+public class Solution {
+
+
+ public class ListNode {
+ int val;
+ ListNode next;
+
+ ListNode(int x) {
+ val = x;
+ }
+ }
+
+
+ public ListNode sortList(ListNode head) {
+
+ if (head == null || head.next == null) {
+ return head;
+ }
+
+ ListNode middle = getMiddle(head);
+ ListNode temp = middle.next;
+ middle.next = null;
+
+ ListNode left = sortList(head);
+ ListNode right = sortList(temp);
+ ListNode h = new ListNode(0);
+ ListNode res = h;
+
+ while (left != null && right != null) {
+ if (left.val < right.val) {
+ h.next = left;
+ left = left.next;
+ } else {
+ h.next = right;
+ right = right.next;
+ }
+ h = h.next;
+ }
+
+ h.next = left != null ? left : right;
+ return res.next;
+ }
+
+ private ListNode getMiddle(ListNode head) {
+
+ ListNode fast = head;
+ ListNode slow = head;
+
+ while (fast.next != null && fast.next.next != null) {
+
+ fast = fast.next.next;
+ slow = slow.next;
+
+ }
+ return slow;
+
+
+ }
+
+
+}
diff --git a/src/main/java/com/chen/algorithm/study/test15/Solution.java b/src/main/java/com/chen/algorithm/study/test15/Solution.java
new file mode 100644
index 0000000..d1e2483
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/study/test15/Solution.java
@@ -0,0 +1,61 @@
+package com.chen.algorithm.study.test15;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * https://leetcode-cn.com/problems/3sum/solution/hua-jie-suan-fa-15-san-shu-zhi-he-by-guanpengchn/
+ *
+ * @author : chen weijie
+ * @Date: 2019-11-08 23:46
+ */
+public class Solution {
+
+
+ public List> threeSum(int[] nums) {
+
+ List> ans = new ArrayList<>();
+ if (nums == null) {
+ return ans;
+ }
+ int len = nums.length;
+ if (len < 3) {
+ return ans;
+ }
+
+ Arrays.sort(nums);
+ for (int i = 0; i < len; i++) {
+ if (nums[i] > 0) {
+ return ans;
+ }
+ if (i > 0 && nums[i] == nums[i - 1]) {
+ continue;
+ }
+ int L = i + 1;
+ int R = len - 1;
+
+ while (L < R) {
+ int sum = nums[i] + nums[L] + nums[R];
+ if (sum == 0) {
+ ans.add(Arrays.asList(nums[i], nums[L], nums[R]));
+ while (L < R && nums[L] == nums[L + 1]) {
+ L++;
+ }
+ while (L < R && nums[R] == nums[R - 1]) {
+ R--;
+ }
+ L++;
+ R--;
+ } else if (sum > 0) {
+ R--;
+ } else if (sum < 0) {
+ L++;
+ }
+ }
+ }
+ return ans;
+ }
+
+
+}
diff --git a/src/main/java/com/chen/algorithm/study/test15/Solution1.java b/src/main/java/com/chen/algorithm/study/test15/Solution1.java
new file mode 100644
index 0000000..9a43ff6
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/study/test15/Solution1.java
@@ -0,0 +1,62 @@
+package com.chen.algorithm.study.test15;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * @author : chen weijie
+ * @Date: 2020-05-04 10:46
+ */
+public class Solution1 {
+
+ public List> threeSum(int[] nums) {
+
+ List> res = new ArrayList<>();
+
+ if (nums == null || nums.length == 0) {
+ return res;
+ }
+
+ Arrays.sort(nums);
+
+ for (int i = 0; i < nums.length; i++) {
+
+ if (nums[i] > 0) {
+ break;
+ }
+
+ if (i > 0 && nums[i] == nums[i - 1]) {
+ continue;
+ }
+
+ int left = i + 1, right = nums.length - 1;
+
+ while (left < right) {
+
+ int sum = nums[left] + nums[right] + nums[i];
+
+ if (sum == 0) {
+ res.add(Arrays.asList(nums[left], nums[right], nums[i]));
+ while (left < right && nums[left] == nums[left + 1]) {
+ left++;
+ }
+ while (left < right && nums[right] == nums[right - 1]) {
+ right--;
+ }
+ right--;
+ left++;
+ } else if (sum > 0) {
+ right--;
+ } else {
+ left++;
+ }
+ }
+ }
+
+
+ return res;
+ }
+
+
+}
diff --git a/src/main/java/com/chen/algorithm/study/test15/Solution2.java b/src/main/java/com/chen/algorithm/study/test15/Solution2.java
new file mode 100644
index 0000000..982dcc4
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/study/test15/Solution2.java
@@ -0,0 +1,55 @@
+package com.chen.algorithm.study.test15;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * @author : chen weijie
+ * @Date: 2020-05-22 01:50
+ */
+public class Solution2 {
+
+ public List> threeSum(int[] nums) {
+
+ List> res = new ArrayList<>();
+
+ if (nums == null || nums.length == 0) {
+ return res;
+ }
+
+ Arrays.sort(nums);
+ for (int i = 0; i < nums.length; i++) {
+ if (nums[i] > 0) {
+ break;
+ }
+ if (i > 0 && nums[i] == nums[i - 1]) {
+ continue;
+ }
+
+ int L = i + 1, R = nums.length - 1;
+ while (L < R) {
+ int sum = nums[i] + nums[L] + nums[R];
+ if (sum == 0) {
+ res.add(Arrays.asList(nums[i], nums[L], nums[R]));
+ while (L < R && nums[L] == nums[L + 1]) {
+ L++;
+ }
+ while (L < R && nums[R] == nums[R - 1]) {
+ R--;
+ }
+ L++;
+ R--;
+ } else if (sum > 0) {
+ R--;
+ } else {
+ L++;
+ }
+ }
+
+ }
+ return res;
+ }
+
+
+}
diff --git a/src/main/java/com/chen/algorithm/study/test152/Solution.java b/src/main/java/com/chen/algorithm/study/test152/Solution.java
new file mode 100644
index 0000000..bacde50
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/study/test152/Solution.java
@@ -0,0 +1,47 @@
+package com.chen.algorithm.study.test152;
+
+import org.junit.Test;
+
+/**
+ * https://leetcode-cn.com/problems/maximum-product-subarray/solution/hua-jie-suan-fa-152-cheng-ji-zui-da-zi-xu-lie-by-g/
+ *
+ * @author : chen weijie
+ * @Date: 2019-12-11 23:08
+ */
+public class Solution {
+
+
+ public int maxProduct(int[] nums) {
+
+ int max = nums[0];
+ int iMax = nums[0];
+ int iMin = nums[0];
+
+ for (int i = 1; i < nums.length; i++) {
+ int num = nums[i];
+
+ if (num < 0) {
+ int temp = iMax;
+ iMax = iMin;
+ iMin = temp;
+ }
+
+ iMax = Math.max(num, iMax * num);
+ iMin = Math.min(num, iMin * num);
+ max = Math.max(max, iMax);
+ }
+
+ return max;
+ }
+
+ @Test
+ public void testCase() {
+
+
+ int[] nums = {2, 3, -2, 4};
+
+ System.out.println(maxProduct(nums));
+ }
+
+
+}
diff --git a/src/main/java/com/chen/algorithm/study/test152/Solution3.java b/src/main/java/com/chen/algorithm/study/test152/Solution3.java
new file mode 100644
index 0000000..043fd85
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/study/test152/Solution3.java
@@ -0,0 +1,44 @@
+package com.chen.algorithm.study.test152;
+
+import org.junit.Test;
+
+/**
+ * @author : chen weijie
+ * @Date: 2020-09-04 18:35
+ */
+public class Solution3 {
+
+
+// 5 3 -2 10
+
+ public int maxProduct(int[] nums) {
+ return digui(nums.length - 1, 1, nums, nums[0], nums[0], nums[0]);
+ }
+
+
+ public int digui(int maxLevel, int currLevel, int[] nums, int currMax, int currMin, int max) {
+
+ if (maxLevel < currLevel) {
+ return max;
+ }
+ if (nums[currLevel] > 0) {
+ currMax = Math.max(currMax * nums[currLevel], nums[currLevel]);
+ currMin = Math.min(currMin * nums[currLevel], nums[currLevel]);
+ } else {
+ currMax = Math.max(currMin * nums[currLevel], nums[currLevel]);
+ currMin = Math.min(currMax * nums[currLevel], nums[currLevel]);
+ }
+ max = Math.max(max, currMax);
+
+ return digui(maxLevel, currLevel + 1, nums, currMax, currMin, max);
+ }
+
+ @Test
+ public void testCase() {
+
+ int[] nums = {5, 3, -2, 10};
+ System.out.println(maxProduct(nums));
+ }
+
+
+}
diff --git a/src/main/java/com/chen/algorithm/study/test152/Solution4.java b/src/main/java/com/chen/algorithm/study/test152/Solution4.java
new file mode 100644
index 0000000..245ba19
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/study/test152/Solution4.java
@@ -0,0 +1,44 @@
+package com.chen.algorithm.study.test152;
+
+import org.junit.Test;
+
+/**
+ * @author : chen weijie
+ * @Date: 2020-09-04 18:35
+ */
+public class Solution4 {
+
+
+// 5 3 -2 10
+
+ public int maxProduct(int[] nums) {
+
+ int[][] dp = new int[nums.length + 1][2];
+
+ dp[0][1] = nums[0];
+ dp[0][0] = nums[0];
+ int max = nums[0];
+ for (int i = 1; i < nums.length; i++) {
+ int currVal = nums[i];
+ if (currVal > 0) {
+ dp[i][0] = Math.max(dp[i - 1][0] * currVal, currVal);
+ dp[i][1] = Math.min(dp[i - 1][1] * currVal, currVal);
+ } else {
+ dp[i][0] = Math.max(dp[i - 1][1] * currVal, currVal);
+ dp[i][1] = Math.min(dp[i - 1][0] * currVal, currVal);
+ }
+ max = Math.max(dp[i][0], max);
+ }
+ return max;
+ }
+
+
+ @Test
+ public void testCase() {
+
+ int[] nums = {5, 3, -2, 10};
+ System.out.println(maxProduct(nums));
+ }
+
+
+}
diff --git a/src/main/java/com/chen/algorithm/study/test155/Solution.java b/src/main/java/com/chen/algorithm/study/test155/Solution.java
new file mode 100644
index 0000000..cdeebee
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/study/test155/Solution.java
@@ -0,0 +1,94 @@
+package com.chen.algorithm.study.test155;
+
+import org.junit.Test;
+
+import java.util.Stack;
+
+/**
+ * https://leetcode-cn.com/problems/min-stack/solution/min-stack-fu-zhu-stackfa-by-jin407891080/
+ *
+ * @author : chen weijie
+ * @Date: 2019-11-02 16:51
+ */
+public class Solution {
+
+
+ class MinStack {
+
+
+ private Stack stack;
+
+ private Stack min_stack;
+
+ /**
+ * initialize your data structure here.
+ */
+ public MinStack() {
+ stack = new Stack<>();
+ min_stack = new Stack<>();
+ }
+
+ public void push(int x) {
+
+ stack.push(x);
+
+ if (min_stack.isEmpty() || x <= min_stack.peek()) {
+ min_stack.push(x);
+ }
+ }
+
+ public void pop() {
+
+ if (stack.pop().equals(min_stack.peek())) {
+ min_stack.pop();
+ }
+ }
+
+
+ public int top() {
+ return stack.peek();
+ }
+
+ public int getMin() {
+ return min_stack.peek();
+ }
+
+ public Stack getStack() {
+ return stack;
+ }
+
+ public void setStack(Stack stack) {
+ this.stack = stack;
+ }
+
+ public Stack getMin_stack() {
+ return min_stack;
+ }
+
+ public void setMin_stack(Stack min_stack) {
+ this.min_stack = min_stack;
+ }
+ }
+
+
+ @Test
+ public void testCase() {
+ MinStack minStack = new MinStack();
+
+ int[] array = {10, 6, 7, 2, 11};
+
+ for (int i : array) {
+ minStack.push(i);
+ }
+
+ while (!minStack.getStack().isEmpty()) {
+ System.out.println("取出元素后:" + minStack.top());
+ minStack.pop();
+ System.out.println(minStack.getMin());
+
+ }
+
+ }
+
+
+}
diff --git a/src/main/java/com/chen/algorithm/study/test160/Solution.java b/src/main/java/com/chen/algorithm/study/test160/Solution.java
new file mode 100644
index 0000000..6f48a07
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/study/test160/Solution.java
@@ -0,0 +1,67 @@
+package com.chen.algorithm.study.test160;
+
+import org.junit.Test;
+
+/**
+ * @author : chen weijie
+ * @Date: 2019-11-02 17:40
+ * @Description: zhunn 相交链表
+ */
+public class Solution {
+
+ public class ListNode {
+ int val;
+ ListNode next;
+
+ ListNode(int x) {
+ val = x;
+ next = null;
+ }
+ }
+
+
+ public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
+
+ if (headA == null || headB == null) {
+ return null;
+ }
+ ListNode a = headA;
+ ListNode b = headB;
+
+ while (a != b) {
+ a = a == null ? headB : a.next;
+ b = b == null ? headA : b.next;
+ }
+ return b;
+ }
+
+ @Test
+ public void test() {
+ ListNode l1_1 = new ListNode(4);
+ ListNode l1_2 = new ListNode(1);
+ ListNode l1_3 = new ListNode(8);
+ ListNode l1_4 = new ListNode(7);
+ ListNode l1_5 = new ListNode(5);
+
+ ListNode l2_1 = new ListNode(5);
+ ListNode l2_2 = new ListNode(0);
+ ListNode l2_3 = new ListNode(1);
+
+ l1_1.next = l1_2;
+ l1_2.next = l1_3;
+ l1_3.next = l1_4;
+ l1_4.next = l1_5;
+
+ l2_1.next = l2_2;
+ l2_2.next = l2_3;
+ l2_3.next = l1_3;
+
+ ListNode result = getIntersectionNode(l1_1, l2_1);
+
+ while (result != null) {
+ System.out.println(result.val);
+ result = result.next;
+ }
+ }
+
+}
diff --git a/src/main/java/com/chen/algorithm/study/test160/Solution1.java b/src/main/java/com/chen/algorithm/study/test160/Solution1.java
new file mode 100644
index 0000000..d2e2750
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/study/test160/Solution1.java
@@ -0,0 +1,47 @@
+package com.chen.algorithm.study.test160;
+
+/**
+ * @author : chen weijie
+ * @Date: 2020-05-03 14:42
+ */
+public class Solution1 {
+
+ public class ListNode {
+ int val;
+ ListNode next;
+
+ ListNode(int x) {
+ val = x;
+ next = null;
+ }
+ }
+
+ public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
+
+ if (headA == null || headB == null) {
+ return null;
+ }
+
+ ListNode pA = headA;
+ ListNode pB = headB;
+
+ // 每个指针都走过两个链表,要么都相等等于相交节点,要么走到最后都是null
+ while (pA != pB) {
+ if (pA == null) {
+ // 指针直接指向另一个链表,不是next指向另一个链表。因为此时pA已经是null
+ pA = headB;
+ } else {
+ pA = pA.next;
+ }
+
+ if (pB != null) {
+ pB = pB.next;
+ } else {
+ pB = headA;
+ }
+ }
+ return pB;
+ }
+
+
+}
diff --git a/src/main/java/com/chen/algorithm/study/test160/Solution2.java b/src/main/java/com/chen/algorithm/study/test160/Solution2.java
new file mode 100644
index 0000000..09c0d89
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/study/test160/Solution2.java
@@ -0,0 +1,47 @@
+package com.chen.algorithm.study.test160;
+
+/**
+ * @author : chen weijie
+ * @Date: 2019-11-02 17:40
+ */
+public class Solution2 {
+
+ public class ListNode {
+ int val;
+ ListNode next;
+
+ ListNode(int x) {
+ val = x;
+ next = null;
+ }
+ }
+
+
+ public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
+
+ if (headA == null ||headB == null){
+ return null;
+ }
+
+ ListNode pA = headA;
+ ListNode pB = headB;
+
+ while (pA != pB) {
+
+ if (pA != null) {
+ pA = pA.next;
+ } else {
+ pA = headB;
+ }
+
+ if (pB != null) {
+ pB = pB.next;
+ } else {
+ pB = headA;
+ }
+ }
+
+ return pA;
+ }
+
+}
diff --git a/src/main/java/com/chen/algorithm/study/test169/Solution.java b/src/main/java/com/chen/algorithm/study/test169/Solution.java
new file mode 100644
index 0000000..c0d007d
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/study/test169/Solution.java
@@ -0,0 +1,36 @@
+package com.chen.algorithm.study.test169;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ *
+ * https://leetcode-cn.com/problems/majority-element/solution/qiu-zhong-shu-by-leetcode-2/
+ *
+ * @author : chen weijie
+ * @Date: 2019-11-02 18:24
+ */
+public class Solution {
+
+ public int majorityElement(int[] nums) {
+
+ if (nums.length == 1) {
+ return nums[0];
+ }
+
+ Map numsMap = new HashMap<>(nums.length);
+ for (Integer num : nums) {
+ if (numsMap.containsKey(num)) {
+ int count = numsMap.get(num) + 1;
+ if (count > (nums.length / 2)) {
+ return num;
+ }
+ numsMap.put(num, count);
+ } else {
+ numsMap.put(num, 1);
+ }
+ }
+ return 0;
+ }
+
+}
diff --git a/src/main/java/com/chen/algorithm/study/test169/Solution1.java b/src/main/java/com/chen/algorithm/study/test169/Solution1.java
new file mode 100644
index 0000000..853fb35
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/study/test169/Solution1.java
@@ -0,0 +1,19 @@
+package com.chen.algorithm.study.test169;
+
+import java.util.Arrays;
+
+/**
+ *
+ * https://leetcode-cn.com/problems/majority-element/solution/qiu-zhong-shu-by-leetcode-2/
+ *
+ * @author : chen weijie
+ * @Date: 2019-11-02 18:24
+ */
+public class Solution1 {
+
+ public int majorityElement(int[] nums) {
+ Arrays.sort(nums);
+ return nums[nums.length/2];
+ }
+
+}
diff --git a/src/main/java/com/chen/algorithm/study/test17/Solution.java b/src/main/java/com/chen/algorithm/study/test17/Solution.java
new file mode 100644
index 0000000..bbf7051
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/study/test17/Solution.java
@@ -0,0 +1,71 @@
+package com.chen.algorithm.study.test17;
+
+import com.alibaba.fastjson.JSONObject;
+import org.junit.Test;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 回溯算法
+ *
+ * @author : chen weijie
+ * @Date: 2019-11-09 23:53
+ */
+public class Solution {
+
+
+ Map phone = new HashMap() {
+ {
+ put("2", "abc");
+ put("3", "def");
+ put("4", "ghi");
+ put("5", "jkl");
+ put("6", "mno");
+ put("7", "pqrs");
+ put("8", "tuv");
+ put("9", "wxyz");
+ }
+ };
+
+ List output = new ArrayList<>();
+
+
+ public void backtrack(String combination, String next_digits) {
+
+ if (next_digits.length() == 0) {
+ output.add(combination);
+ } else {
+ String digit = next_digits.substring(0, 1);
+ String letters = phone.get(digit);
+
+ for (int i = 0; i < letters.length(); i++) {
+ String letter = phone.get(digit).substring(i, i + 1);
+ backtrack(combination + letter, next_digits.substring(1));
+ }
+ }
+
+ }
+
+ public List letterCombinations(String digits) {
+ if (digits.length() != 0) {
+ backtrack("", digits);
+ }
+ return output;
+ }
+
+
+ @Test
+ public void testCase() {
+
+ String nums = "23";
+
+ System.out.println(JSONObject.toJSONString(letterCombinations(nums)));
+
+
+ }
+
+
+}
diff --git a/src/main/java/com/chen/algorithm/study/test18/Solution.java b/src/main/java/com/chen/algorithm/study/test18/Solution.java
new file mode 100644
index 0000000..f54e49c
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/study/test18/Solution.java
@@ -0,0 +1,58 @@
+package com.chen.algorithm.study.test18;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * @author : chen weijie
+ * @Date: 2020-08-30 17:15
+ */
+public class Solution {
+
+
+ public List> fourSum(int[] nums, int target) {
+
+ List> res = new ArrayList<>();
+ if (nums == null || nums.length == 0) {
+ return res;
+ }
+ Arrays.sort(nums);
+
+ for (int i = 0; i < nums.length; i++) {
+ if (i > 0 && nums[i - 1] == nums[i]) {
+ continue;
+ }
+
+ for (int j = i + 1; j < nums.length; j++) {
+
+ if (j > i + 1 && nums[j - 1] == nums[j]) {
+ continue;
+ }
+ int left = j + 1, right = nums.length - 1;
+ while (left < right) {
+ int sum = nums[i] + nums[j] + nums[left] + nums[right];
+
+ if (sum > target) {
+ right--;
+ } else if (sum < target) {
+ left++;
+ } else {
+ res.add(Arrays.asList(nums[i], nums[j], nums[left], nums[right]));
+
+ while (left < right && nums[left + 1] == nums[left]) {
+ left++;
+ }
+ while (left < right && nums[right] == nums[right - 1]) {
+ right--;
+ }
+ left++;
+ right--;
+ }
+ }
+ }
+ }
+
+ return res;
+ }
+}
diff --git a/src/main/java/com/chen/algorithm/study/test188/Solution.java b/src/main/java/com/chen/algorithm/study/test188/Solution.java
new file mode 100644
index 0000000..35782bc
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/study/test188/Solution.java
@@ -0,0 +1,79 @@
+package com.chen.algorithm.study.test188;
+
+/**
+ * https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock-iv/solution/dong-tai-gui-hua-by-liweiwei1419-4/
+ *
+ * @author : chen weijie
+ * @Date: 2020-09-06 01:37
+ */
+public class Solution {
+
+
+ public int maxProfit(int k, int[] prices) {
+
+ int len = prices.length;
+ // 特判
+ if (k == 0 || len < 2) {
+ return 0;
+ }
+ if (k >= len / 2) {
+ return greedy(prices, len);
+ }
+
+ // dp[i][j][K]:到下标为 i 的天数为止(从 0 开始),到下标为 j 的交易次数(从 0 开始)
+ // 状态为 K 的最大利润,K = 0 表示不持股,K = 1 表示持股
+ int[][][] dp = new int[len][k][2];
+
+ // 初始化:把持股的部分都设置为一个较大的负值
+ for (int i = 0; i < len; i++) {
+ for (int j = 0; j < k; j++) {
+ dp[i][j][1] = Integer.MIN_VALUE;
+ }
+ }
+
+
+ for (int i = 0; i < len; i++) {
+
+ for (int j = 0; j < k; j++) {
+ if (i == 0) {
+ dp[i][j][1] = -prices[i];
+ dp[i][j][0] = 0;
+ } else {
+ if (j == 0) {
+ dp[i][j][1] = Math.max(dp[i - 1][j][1], -prices[i]);
+ } else {
+ // 基本状态转移方程 1。
+ //分类讨论的依据依然是:昨天是否持股。
+ //
+ //(1)昨天持股,今天还持股,说明没有发生新的交易,这两天在同一个交易区间里;
+ //(2)昨天不持股,今天持股,说明开启了一次新的交易。
+ dp[i][j][1] = Math.max(dp[i - 1][j][1], dp[i - 1][j - 1][0] - prices[i]);
+ }
+ // 基本状态转移方程 2
+
+ //分类讨论的依据是:昨天是否持股。
+ //(1)昨天不持股,今天还不持股,说明没有发生新的交易;
+ //(2)昨天持股,今天不持股,说明这次交易结束了。这两种情况都在一次交易里。
+
+ dp[i][j][0] = Math.max(dp[i - 1][j][0], dp[i - 1][j][1] + prices[i]);
+ }
+ }
+ }
+ // 说明:i、j 状态都是前缀性质的,只需返回最后一个状态
+ return dp[len - 1][k - 1][0];
+ }
+
+
+ private int greedy(int[] prices, int len) {
+ // 转换为股票系列的第 2 题,使用贪心算法完成,思路是只要有利润,就交易
+ int res = 0;
+ for (int i = 1; i < len; i++) {
+ if (prices[i - 1] < prices[i]) {
+ res += prices[i] - prices[i - 1];
+ }
+ }
+ return res;
+ }
+
+
+}
diff --git a/src/main/java/com/chen/algorithm/study/test188/Solution1.java b/src/main/java/com/chen/algorithm/study/test188/Solution1.java
new file mode 100644
index 0000000..0c0d98a
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/study/test188/Solution1.java
@@ -0,0 +1,59 @@
+package com.chen.algorithm.study.test188;
+
+/**
+ * @author : chen weijie
+ * @Date: 2020-09-22 00:08
+ */
+public class Solution1 {
+
+ public int maxProfit(int k, int[] prices) {
+
+ if (prices.length < 2 || k == 0) {
+ return 0;
+ }
+
+ int length = prices.length;
+
+ if (k >= length / 2) {
+ return greedy(prices);
+ }
+
+
+ int[][][] dp = new int[length][k][2];
+
+ for (int i = 0; i < length; i++) {
+ for (int j = 0; j < k; j++) {
+ dp[i][j][1] = Integer.MIN_VALUE;
+ }
+ }
+
+ for (int i = 0; i < length; i++) {
+ for (int j = 0; j < k; j++) {
+ if (i == 0) {
+ dp[i][j][0] = 0;
+ dp[i][j][1] = -prices[i];
+ } else {
+ if (j == 0) {
+ dp[i][j][1] = Math.max(dp[i - 1][j][1], -prices[i]);
+ } else {
+ dp[i][j][1] = Math.max(dp[i - 1][j][1], dp[i - 1][j - 1][0] - prices[i]);
+ }
+ dp[i][j][0] = Math.max(dp[i - 1][j][0], dp[i - 1][j][1] + prices[i]);
+ }
+ }
+ }
+
+ return dp[length - 1][k - 1][0];
+ }
+
+ private int greedy(int[] prices) {
+ int res = 0;
+
+ for (int i = 1; i < prices.length; i++) {
+ if (prices[i] > prices[i - 1]) {
+ res += prices[i] - prices[i - 1];
+ }
+ }
+ return res;
+ }
+}
diff --git a/src/main/java/com/chen/algorithm/study/test19/Solution.java b/src/main/java/com/chen/algorithm/study/test19/Solution.java
new file mode 100644
index 0000000..a1d083b
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/study/test19/Solution.java
@@ -0,0 +1,58 @@
+package com.chen.algorithm.study.test19;
+
+/**
+ * https://leetcode-cn.com/problems/remove-nth-node-from-end-of-list/solution/shan-chu-lian-biao-de-dao-shu-di-nge-jie-dian-by-l/
+ *
+ * 正确,写的不规整
+ *
+ * @author : chen weijie
+ * @Date: 2019-11-10 00:25
+ */
+public class Solution {
+
+
+ class ListNode {
+ int val;
+ ListNode next;
+
+ ListNode(int x) {
+ val = x;
+ }
+ }
+
+ public ListNode removeNthFromEnd(ListNode head, int n) {
+ if (head == null) {
+ return null;
+ }
+ ListNode pre = head;
+ int num = 0;
+
+ while (pre != null) {
+ num++;
+ pre = pre.next;
+ }
+ if (num < n) {
+ return null;
+ }
+
+ if (num == n) {
+ head = head.next;
+ return head;
+ }
+
+
+ ListNode pre2 = head;
+ int num2 = 0;
+ while (head != null) {
+ num2++;
+ if (num2 + n == num) {
+ head.next = head.next.next;
+ return pre2;
+ }
+ head = head.next;
+ }
+ return null;
+ }
+
+
+}
diff --git a/src/main/java/com/chen/algorithm/study/test19/Solution1.java b/src/main/java/com/chen/algorithm/study/test19/Solution1.java
new file mode 100644
index 0000000..13db539
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/study/test19/Solution1.java
@@ -0,0 +1,86 @@
+package com.chen.algorithm.study.test19;
+
+import org.junit.Test;
+
+/**
+ * @author : chen weijie
+ * @Date: 2019-11-10 00:54
+ */
+public class Solution1 {
+
+
+ class ListNode {
+ int val;
+ ListNode next;
+
+ ListNode(int x) {
+ val = x;
+ }
+ }
+
+ public ListNode removeNthFromEnd(ListNode head, int n) {
+
+ ListNode dummy = new ListNode(0);
+ dummy.next = head;
+
+ System.out.println("first====" + (head == dummy.next));
+
+ ListNode first = dummy;
+ ListNode second = dummy;
+
+ // Advances first pointer so that the gap between first and second is n nodes apart
+ for (int i = 1; i <= n + 1; i++) {
+ first = first.next;
+ System.out.println("i===" + (head == dummy.next));
+ }
+
+ while (first != null) {
+ System.out.println("n===" + (head == dummy.next));
+ first = first.next;
+ second = second.next;
+ }
+ second.next = second.next.next;
+
+ System.out.println(head);
+ System.out.println(dummy.next);
+ System.out.println(head.val);
+
+// System.out.println("last====" + (head == dummy.next));
+ return dummy.next;
+ }
+
+
+ @Test
+ public void testCase() {
+
+
+ ListNode head = new ListNode(1);
+
+ ListNode head1 = new ListNode(2);
+ ListNode head2 = new ListNode(3);
+ ListNode head3 = new ListNode(4);
+ ListNode head4 = new ListNode(5);
+ head.next = head1;
+ head1.next = head2;
+ head2.next = head3;
+ head3.next = head4;
+
+
+ ListNode nextNode = new ListNode(1);
+// head.next = nextNode;
+
+
+// ListNode dummy = new ListNode(0);
+// dummy.next = head;
+//
+// System.out.println(head == dummy.next);
+
+ System.out.println(System.identityHashCode(removeNthFromEnd(nextNode, 1)));
+// System.out.println(System.identityHashCode(dummy.next));
+// System.out.println(System.identityHashCode(dummy));
+
+
+ }
+
+
+}
diff --git a/src/main/java/com/chen/algorithm/study/test19/Solution2.java b/src/main/java/com/chen/algorithm/study/test19/Solution2.java
new file mode 100644
index 0000000..4f4314c
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/study/test19/Solution2.java
@@ -0,0 +1,43 @@
+package com.chen.algorithm.study.test19;
+
+/**
+ * @author : chen weijie
+ * @Date: 2020-05-03 21:56
+ */
+public class Solution2 {
+
+
+ public class ListNode {
+ int val;
+ ListNode next;
+
+ ListNode(int x) {
+ val = x;
+ }
+ }
+
+ public ListNode getKthFromEnd(ListNode head, int k) {
+
+ if (head == null){
+ return null;
+ }
+
+ ListNode pre = new ListNode(-1);
+ pre.next = head;
+ ListNode slow = pre;
+ ListNode fast = pre;
+
+ for (int i = 0; i < k ; i++) {
+ fast = fast.next;
+ }
+
+ while (fast.next != null) {
+ fast = fast.next;
+ slow = slow.next;
+ }
+
+ slow.next = slow.next.next;
+ return pre.next;
+ }
+
+}
diff --git a/src/main/java/com/chen/algorithm/study/test19/Solution3.java b/src/main/java/com/chen/algorithm/study/test19/Solution3.java
new file mode 100644
index 0000000..6801145
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/study/test19/Solution3.java
@@ -0,0 +1,46 @@
+package com.chen.algorithm.study.test19;
+
+/**
+ * 正确,写的不规整
+ *
+ * @author : chen weijie
+ * @Date: 2019-11-10 00:25
+ */
+public class Solution3 {
+
+
+ class ListNode {
+ int val;
+ ListNode next;
+
+ ListNode(int x) {
+ val = x;
+ }
+ }
+
+ public ListNode removeNthFromEnd(ListNode head, int n) {
+
+ if (head == null){
+ return head;
+ }
+
+ ListNode pre = new ListNode(-1);
+ pre.next = head;
+
+ ListNode fast = pre;
+ ListNode slow = pre;
+
+ for (int i = 0; i < n-1; i++) {
+ fast = fast.next;
+ }
+
+ while (fast.next != null) {
+ fast = fast.next;
+ slow = slow.next;
+ }
+ slow.next = slow.next.next;
+ return pre.next;
+ }
+
+
+}
diff --git a/src/main/java/com/chen/algorithm/study/test19/Solution4.java b/src/main/java/com/chen/algorithm/study/test19/Solution4.java
new file mode 100644
index 0000000..0f7b416
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/study/test19/Solution4.java
@@ -0,0 +1,142 @@
+package com.chen.algorithm.study.test19;
+
+import org.junit.Test;
+
+import java.util.Deque;
+import java.util.LinkedList;
+
+/**
+ * @Auther: zhunn
+ * @Date: 2020/10/22 14:51
+ * @Description: 1、遍历length-n+1;2、栈、3、双指针法
+ */
+public class Solution4 {
+
+ class ListNode {
+ int val;
+ ListNode next;
+
+ public ListNode() {
+ }
+
+ public ListNode(int val) {
+ this.val = val;
+ }
+
+ public ListNode(int val, ListNode next) {
+ this.val = val;
+ this.next = next;
+ }
+ }
+
+ /**
+ * 计算链表长度并遍历
+ *
+ * @param head 头结点
+ * @param n 删除倒数第几个
+ * @return
+ */
+ public ListNode removeNthFromEnd1(ListNode head, int n) {
+ if (head == null) {
+ return head;
+ }
+
+ ListNode dummy = new ListNode(-1, head);
+ ListNode curr = dummy;
+ int len = getLength(head);
+ for (int i = 1; i < len - n + 1; i++) {
+ curr = curr.next;
+ }
+ curr.next = curr.next.next;
+
+ return dummy.next;
+ }
+
+ /**
+ * 用stack
+ *
+ * @param head 头结点
+ * @param n 删除倒数第几个
+ * @return
+ */
+ public ListNode removeNthFromEnd2(ListNode head, int n) {
+ if (head == null) {
+ return head;
+ }
+ ListNode dummy = new ListNode(-1, head);
+ Deque stack = new LinkedList<>();
+ ListNode curr = dummy;
+ while (curr != null) {
+ stack.push(curr);
+ curr = curr.next;
+ }
+
+ for (int i = 0; i < n; i++) {
+ stack.pop();
+ }
+ ListNode pre = stack.peek();
+ pre.next = pre.next.next;
+ return dummy.next;
+ }
+
+ /**
+ * 双指针法
+ *
+ * @param head 头结点
+ * @param n 删除倒数第几个
+ * @return
+ */
+ public ListNode removeNthFromEnd3(ListNode head, int n) {
+ if (head == null) {
+ return head;
+ }
+
+ ListNode dummy = new ListNode(-1, head);
+ ListNode fast = dummy;
+ ListNode slow = dummy;
+
+ for (int i = 0; i < n; i++) {
+ fast = fast.next;
+ }
+
+ while (fast.next != null) {
+ fast = fast.next;
+ slow = slow.next;
+ }
+
+ slow.next = slow.next.next;
+
+ return dummy.next;
+ }
+
+ private int getLength(ListNode head) {
+ if (head == null) {
+ return 0;
+ }
+ ListNode lenNode = head;
+ int len = 0;
+ while (lenNode != null) {
+ len++;
+ lenNode = lenNode.next;
+ }
+ return len;
+ }
+
+ @Test
+ public void test() {
+ ListNode five = new ListNode(5);
+ ListNode four = new ListNode(4, five);
+ ListNode three = new ListNode(3, four);
+ ListNode two = new ListNode(2, three);
+ ListNode head = new ListNode(1, two);
+
+ ListNode result = removeNthFromEnd3(head, 2);
+
+ ListNode a = result;
+ while (a != null) {
+ System.out.println(a.val);
+ a = a.next;
+ }
+ //System.out.println(result);
+ }
+}
diff --git a/src/main/java/com/chen/algorithm/study/test191/Solution.java b/src/main/java/com/chen/algorithm/study/test191/Solution.java
new file mode 100644
index 0000000..8dd9261
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/study/test191/Solution.java
@@ -0,0 +1,20 @@
+package com.chen.algorithm.study.test191;
+
+/**
+ * @author : chen weijie
+ * @Date: 2020-05-17 14:27
+ */
+public class Solution {
+
+ public int hammingWeight(int n) {
+ int result = 0;
+ while (n != 0) {
+ result++;
+ n &= (n - 1);
+ }
+ return result;
+ }
+
+
+
+}
diff --git a/src/main/java/com/chen/algorithm/study/test191/Solution1.java b/src/main/java/com/chen/algorithm/study/test191/Solution1.java
new file mode 100644
index 0000000..bb8299a
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/study/test191/Solution1.java
@@ -0,0 +1,35 @@
+package com.chen.algorithm.study.test191;
+
+import org.junit.Test;
+
+/**
+ * @author : chen weijie
+ * @Date: 2020-05-17 14:27
+ */
+public class Solution1 {
+
+ public int hammingWeight(int n) {
+
+ int sum = 0;
+ int mask = 1;
+ for (int i = 0; i < 32; i++) {
+ if ((n & mask) != 0) {
+ sum++;
+ }
+ mask = mask << 1;
+ }
+ return sum;
+ }
+
+ @Test
+ public void testCase(){
+
+ // 0000 1010
+ // 0000 0010
+ int count = hammingWeight(10);
+ System.out.println(count);
+
+ }
+
+
+}
diff --git a/src/main/java/com/chen/algorithm/study/test198/Solution.java b/src/main/java/com/chen/algorithm/study/test198/Solution.java
new file mode 100644
index 0000000..25e2dcc
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/study/test198/Solution.java
@@ -0,0 +1,30 @@
+package com.chen.algorithm.study.test198;
+
+import org.junit.Test;
+
+/**
+ * @author : chen weijie
+ * @Date: 2019-11-02 18:43
+ */
+public class Solution {
+
+
+ public int rob(int[] nums) {
+
+ int[] dp = new int[nums.length + 2];
+ for (int i = 0; i < nums.length; i++) {
+ dp[i + 2] = Math.max(dp[i] + nums[i], dp[i + 1]);
+ }
+ return dp[nums.length + 1];
+ }
+
+
+ @Test
+ public void testCase() {
+
+ int[] nums = {1, 2};
+ System.out.println(rob(nums));
+ }
+
+
+}
diff --git a/src/main/java/com/chen/algorithm/study/test198/Solution1.java b/src/main/java/com/chen/algorithm/study/test198/Solution1.java
new file mode 100644
index 0000000..24741d2
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/study/test198/Solution1.java
@@ -0,0 +1,28 @@
+package com.chen.algorithm.study.test198;
+
+/**
+ * @author : chen weijie
+ * @Date: 2020-09-16 17:54
+ */
+public class Solution1 {
+
+
+ public int rob(int[] nums) {
+
+
+ if (nums == null || nums.length == 0) {
+ return 0;
+ }
+
+ int[] dp = new int[nums.length];
+ dp[0] = nums[0];
+ dp[1] = Math.max(nums[0], nums[1]);
+
+ for (int i = 2; i < nums.length; i++) {
+ dp[i] = Math.max(dp[i - 2] + nums[i], dp[i - 1]);
+ }
+
+ return dp[nums.length - 1];
+ }
+
+}
diff --git a/src/main/java/com/chen/algorithm/study/test198/Solution2.java b/src/main/java/com/chen/algorithm/study/test198/Solution2.java
new file mode 100644
index 0000000..5826246
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/study/test198/Solution2.java
@@ -0,0 +1,27 @@
+package com.chen.algorithm.study.test198;
+
+/**
+ * @author : chen weijie
+ * @Date: 2020-08-23 23:55
+ */
+public class Solution2 {
+
+ public int rob(int[] nums) {
+
+ if (nums == null || nums.length == 0) {
+ return 0;
+ }
+
+ if (nums.length == 1) {
+ return nums[0];
+ }
+ int[] dp = new int[nums.length];
+ dp[0] = nums[0];
+ dp[1] = Math.max(nums[0], nums[1]);
+ for (int i = 2; i < nums.length; i++) {
+ dp[i] = Math.max(dp[i - 1], dp[i - 2] + nums[i]);
+ }
+ return dp[nums.length - 1];
+
+ }
+}
diff --git a/src/main/java/com/chen/algorithm/study/test2/ListNode.java b/src/main/java/com/chen/algorithm/study/test2/ListNode.java
index d09530b..c759bf1 100644
--- a/src/main/java/com/chen/algorithm/study/test2/ListNode.java
+++ b/src/main/java/com/chen/algorithm/study/test2/ListNode.java
@@ -3,6 +3,7 @@
/**
* @author : chen weijie
* @Date: 2019-09-02 23:06
+ * 参考 Solution3
*/
public class ListNode {
@@ -10,9 +11,16 @@ public class ListNode {
ListNode next;
+ ListNode() {
+ }
+
ListNode(int val) {
this.val = val;
}
+ ListNode(int val, ListNode next) {
+ this.val = val;
+ this.next = next;
+ }
}
diff --git a/src/main/java/com/chen/algorithm/study/test2/Solution1.java b/src/main/java/com/chen/algorithm/study/test2/Solution1.java
new file mode 100644
index 0000000..39ec5a1
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/study/test2/Solution1.java
@@ -0,0 +1,68 @@
+package com.chen.algorithm.study.test2;
+
+import org.junit.Test;
+
+/**
+ * 需要思考下,写了好久才写出来
+ * @author : chen weijie
+ * @Date: 2019-09-02 23:05
+ */
+public class Solution1 {
+
+
+ public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
+
+ ListNode dummy = new ListNode(-1);
+ ListNode p = dummy;
+
+ int carry = 0;
+
+ while (l1 != null || l2 != null || carry != 0){
+
+ if (l1 != null){
+ carry += l1.val;
+ l1 = l1.next;
+ }
+ if (l2 != null){
+ carry += l2.val;
+ l2 = l2.next;
+ }
+
+ p.next = new ListNode(carry % 10);
+ p = p.next;
+ carry = carry /10;
+ }
+ return dummy.next;
+ }
+
+
+ @Test
+ public void testCase() {
+
+ ListNode l1_1 = new ListNode(2);
+ ListNode l1_2 = new ListNode(4);
+ ListNode l1_3 = new ListNode(3);
+
+ l1_1.next = l1_2;
+ l1_2.next = l1_3;
+
+
+ ListNode l2_1 = new ListNode(5);
+ ListNode l2_2 = new ListNode(6);
+ ListNode l2_3 = new ListNode(4);
+
+ l2_1.next = l2_2;
+ l2_2.next = l2_3;
+
+
+ ListNode result = addTwoNumbers(l1_1, l2_1);
+
+ System.out.println(result.val);
+ System.out.println(result.next.val);
+ System.out.println(result.next.next.val);
+
+
+ }
+
+
+}
diff --git a/src/main/java/com/chen/algorithm/study/test2/Solution2.java b/src/main/java/com/chen/algorithm/study/test2/Solution2.java
index a472c99..d7789f6 100644
--- a/src/main/java/com/chen/algorithm/study/test2/Solution2.java
+++ b/src/main/java/com/chen/algorithm/study/test2/Solution2.java
@@ -1,5 +1,7 @@
package com.chen.algorithm.study.test2;
+import org.junit.Test;
+
/**
* @author : chen weijie
* @Date: 2019-09-07 16:16
@@ -33,8 +35,34 @@ public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
}
return dummmy.next;
}
+ @Test
+ public void testCase() {
+
+ ListNode l1_1 = new ListNode(2);
+ ListNode l1_2 = new ListNode(4);
+ ListNode l1_3 = new ListNode(3);
+
+ l1_1.next = l1_2;
+ l1_2.next = l1_3;
+
+
+ ListNode l2_1 = new ListNode(5);
+ ListNode l2_2 = new ListNode(6);
+ ListNode l2_3 = new ListNode(4);
+
+ l2_1.next = l2_2;
+ l2_2.next = l2_3;
+ ListNode result = addTwoNumbers(l1_1, l2_1);
+
+ System.out.println(result.val);
+ System.out.println(result.next.val);
+ System.out.println(result.next.next.val);
+
+
+ }
+
}
diff --git a/src/main/java/com/chen/algorithm/study/test2/Solution3.java b/src/main/java/com/chen/algorithm/study/test2/Solution3.java
new file mode 100644
index 0000000..707ed99
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/study/test2/Solution3.java
@@ -0,0 +1,68 @@
+package com.chen.algorithm.study.test2;
+
+import org.junit.Test;
+
+/**
+ * @author : chen weijie
+ * @Date: 2020-07-30 17:43
+ * @Description: zhunn 两数相加
+ */
+public class Solution3 {
+
+
+ public ListNode addTwo(ListNode a, ListNode b) {
+
+ ListNode result = new ListNode(-1);
+ ListNode curr = result;
+
+
+ int carry = 0;
+
+ while (a != null || b != null || carry != 0) {
+
+ if (a != null) {
+ carry += a.val;
+ a = a.next;
+ }
+
+ if (b != null) {
+ carry += b.val;
+ b = b.next;
+ }
+ curr.next = new ListNode(carry % 10);
+ carry = carry / 10;
+ curr = curr.next;
+ }
+ return result.next;
+ }
+
+ @Test
+ public void testCase() {
+
+ ListNode l1_1 = new ListNode(2);
+ ListNode l1_2 = new ListNode(4);
+ ListNode l1_3 = new ListNode(3);
+
+ l1_1.next = l1_2;
+ l1_2.next = l1_3;
+
+
+ ListNode l2_1 = new ListNode(5);
+ ListNode l2_2 = new ListNode(6);
+ ListNode l2_3 = new ListNode(4);
+
+ l2_1.next = l2_2;
+ l2_2.next = l2_3;
+
+
+ ListNode result = addTwo(l1_1, l2_1);
+
+ System.out.println(result.val);
+ System.out.println(result.next.val);
+ System.out.println(result.next.next.val);
+
+
+ }
+
+
+}
diff --git a/src/main/java/com/chen/algorithm/study/test20/Solution1.java b/src/main/java/com/chen/algorithm/study/test20/Solution1.java
new file mode 100644
index 0000000..6fa934a
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/study/test20/Solution1.java
@@ -0,0 +1,59 @@
+package com.chen.algorithm.study.test20;
+
+import org.junit.Test;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Stack;
+
+
+/**
+ * 错误
+ *
+ * @author : chen weijie
+ * @Date: 2019-09-05 23:10
+ */
+public class Solution1 {
+
+
+ public boolean isValid(String s) {
+
+ if (s == null) {
+ return false;
+ }
+
+ if ("".equals(s)) {
+ return true;
+ }
+
+ Map map = new HashMap<>();
+ map.put('[',']');
+ map.put('{','}');
+ map.put('(',')');
+
+ Stack stack = new Stack<>();
+
+ for (int i = 0; i < s.length(); i++) {
+ char c = s.charAt(i);
+
+ if (map.containsKey(c)){
+ stack.push(c);
+ }else {
+ if (stack.isEmpty() || map.get(stack.pop()) != c){
+ return false;
+ }
+ }
+ }
+ return stack.isEmpty();
+ }
+
+
+ @Test
+ public void testCase() {
+
+ System.out.println(isValid("(]"));
+
+ }
+
+
+}
diff --git a/src/main/java/com/chen/algorithm/study/test20/Solution2.java b/src/main/java/com/chen/algorithm/study/test20/Solution2.java
deleted file mode 100644
index 5ecad36..0000000
--- a/src/main/java/com/chen/algorithm/study/test20/Solution2.java
+++ /dev/null
@@ -1,59 +0,0 @@
-package com.chen.algorithm.study.test20;
-
-import org.junit.Test;
-
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Stack;
-
-/**
- * 初始化栈 S。
- * 一次处理表达式的每个括号。
- * 如果遇到开括号,我们只需将其推到栈上即可。这意味着我们将稍后处理它,让我们简单地转到前面的 子表达式。
- * 如果我们遇到一个闭括号,那么我们检查栈顶的元素。如果栈顶的元素是一个 相同类型的 左括号,那么我们将它从栈中弹出并继续处理。否则,这意味着表达式无效。
- * 如果到最后我们剩下的栈中仍然有元素,那么这意味着表达式无效。
- *
- * @author : chen weijie
- * @Date: 2019-09-06 00:10
- */
-public class Solution2 {
-
-
- public boolean isValid(String s) {
-
-
- Map map = new HashMap<>(3);
- map.put('{', '}');
- map.put('[', ']');
- map.put('(', ')');
-
- Stack stack = new Stack<>();
-
- char[] chars = s.toCharArray();
- for (char aChar : chars) {
- if (map.containsKey(aChar)) {
- stack.push(aChar);
- } else {
- if (stack.empty()) {
- return false;
- }
- Character c = stack.pop();
- if (aChar != (map.get(c))) {
- return false;
- }
- }
- }
- return stack.empty();
- }
-
-
- @Test
- public void testCase() {
-
- System.out.println(isValid("[](){}"));
-
-
- }
-
-
-}
diff --git a/src/main/java/com/chen/algorithm/study/test20/Solution3.java b/src/main/java/com/chen/algorithm/study/test20/Solution3.java
new file mode 100644
index 0000000..2f950fa
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/study/test20/Solution3.java
@@ -0,0 +1,49 @@
+package com.chen.algorithm.study.test20;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Stack;
+
+/**
+ * @author : chen weijie
+ * @Date: 2020-05-07 01:48
+ */
+public class Solution3 {
+
+
+ public boolean isValid(String s) {
+
+ Map map = new HashMap<>(3);
+ map.put('{', '}');
+ map.put('[', ']');
+ map.put('(', ')');
+
+ if (s == null || s.length() == 1) {
+ return false;
+ }
+
+ Stack stack = new Stack();
+
+ for (int i = 0; i < s.length(); i++) {
+ char c = s.charAt(i);
+ if (c == '(' || c == '{' || c == '[') {
+ stack.push(c);
+ } else if (c == '}') {
+ if (stack.isEmpty() || stack.pop() != '{') {
+ return false;
+ }
+ } else if (c == ']') {
+ if (stack.isEmpty() || stack.pop() != '[') {
+ return false;
+ }
+ } else if (c == ')') {
+
+ if (stack.isEmpty() || stack.pop() != '(') {
+ return false;
+ }
+ }
+ }
+ return stack.isEmpty();
+ }
+
+}
diff --git a/src/main/java/com/chen/algorithm/study/test206/Solution3.java b/src/main/java/com/chen/algorithm/study/test206/Solution3.java
index a16cc68..472b616 100644
--- a/src/main/java/com/chen/algorithm/study/test206/Solution3.java
+++ b/src/main/java/com/chen/algorithm/study/test206/Solution3.java
@@ -15,14 +15,37 @@ public ListNode reverseList(ListNode head) {
return head;
}
- ListNode pre = null;
+ ListNode dummy = new ListNode(-1);
+ dummy.next = head;
while (head != null) {
ListNode temp = head.next;
- head.next = pre;
- pre = head;
+ head.next = dummy;
+ dummy = head;
head = temp;
}
- return pre;
+ return dummy;
+ }
+
+
+ // 检测环
+ public static boolean checkCircle(ListNode list) {
+ if (list == null) {
+ return false;
+ }
+
+ ListNode fast = list.next;
+ ListNode slow = list;
+
+ while (fast != null && fast.next != null) {
+ fast = fast.next.next;
+ slow = slow.next;
+
+ if (slow == fast) {
+ return true;
+ }
+ }
+
+ return false;
}
@Test
diff --git a/src/main/java/com/chen/algorithm/study/test206/Solution4.java b/src/main/java/com/chen/algorithm/study/test206/Solution4.java
new file mode 100644
index 0000000..e893d25
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/study/test206/Solution4.java
@@ -0,0 +1,32 @@
+package com.chen.algorithm.study.test206;
+
+/**
+ * @author : chen weijie
+ * @Date: 2019-11-28 18:06
+ */
+public class Solution4 {
+
+
+ public void solution(ListNode head) {
+
+ if (head == null) {
+ return;
+ }
+
+
+ ListNode pre = null;
+
+ while (head != null) {
+
+ ListNode temp = head.next;
+ head.next = pre;
+ pre = head;
+ head = temp;
+
+ }
+
+
+ }
+
+
+}
diff --git a/src/main/java/com/chen/algorithm/study/test206/Solution5.java b/src/main/java/com/chen/algorithm/study/test206/Solution5.java
new file mode 100644
index 0000000..3e4e9de
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/study/test206/Solution5.java
@@ -0,0 +1,72 @@
+package com.chen.algorithm.study.test206;
+
+import org.junit.Test;
+
+/**
+ * @Auther: zhunn
+ * @Date: 2020/10/22 17:23
+ * @Description: 反转链表:1-迭代法,2-递归
+ */
+public class Solution5 {
+
+ class ListNode {
+ int val;
+ ListNode next;
+
+ public ListNode() {
+ }
+
+ public ListNode(int val) {
+ this.val = val;
+ }
+
+ public ListNode(int val, ListNode next) {
+ this.val = val;
+ this.next = next;
+ }
+
+ }
+
+ public ListNode reverseList1(ListNode head) {
+ if (head == null || head.next == null) {
+ return head;
+ }
+
+ ListNode pre = null;
+ ListNode curr = head;
+ while (curr != null) {
+ ListNode nextTemp = curr.next;
+ curr.next = pre;
+ pre = curr;
+ curr = nextTemp;
+ }
+
+ return pre;
+ }
+
+ public ListNode reverseList2(ListNode head){
+ if(head == null || head.next == null){
+ return head;
+ }
+ ListNode p = reverseList2(head.next);
+ head.next.next = head;
+ head.next = null;
+ return p;
+ }
+
+ @Test
+ public void test() {
+ ListNode l1_4 = new ListNode(18);
+ ListNode l1_3 = new ListNode(9, l1_4);
+ ListNode l1_2 = new ListNode(6, l1_3);
+ ListNode l1_1 = new ListNode(7, l1_2);
+
+ ListNode result = reverseList2(l1_1);
+ System.out.println(result.val);
+ System.out.println(result.next.val);
+ System.out.println(result.next.next.val);
+ System.out.println(result.next.next.next.val);
+ }
+
+
+}
diff --git a/src/main/java/com/chen/algorithm/study/test206/SolutionTest.java b/src/main/java/com/chen/algorithm/study/test206/SolutionTest.java
index bb0f2c8..ba5daae 100644
--- a/src/main/java/com/chen/algorithm/study/test206/SolutionTest.java
+++ b/src/main/java/com/chen/algorithm/study/test206/SolutionTest.java
@@ -1,7 +1,5 @@
package com.chen.algorithm.study.test206;
-import org.junit.Test;
-
/**
* @author : chen weijie
* @Date: 2019-09-08 01:38
@@ -9,26 +7,24 @@
public class SolutionTest {
- public ListNode reverseList(ListNode head) {
+ public static ListNode reverseList(ListNode head) {
if (head == null || head.next == null) {
return head;
}
- ListNode prev = null;
- ListNode temp;
+ ListNode pre = null;
while (head != null) {
- temp = head.next;
- head.next = prev;
- prev = head;
+ ListNode temp = head.next;
+ head.next = pre;
+ pre = head;
head = temp;
}
- return prev;
+ return pre;
}
- @Test
- public void testCase() {
+ public static void main(String[] args) {
ListNode l1_1 = new ListNode(4);
ListNode l1_2 = new ListNode(6);
ListNode l1_3 = new ListNode(10);
@@ -43,3 +39,13 @@ public void testCase() {
}
}
+
+class ListNode {
+
+ int val;
+ ListNode next;
+
+ ListNode(int x) {
+ val = x;
+ }
+}
diff --git a/src/main/java/com/chen/algorithm/study/test208/Trie.java b/src/main/java/com/chen/algorithm/study/test208/Trie.java
new file mode 100644
index 0000000..43a4bd7
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/study/test208/Trie.java
@@ -0,0 +1,85 @@
+package com.chen.algorithm.study.test208;
+
+/**
+ * @author : chen weijie
+ * @Date: 2020-09-02 01:19
+ */
+public class Trie {
+
+
+
+ public TrieNode root;
+
+ /**
+ * Initialize your data structure here.
+ */
+ public Trie() {
+ root = new TrieNode();
+ root.val = ' ';
+ }
+
+
+ /**
+ * Inserts a word into the trie.
+ */
+ public void insert(String word) {
+ TrieNode ws = root;
+ for (int i = 0; i < word.length(); i++) {
+ char c = word.charAt(i);
+ if (ws.children[c - 'a'] == null) {
+ ws.children[c - 'a'] = new TrieNode(c);
+ }
+ ws = ws.children[c - 'a'];
+ }
+ ws.isWorld = true;
+ }
+
+ /**
+ * Returns if the word is in the trie.
+ */
+ public boolean search(String word) {
+
+ TrieNode ws = root;
+ for (int i = 0; i < word.length(); i++) {
+ char c = word.charAt(i);
+ if (ws.children[c - 'a'] == null) {
+ return false;
+ }
+ ws = ws.children[c - 'a'];
+ }
+
+ return ws.isWorld;
+ }
+
+ /**
+ * Returns if there is any word in the trie that starts with the given prefix.
+ */
+ public boolean startsWith(String prefix) {
+ TrieNode ws = root;
+ for (int i = 0; i < prefix.length(); i++) {
+ char c = prefix.charAt(i);
+ if (ws.children[c - 'a'] == null) {
+ return false;
+ }
+ ws = ws.children[c - 'a'];
+ }
+ return true;
+ }
+
+
+
+ class TrieNode {
+ public char val;
+ public boolean isWorld;
+ public TrieNode[] children = new TrieNode[26];
+
+ public TrieNode() {
+ }
+
+ TrieNode(char c) {
+ TrieNode node = new TrieNode();
+ node.val = c;
+ }
+ }
+
+}
diff --git a/src/main/java/com/chen/algorithm/study/test21/ListNode.java b/src/main/java/com/chen/algorithm/study/test21/ListNode.java
index 0d1e6fa..1b81f36 100644
--- a/src/main/java/com/chen/algorithm/study/test21/ListNode.java
+++ b/src/main/java/com/chen/algorithm/study/test21/ListNode.java
@@ -3,6 +3,7 @@
/**
* @author : chen weijie
* @Date: 2019-09-06 00:35
+ * 参考 Solution3
*/
public class ListNode {
@@ -10,8 +11,16 @@ public class ListNode {
ListNode next;
- public ListNode(int val) {
+ ListNode() {
+ }
+
+ ListNode(int val) {
+ this.val = val;
+ }
+
+ ListNode(int val, ListNode next) {
this.val = val;
+ this.next = next;
}
diff --git a/src/main/java/com/chen/algorithm/study/test21/Solution3.java b/src/main/java/com/chen/algorithm/study/test21/Solution3.java
index dc8c4b3..8a94756 100644
--- a/src/main/java/com/chen/algorithm/study/test21/Solution3.java
+++ b/src/main/java/com/chen/algorithm/study/test21/Solution3.java
@@ -5,6 +5,7 @@
/**
* @author : chen weijie
* @Date: 2019-09-06 01:43
+ * @Description: zhunn 合并两个有序链表
*/
public class Solution3 {
@@ -52,7 +53,7 @@ public void testCase(){
l2_2.next = l2_3;
- ListNode result = mergeTwoLists(l1_1, l2_1);
+ ListNode result = merge(l1_1, l2_1);
System.out.println(result.val);
System.out.println(result.next.val);
@@ -62,4 +63,40 @@ public void testCase(){
System.out.println(result.next.next.next.next.next.val);
}
+
+ public static ListNode merge(ListNode a, ListNode b) {
+ // TODO
+ if(a == null){
+ return b;
+ }
+
+ if(b == null){
+ return a;
+ }
+
+ ListNode pre = new ListNode(-1);
+ ListNode dummy = pre;
+
+ while(a !=null && b !=null){
+
+ if(a.val <= b.val){
+ pre.next = a;
+ a = a.next;
+ }else{
+ pre.next = b;
+ b = b.next;
+ }
+ pre =pre.next;
+ }
+
+ if(a == null){
+ pre.next = b;
+ }
+
+ if(b == null){
+ pre.next = a;
+ }
+ return dummy.next;
+ }
+
}
diff --git a/src/main/java/com/chen/algorithm/study/test215/KthLargest.java b/src/main/java/com/chen/algorithm/study/test215/KthLargest.java
new file mode 100644
index 0000000..9742485
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/study/test215/KthLargest.java
@@ -0,0 +1,35 @@
+package com.chen.algorithm.study.test215;
+
+import java.util.PriorityQueue;
+
+/**
+ * @author : chen weijie
+ * @Date: 2020-05-04 16:37
+ */
+public class KthLargest {
+
+
+ public PriorityQueue queue = null;
+ private Integer limit = null;
+
+
+ public KthLargest(int k, int[] nums) {
+ limit = k;
+ queue = new PriorityQueue<>(k);
+ for (int num : nums) {
+ add(num);
+ }
+ }
+
+ public int add(int val) {
+ if (queue.size() < limit) {
+ queue.add(val);
+ } else if (val > queue.peek()) {
+ queue.poll();
+ queue.add(val);
+ }
+ return queue.peek();
+ }
+
+
+}
diff --git a/src/main/java/com/chen/algorithm/study/test215/Solution.java b/src/main/java/com/chen/algorithm/study/test215/Solution.java
new file mode 100644
index 0000000..066a6ba
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/study/test215/Solution.java
@@ -0,0 +1,38 @@
+package com.chen.algorithm.study.test215;
+
+import org.junit.Test;
+
+/**
+ * @author : chen weijie
+ * @Date: 2019-12-12 23:50
+ */
+public class Solution {
+
+
+ public int findKthLargest(int[] nums, int k) {
+
+
+ for (int i = 0; i < nums.length; i++) {
+
+ for (int j = 1; j < nums.length ; j++) {
+
+ if (nums[j] > nums[j - 1]) {
+ int temp = nums[j - 1];
+ nums[j - 1] = nums[j];
+ nums[j] = temp;
+ }
+ }
+ }
+ return nums[k - 1];
+ }
+
+
+ @Test
+ public void testCase() {
+ int[] n = {3, 2, 3, 1, 2, 4, 5, 5, 6};
+ System.out.println(findKthLargest(n, 4));
+
+ }
+
+
+}
diff --git a/src/main/java/com/chen/algorithm/study/test22/Solution.java b/src/main/java/com/chen/algorithm/study/test22/Solution.java
new file mode 100644
index 0000000..fb1664f
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/study/test22/Solution.java
@@ -0,0 +1,51 @@
+package com.chen.algorithm.study.test22;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @author : chen weijie
+ * @Date: 2019-11-10 02:20
+ */
+public class Solution {
+
+
+ public List generateParenthesis(int n) {
+ List combinations = new ArrayList();
+ generateAll(new char[2 * n], 0, combinations);
+ return combinations;
+
+ }
+
+
+ public void generateAll(char[] current, int pos, List result) {
+ if (pos == current.length) {
+ if (valid(current)) {
+ result.add(new String(current));
+ }
+ } else {
+ current[pos] = '(';
+ generateAll(current, pos + 1, result);
+ current[pos] = ')';
+ generateAll(current, pos + 1, result);
+ }
+ }
+
+
+ public boolean valid(char[] current) {
+ int balance = 0;
+ for (char c : current) {
+ if (c == '(') {
+ balance++;
+ } else {
+ balance--;
+ }
+ if (balance < 0) {
+ return false;
+ }
+ }
+ return (balance == 0);
+ }
+
+
+}
diff --git a/src/main/java/com/chen/algorithm/study/test22/Solution1.java b/src/main/java/com/chen/algorithm/study/test22/Solution1.java
new file mode 100644
index 0000000..792013c
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/study/test22/Solution1.java
@@ -0,0 +1,45 @@
+package com.chen.algorithm.study.test22;
+
+import org.junit.Test;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @author : chen weijie
+ * @Date: 2019-11-10 02:20
+ */
+public class Solution1 {
+
+
+ public List generateParenthesis(int n) {
+
+ List res = new ArrayList<>();
+ generateAll("", n, n, res);
+ return res;
+ }
+
+
+ public void generateAll(String current, int left, int right, List result) {
+
+ if (left == 0 && right == 0) {
+ result.add(current);
+ return;
+ }
+
+ if (left > 0) {
+ generateAll(current + "(", left - 1, right, result);
+ }
+
+ if (right > 0 && right > left) {
+ generateAll(current + ")", left, right - 1, result);
+ }
+ }
+
+ @Test
+ public void testCase(){
+ generateParenthesis(3).stream().forEach(System.out::println);
+ }
+
+
+}
diff --git a/src/main/java/com/chen/algorithm/study/test22/Solution2.java b/src/main/java/com/chen/algorithm/study/test22/Solution2.java
new file mode 100644
index 0000000..4ab73c6
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/study/test22/Solution2.java
@@ -0,0 +1,49 @@
+package com.chen.algorithm.study.test22;
+
+import org.junit.Test;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @author : chen weijie
+ * @Date: 2020-05-17 02:17
+ */
+public class Solution2 {
+
+ public List generateParenthesis(int n) {
+ List combinations = new ArrayList();
+ generationOneByOne("", combinations, n, n);
+ return combinations;
+
+ }
+
+ /**
+ * @param subList 子字符串
+ * @param result
+ * @param left 左括号还剩多少个
+ * @param right 右括号还剩多少个
+ */
+ public void generationOneByOne(String subList, List result, int left, int right) {
+ if (left == 0 && right == 0) {
+ result.add(subList);
+ return;
+ }
+
+ if (left > 0) {
+ generationOneByOne(subList + "(", result, left-1, right);
+ }
+
+ // 子字符串中肯定是左括号多余右括号的
+ if (right > 0 && right > left) {
+ generationOneByOne(subList + ")", result, left, right-1);
+ }
+ }
+
+ @Test
+ public void testCase(){
+ generateParenthesis(3).stream().forEach(System.out::println);
+ }
+
+
+}
diff --git a/src/main/java/com/chen/algorithm/study/test225/MyStack.java b/src/main/java/com/chen/algorithm/study/test225/MyStack.java
new file mode 100644
index 0000000..f3e8725
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/study/test225/MyStack.java
@@ -0,0 +1,57 @@
+package com.chen.algorithm.study.test225;
+
+import java.util.LinkedList;
+import java.util.Queue;
+
+/**
+ * @author : chen weijie
+ * @Date: 2020-05-04 15:56
+ */
+public class MyStack {
+
+
+ private Queue q1;
+ private Queue q2;
+ private int top;
+
+
+ /** Initialize your data structure here. */
+ public MyStack() {
+ q1 = new LinkedList<>();
+ q2 = new LinkedList<>();
+ }
+
+ /** Push element x onto stack. */
+ public void push(int x) {
+ q1.add(x);
+ top = x;
+ }
+
+ /**
+ * Removes the element on top of the stack and returns that element.
+ */
+ public int pop() {
+ while (q1.size() > 1) {
+ q2.add(q1.peek());
+ top = q1.remove();
+ }
+ int result = q1.remove();
+ Queue temp = q1;
+ q1 = q2;
+ q2 = temp;
+ return result;
+ }
+
+ /** Get the top element. */
+ public int top() {
+ return top;
+ }
+
+ /**
+ * Returns whether the stack is empty.
+ */
+ public boolean empty() {
+ return q1.isEmpty() && q2.isEmpty();
+ }
+
+}
diff --git a/src/main/java/com/chen/algorithm/study/test226/Solution.java b/src/main/java/com/chen/algorithm/study/test226/Solution.java
new file mode 100644
index 0000000..0546fd8
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/study/test226/Solution.java
@@ -0,0 +1,55 @@
+package com.chen.algorithm.study.test226;
+
+/**
+ * @author : chen weijie
+ * @Date: 2019-11-03 17:33
+ */
+public class Solution {
+
+
+ class TreeNode {
+
+ int val;
+ TreeNode left;
+ TreeNode right;
+
+ TreeNode(int val) {
+ this.val = val;
+ }
+ }
+
+ public TreeNode invertTree(TreeNode root) {
+
+ if (root == null) {
+ return null;
+ }
+
+ if (root.right == null && root.left == null) {
+ return root;
+ }
+
+
+ if (root.left != null) {
+ invertTree(root.left);
+ }
+
+ if (root.right != null) {
+ invertTree(root.right);
+ }
+
+ TreeNode temp = root.right;
+ root.right = root.left;
+ root.left = temp;
+ return root;
+ }
+
+
+
+
+
+
+
+
+
+
+}
diff --git a/src/main/java/com/chen/algorithm/study/test226/Solution2.java b/src/main/java/com/chen/algorithm/study/test226/Solution2.java
new file mode 100644
index 0000000..2a6e60b
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/study/test226/Solution2.java
@@ -0,0 +1,56 @@
+package com.chen.algorithm.study.test226;
+
+import java.util.LinkedList;
+import java.util.Queue;
+
+/**
+ * @author : chen weijie
+ * @Date: 2020-08-03 23:01
+ */
+public class Solution2 {
+
+ class TreeNode {
+
+ int val;
+ TreeNode left;
+ TreeNode right;
+
+ TreeNode(int val) {
+ this.val = val;
+ }
+ }
+
+ public TreeNode revertTree(TreeNode root) {
+
+
+ if (root == null) {
+ return root;
+ }
+
+ Queue queue = new LinkedList<>();
+ queue.add(root);
+
+ while (!queue.isEmpty()) {
+
+ int size = queue.size();
+
+ for (int i = 0; i < size; i++) {
+ TreeNode node = queue.remove();
+ TreeNode temp = node.left;
+ node.left = node.right;
+ node.right = temp;
+
+ if (node.left != null) {
+ queue.add(node.left);
+ }
+
+ if (node.right != null) {
+ queue.add(node.right);
+ }
+ }
+ }
+ return root;
+ }
+
+
+}
diff --git a/src/main/java/com/chen/algorithm/study/test227/Solution.java b/src/main/java/com/chen/algorithm/study/test227/Solution.java
new file mode 100644
index 0000000..77133b3
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/study/test227/Solution.java
@@ -0,0 +1,72 @@
+package com.chen.algorithm.study.test227;
+
+import org.junit.Test;
+
+import java.util.Stack;
+
+/**
+ * @author : chen weijie
+ * @Date: 2020-08-05 15:50
+ */
+public class Solution {
+
+
+ public void vert() {
+ String s = "458";
+ int n = 0;
+ for (char c : s.toCharArray()) {
+ n = n * 10 + (c - '0');
+ }
+ System.out.println(n);
+ }
+
+
+ public int calculate(String s) {
+
+ char sign = '+';
+ Stack stack = new Stack<>();
+ int num = 0;
+ for (int i = 0; i < s.length(); i++) {
+ char c = s.charAt(i);
+ // 如果是数字,连续读取到 num
+ if (Character.isDigit(c)) {
+ num = num * 10 + (c - '0');
+ }
+
+ // 如果不是数字,就是遇到了下一个符号,或者等于最后一个字符
+ // 之前的数字和符号就要存进栈中
+ if ((!Character.isDigit(c) && c != ' ') || i == s.length() - 1) {
+ int pre;
+ if (sign == '+') {
+ stack.push(num);
+ } else if (sign == '-') {
+ stack.push(-num);
+ } else if (sign == '*') {
+ pre = stack.pop();
+ stack.push(pre * num);
+ } else if (sign == '/') {
+ pre = stack.pop();
+ stack.push(pre / num);
+ }
+ // 更新符号为当前符号,数字清零
+ sign = c;
+ num = 0;
+ }
+ }
+
+ int res = 0;
+ while (!stack.isEmpty()) {
+ res += stack.pop();
+ }
+
+ return res;
+ }
+
+
+ @Test
+ public void testCase() {
+ System.out.println(calculate("-30+5/2 "));
+ }
+
+
+}
diff --git a/src/main/java/com/chen/algorithm/study/test227/Solution1.java b/src/main/java/com/chen/algorithm/study/test227/Solution1.java
new file mode 100644
index 0000000..7ee0be6
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/study/test227/Solution1.java
@@ -0,0 +1,50 @@
+package com.chen.algorithm.study.test227;
+
+import java.util.Stack;
+
+/**
+ * @author : chen weijie
+ * @Date: 2020-09-21 23:32
+ */
+public class Solution1 {
+
+
+ public int calculate(String s) {
+ char sign = '+';
+ Stack stack = new Stack<>();
+ int num = 0;
+
+ for (int i = 0; i < s.length(); i++) {
+ char c = s.charAt(i);
+
+ if (Character.isDigit(c)) {
+ num = num * 10 + (c - '0');
+ }
+
+ if ((!Character.isDigit(c) && c != ' ') || i == s.length() - 1) {
+
+ if (sign == '+') {
+ stack.push(num);
+ } else if (sign == '-') {
+ stack.push(-num);
+ } else if (sign == '/') {
+ Integer pre = stack.pop();
+ stack.push(pre / num);
+ } else if (sign == '*') {
+ Integer pre = stack.pop();
+ stack.push(pre * num);
+ }
+ sign = c;
+ num = 0;
+ }
+ }
+
+ int res = 0;
+
+ while (!stack.isEmpty()) {
+ res += stack.pop();
+ }
+
+ return res;
+ }
+}
diff --git a/src/main/java/com/chen/algorithm/study/test227/Solution2.java b/src/main/java/com/chen/algorithm/study/test227/Solution2.java
new file mode 100644
index 0000000..1901e9f
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/study/test227/Solution2.java
@@ -0,0 +1,71 @@
+package com.chen.algorithm.study.test227;
+
+import org.junit.Test;
+
+import java.util.Stack;
+
+/**
+ * @author : chen weijie
+ * @Date: 2020-08-05 15:50
+ */
+public class Solution2 {
+
+
+ public void vert() {
+ String s = "458";
+ int n = 0;
+ for (char c : s.toCharArray()) {
+ n = n * 10 + (c - '0');
+ }
+ System.out.println(n);
+ }
+
+
+ public int calculate(String s) {
+ int res = 0;
+ char sign = '+';
+
+ if (s == null || s.length() == 0){
+ return 0;
+ }
+ int num = 0;
+ Stack stack = new Stack<>();
+
+ for (int i = 0; i < s.length(); i++) {
+ char c = s.charAt(i);
+
+ if ( Character.isDigit(c)){
+ num = num * 10 + (c - '0');
+ }
+
+ if ((!Character.isDigit(c) && c != ' ') || i == s.length() - 1){
+ if (sign == '+') {
+ stack.push(num);
+ } else if (sign == '-') {
+ stack.push(-num);
+ } else if (sign == '*') {
+ int pre = stack.pop();
+ stack.push(pre * num);
+ } else if (sign == '/') {
+ int pre = stack.pop();
+ stack.push(pre / num);
+ }
+ sign = c;
+ num = 0;
+ }
+ }
+
+ while (!stack.isEmpty()){
+ res += stack.pop();
+ }
+ return res;
+ }
+
+
+ @Test
+ public void testCase() {
+ System.out.println(calculate("-30+5/2 "));
+ }
+
+
+}
diff --git a/src/main/java/com/chen/algorithm/study/test231/Solution.java b/src/main/java/com/chen/algorithm/study/test231/Solution.java
new file mode 100644
index 0000000..4040a76
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/study/test231/Solution.java
@@ -0,0 +1,21 @@
+package com.chen.algorithm.study.test231;
+
+/**
+ * @author : chen weijie
+ * @Date: 2020-05-17 17:45
+ */
+public class Solution {
+
+ public boolean isPowerOfTwo(int n) {
+
+ if (n == 0) {
+ return false;
+ }
+
+ while (n % 2 == 0) {
+ n = n / 2;
+ }
+
+ return n == 1;
+ }
+}
diff --git a/src/main/java/com/chen/algorithm/study/test231/Solution2.java b/src/main/java/com/chen/algorithm/study/test231/Solution2.java
new file mode 100644
index 0000000..5c4f565
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/study/test231/Solution2.java
@@ -0,0 +1,29 @@
+package com.chen.algorithm.study.test231;
+
+/**
+ *
+ * https://leetcode-cn.com/problems/power-of-two/solution/2de-mi-by-leetcode/
+ *
+ * 如何获取二进制中最右边的 1:x & (-x)。
+ * 如何将二进制中最右边的 1 设置为 0:x & (x - 1)。
+ *
+ *
+ * 2 的幂二进制表示只含有一个 1。
+ * x & (x - 1) 操作会将 2 的幂设置为 0,因此判断是否为 2 的幂是:判断 x & (x - 1) == 0。
+ *
+ *
+ * @author : chen weijie
+ * @Date: 2020-05-17 17:45
+ */
+public class Solution2 {
+
+ public boolean isPowerOfTwo(int n) {
+
+ if (n == 0) {
+ return false;
+ }
+
+ return (n & (n - 1)) == 0;
+
+ }
+}
diff --git a/src/main/java/com/chen/algorithm/study/test232/StackForQueen.java b/src/main/java/com/chen/algorithm/study/test232/StackForQueen.java
new file mode 100644
index 0000000..f31b778
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/study/test232/StackForQueen.java
@@ -0,0 +1,41 @@
+package com.chen.algorithm.study.test232;
+
+import java.util.Stack;
+
+/**
+ * @author : chen weijie
+ * @Date: 2020-04-28 18:29
+ */
+public class StackForQueen {
+
+
+ private Stack stack1 = new Stack<>();
+
+ private Stack stack2 = new Stack<>();
+
+
+ public void push(Integer value) {
+ stack1.push(value);
+ }
+
+
+ public Integer pop() {
+
+ if (stack2.isEmpty() && stack1.isEmpty()) {
+ return null;
+ }
+
+
+ if (stack2.isEmpty()) {
+ while (!stack1.isEmpty()) {
+ stack2.push(stack1.pop());
+ }
+ }
+
+ return stack2.pop();
+
+
+ }
+
+
+}
diff --git a/src/main/java/com/chen/algorithm/study/test234/Solution.java b/src/main/java/com/chen/algorithm/study/test234/Solution.java
new file mode 100644
index 0000000..0ad56bd
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/study/test234/Solution.java
@@ -0,0 +1,44 @@
+package com.chen.algorithm.study.test234;
+
+/**
+ * @author : chen weijie
+ * @Date: 2019-11-03 17:58
+ */
+public class Solution {
+
+
+ class ListNode {
+ int val;
+ ListNode next;
+
+ ListNode(int x) {
+ val = x;
+ }
+ }
+
+ public boolean isPalindrome(ListNode head) {
+
+ ListNode p1 = head;
+ int size = 0;
+ for (int i = 1; p1 != null; p1 = p1.next, i++) {
+ size = i;
+ }
+
+ int[] a = new int[size];
+
+ for (int i = 0; head != null; head = head.next, i++) {
+ a[i] = head.val;
+ }
+
+ int j = size;
+
+ for (int i = 0; i < size / 2; i++, j--) {
+ if (a[i] != a[j - 1]) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+}
diff --git a/src/main/java/com/chen/algorithm/study/test234/Solution1.java b/src/main/java/com/chen/algorithm/study/test234/Solution1.java
new file mode 100644
index 0000000..69dd864
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/study/test234/Solution1.java
@@ -0,0 +1,61 @@
+package com.chen.algorithm.study.test234;
+
+/**
+ * https://leetcode-cn.com/problems/palindrome-linked-list/solution/ji-bai-liao-bai-fen-zhi-97de-javayong-hu-by-reedfa/
+ *
+ * @author : chen weijie
+ * @Date: 2019-11-03 17:58
+ */
+public class Solution1 {
+
+
+ class ListNode {
+ int val;
+ ListNode next;
+
+ ListNode(int x) {
+ val = x;
+ }
+ }
+
+ public boolean isPalindrome(ListNode head) {
+
+ if (head == null || head.next == null) {
+ return true;
+ }
+
+ // 快慢指针找到链表的中点
+ ListNode fast = head.next.next;
+ ListNode slow = head.next;
+
+ while (fast != null && fast.next != null) {
+ fast = fast.next.next;
+ slow = slow.next;
+ }
+
+ // 反转链表的前半部分,从上述的算数中,中点此时为slow;
+ ListNode pre = null;
+ while (head != slow) {
+ ListNode next = head.next;
+ head.next = pre;
+ pre = head;
+ head = next;
+ }
+
+ //如果是奇数个节点,去掉后半部分的第一个节点。
+ if (fast != null) {
+ slow = slow.next;
+ }
+
+ // 回文校验
+ while (pre != null) {
+ if (pre.val != slow.val) {
+ return false;
+ }
+ pre = pre.next;
+ slow = slow.next;
+ }
+ return true;
+ }
+
+}
diff --git a/src/main/java/com/chen/algorithm/study/test235/Solution.java b/src/main/java/com/chen/algorithm/study/test235/Solution.java
new file mode 100644
index 0000000..b43814c
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/study/test235/Solution.java
@@ -0,0 +1,32 @@
+package com.chen.algorithm.study.test235;
+
+/**
+ * @author : chen weijie
+ * @Date: 2020-08-30 23:13
+ */
+public class Solution {
+
+
+ class TreeNode {
+ int val;
+ TreeNode left;
+ TreeNode right;
+
+ TreeNode(int x) {
+ val = x;
+ }
+ }
+
+ public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
+
+ if (p.val < root.val && q.val < root.val) {
+ return lowestCommonAncestor(root.left, p, q);
+ }
+
+ if (p.val > root.val && q.val > root.val) {
+ return lowestCommonAncestor(root.right, p, q);
+ }
+
+ return root;
+ }
+}
diff --git a/src/main/java/com/chen/algorithm/study/test235/Solution2.java b/src/main/java/com/chen/algorithm/study/test235/Solution2.java
new file mode 100644
index 0000000..987e8fb
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/study/test235/Solution2.java
@@ -0,0 +1,35 @@
+package com.chen.algorithm.study.test235;
+
+/**
+ * @author : chen weijie
+ * @Date: 2020-08-30 23:02
+ */
+public class Solution2 {
+
+ class TreeNode {
+ int val;
+ TreeNode left;
+ TreeNode right;
+
+ TreeNode(int x) {
+ val = x;
+ }
+ }
+
+ public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
+
+ while (root != null) {
+
+ if (p.val < root.val && q.val < root.val) {
+ root = root.left;
+ } else if (p.val > root.val && q.val > root.val) {
+ root = root.right;
+ } else {
+ return root;
+ }
+ }
+ return root;
+ }
+
+
+}
diff --git a/src/main/java/com/chen/algorithm/study/test236/Solution.java b/src/main/java/com/chen/algorithm/study/test236/Solution.java
new file mode 100644
index 0000000..9a852a6
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/study/test236/Solution.java
@@ -0,0 +1,44 @@
+package com.chen.algorithm.study.test236;
+
+/**
+ * @author : chen weijie
+ * @Date: 2020-08-30 23:02
+ */
+public class Solution {
+
+ class TreeNode {
+ int val;
+ TreeNode left;
+ TreeNode right;
+
+ TreeNode(int x) {
+ val = x;
+ }
+ }
+
+ public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
+
+ if (root == null) {
+ return root;
+ }
+
+ if (root == p || root == q) {
+ return root;
+ }
+
+ TreeNode left = lowestCommonAncestor(root.left, p, q);
+ TreeNode right = lowestCommonAncestor(root.right, p, q);
+
+ if (left == null) {
+ return right;
+ }
+
+ if (right == null) {
+ return left;
+ }
+
+ return root;
+ }
+
+
+}
diff --git a/src/main/java/com/chen/algorithm/study/test238/Solution.java b/src/main/java/com/chen/algorithm/study/test238/Solution.java
new file mode 100644
index 0000000..e8a6b3e
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/study/test238/Solution.java
@@ -0,0 +1,43 @@
+package com.chen.algorithm.study.test238;
+
+import com.alibaba.fastjson.JSONObject;
+import org.junit.Test;
+
+/**
+ * https://leetcode-cn.com/problems/product-of-array-except-self/solution/cheng-ji-dang-qian-shu-zuo-bian-de-cheng-ji-dang-q/
+ *
+ * @author : chen weijie
+ * @Date: 2019-12-13 00:39
+ */
+public class Solution {
+
+ public int[] productExceptSelf(int[] nums) {
+
+ int[] res = new int[nums.length];
+ int k = 1;
+ for (int i = 0; i < nums.length; i++) {
+ res[i] = k;
+ // 此时数组存储的是除去当前元素左边的元素乘积
+ k = k * nums[i];
+ }
+
+
+ k = 1;
+ for (int i = res.length - 1; i >= 0; i--) {
+ // k为该数右边的乘积
+ res[i] = res[i] * k;
+ //此时数组等于左边的 * 该数右边的。
+ k = k * nums[i];
+ }
+
+ return res;
+ }
+
+
+ @Test
+ public void testCase() {
+ int[] nums = {1, 2, 3, 4};
+ System.out.println(JSONObject.toJSONString(productExceptSelf(nums)));
+ }
+
+}
diff --git a/src/main/java/com/chen/algorithm/study/test238/Solution1.java b/src/main/java/com/chen/algorithm/study/test238/Solution1.java
new file mode 100644
index 0000000..c2028f2
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/study/test238/Solution1.java
@@ -0,0 +1,110 @@
+package com.chen.algorithm.study.test238;
+
+import com.alibaba.fastjson.JSON;
+
+/**
+ * @Auther: zhunn
+ * @Date: 2020/10/16 14:30
+ * @Description: 除自身以外数组的乘积
+ */
+public class Solution1 {
+
+ /**
+ * 时间复杂度O(N),空间复杂度O(N)
+ *
+ * @param nums
+ * @return
+ */
+ public static int[] productExceptSelf(int[] nums) {
+ if (nums == null || nums.length == 0) {
+ return new int[0];
+ }
+
+ int length = nums.length;
+
+ // left和right 分别表示左右两侧的乘积列表
+ int[] left = new int[length];
+ int[] right = new int[length];
+
+ int[] answer = new int[length];
+
+ // left[i] 为索引 i 左侧所有元素的乘积
+ // 对于索引为 ‘0’ 的元素,因为左侧没有元素,所以left[0]=1
+ left[0] = 1;
+ for (int i = 1; i < length; i++) {
+ left[i] = left[i - 1] * nums[i - 1];
+ }
+
+ // right[i] 为索引 i 右侧所有元素的乘积
+ // 对于索引为 ‘length-1’ 的元素,因为右侧没有元素,所以right[length - 1] = 1
+ right[length - 1] = 1;
+ for (int i = length - 2; i >= 0; i--) {
+ right[i] = right[i + 1] * nums[i + 1];
+ }
+
+ // 对于索引i,除nums[i]之外其余各元素的乘积就是左侧所有元素的乘积乘以右侧所有元素的乘积
+ for (int i = 0; i < length; i++) {
+ answer[i] = left[i] * right[i];
+ }
+ return answer;
+ }
+
+ /**
+ * 时间复杂度O(N),空间复杂度O(1)
+ *
+ * @param nums
+ * @return
+ */
+ //public static int[] productExceptSelf1(int[] nums) {
+ // if (nums == null || nums.length == 0) {
+ // return new int[0];
+ // }
+ //
+ // int length = nums.length;
+ // int[] answer = new int[length];
+ //
+ // // answer[i] 为索引 i 左侧所有元素的乘积
+ // // 对于索引为 ‘0’ 的元素,因为左侧没有元素,answer[0]=1
+ // answer[0] = 1;
+ // for (int i = 1; i < length; i++) {
+ // answer[i] = answer[i - 1] * nums[i - 1];
+ // }
+ //
+ // // right 为右侧所有元素的乘积
+ // // 刚开始右侧没有元素,所以right = 1
+ // int right = 1;
+ // for (int i = length - 1; i >= 0; i--) {
+ // // 对于索引 i,左边的乘积为answer[i],右边的乘积为right
+ // answer[i] = right * answer[i];
+ // // right 需要包含右边所有的乘积,所以计算下一个结果时需要将当前值乘到 right 上
+ // right = right * nums[i];
+ // }
+ // return answer;
+ //}
+ public static int[] productExceptSelfTest(int[] nums) {
+ if (nums == null || nums.length == 0) {
+ return new int[0];
+ }
+
+ int length = nums.length;
+ int[] answer = new int[length];
+
+ answer[0] = 1;
+ for (int i = 1; i < length; i++) {
+ answer[i] = answer[i - 1] * nums[i - 1];
+ }
+
+ int right = 1;
+ for (int i = length - 1; i >= 0; i--) {
+ answer[i] = right * answer[i];
+ right = right * nums[i];
+ }
+ return answer;
+ }
+
+ public static void main(String[] args) {
+ int[] nums = {1, 2, 3, 4, 2};
+ System.out.println(JSON.toJSONString(productExceptSelf(nums)));
+ }
+
+}
diff --git a/src/main/java/com/chen/algorithm/study/test239/Solution.java b/src/main/java/com/chen/algorithm/study/test239/Solution.java
new file mode 100644
index 0000000..50846e7
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/study/test239/Solution.java
@@ -0,0 +1,54 @@
+package com.chen.algorithm.study.test239;
+
+import org.junit.Test;
+
+import java.util.ArrayDeque;
+import java.util.Arrays;
+
+/**
+ * https://leetcode-cn.com/problems/sliding-window-maximum/solution/xiang-xi-tong-su-de-si-lu-fen-xi-duo-jie-fa-by-5-3/
+ * @author : chen weijie
+ * @Date: 2020-08-30 01:29
+ */
+public class Solution {
+
+
+ public int[] maxSlidingWindow(int[] nums, int k) {
+
+ int[] res = new int[nums.length - k + 1];
+ // 递减队列
+ ArrayDeque queue = new ArrayDeque<>();
+
+ for (int i = 0; i < nums.length; i++) {
+
+ // 添加滑入的数 nums[i] ,构造递减队列
+ while (!queue.isEmpty() && queue.peekLast() < nums[i]) {
+ queue.pollLast();
+ }
+ queue.addLast(nums[i]);
+
+ // 删除滑出的数 nums[i - k],如果删除的数等于队头,删除队头
+ if (i >= k && nums[i - k] == queue.peekFirst()) {
+ queue.pollFirst();
+ }
+
+ // 写入当前最大值
+ if (i >= k - 1) {
+ res[i - k + 1] = queue.peekFirst();
+ }
+ }
+ return res;
+ }
+
+ @Test
+ public void testCase() {
+
+ int[] nums = {1, 3, -1, -3, 5, 3, 2, 6, 7};
+ int k = 3;
+ System.out.println(Arrays.toString(maxSlidingWindow(nums, k)));
+
+
+ }
+
+
+}
diff --git a/src/main/java/com/chen/algorithm/study/test239/Solution1.java b/src/main/java/com/chen/algorithm/study/test239/Solution1.java
new file mode 100644
index 0000000..4b97134
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/study/test239/Solution1.java
@@ -0,0 +1,75 @@
+package com.chen.algorithm.study.test239;
+
+import org.junit.Test;
+
+import java.util.ArrayDeque;
+import java.util.ArrayList;
+import java.util.Arrays;
+
+/**
+ *
+ * https://leetcode-cn.com/problems/sliding-window-maximum/solution/dan-diao-dui-lie-by-labuladong/
+ * @author : chen weijie
+ * @Date: 2020-09-19 19:43
+ */
+public class Solution1 {
+
+ private class MonotonicQueue {
+
+ ArrayDeque deque;
+
+ public MonotonicQueue() {
+ deque = new ArrayDeque<>();
+ }
+
+ public Integer max() {
+ return deque.peekFirst();
+ }
+
+ public void pop(int num) {
+ if (!deque.isEmpty() && num == deque.peekFirst()) {
+ deque.pollFirst();
+ }
+ }
+
+ public void push(int num) {
+ while (!deque.isEmpty() && deque.peekLast() < num) {
+ deque.pollLast();
+ }
+ deque.addLast(num);
+ }
+
+ }
+
+ public int[] maxSlidingWindow(int[] nums, int k) {
+ MonotonicQueue windows = new MonotonicQueue();
+ ArrayList res = new ArrayList<>();
+ for (int i = 0; i < nums.length; i++) {
+ if (i < k - 1) {
+ windows.push(nums[i]);
+ } else {
+ windows.push(nums[i]);
+ res.add(windows.max());
+ windows.pop(nums[i - k + 1]);
+ }
+ }
+ int[] ans = new int[res.size()];
+ for (int i = 0; i < ans.length; i++) {
+ ans[i] = res.get(i);
+ }
+ return ans;
+ }
+
+ @Test
+ public void testCase() {
+ int[] nums = {1, 3, -1, -3, 5, 3, 6, 7};
+ int k = 3;
+
+ int[] res = maxSlidingWindow(nums, k);
+
+ System.out.println(Arrays.toString(res));
+
+
+ }
+
+}
diff --git a/src/main/java/com/chen/algorithm/study/test239/Solution2.java b/src/main/java/com/chen/algorithm/study/test239/Solution2.java
new file mode 100644
index 0000000..5018318
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/study/test239/Solution2.java
@@ -0,0 +1,83 @@
+package com.chen.algorithm.study.test239;
+
+import org.junit.Test;
+
+import java.util.ArrayDeque;
+import java.util.ArrayList;
+import java.util.Arrays;
+
+/**
+ * https://leetcode-cn.com/problems/sliding-window-maximum/solution/dan-diao-dui-lie-by-labuladong/
+ *
+ * @author : chen weijie
+ * @Date: 2020-09-19 19:43
+ */
+public class Solution2 {
+
+ class SlidWindow {
+
+ private ArrayDeque deque;
+
+ public SlidWindow() {
+ deque = new ArrayDeque<>();
+ }
+
+
+ public Integer getMax() {
+ return deque.peekFirst();
+ }
+
+ public void push(Integer value) {
+
+ while (!deque.isEmpty() && deque.peekLast() < value) {
+ deque.pollLast();
+ }
+ deque.addLast(value);
+ }
+
+ public void pop(int value) {
+
+ if (!deque.isEmpty() && deque.peekFirst() == value) {
+ deque.pollFirst();
+ }
+
+ }
+ }
+
+ public int[] maxSlidingWindow(int[] nums, int k) {
+
+ SlidWindow slidWindow = new SlidWindow();
+ ArrayList resList = new ArrayList<>();
+ for (int i = 0; i < nums.length; i++) {
+ int num = nums[i];
+ if (i < k - 1) {
+ slidWindow.push(num);
+ } else {
+ slidWindow.push(num);
+ resList.add(slidWindow.getMax());
+ slidWindow.pop(nums[i - k + 1]);
+ }
+ }
+
+ int[] ans = new int[resList.size()];
+ for (int i = 0; i < ans.length; i++) {
+ ans[i] = resList.get(i);
+ }
+
+ return ans;
+
+ }
+
+ @Test
+ public void testCase() {
+ int[] nums = {1, 3, -1, -3, 5, 3, 6, 7};
+ int k = 3;
+
+ int[] res = maxSlidingWindow(nums, k);
+
+ System.out.println(Arrays.toString(res));
+
+
+ }
+
+}
diff --git a/src/main/java/com/chen/algorithm/study/test239/Solution3.java b/src/main/java/com/chen/algorithm/study/test239/Solution3.java
new file mode 100644
index 0000000..666ec7b
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/study/test239/Solution3.java
@@ -0,0 +1,88 @@
+package com.chen.algorithm.study.test239;
+
+import org.junit.Test;
+
+import java.util.ArrayDeque;
+import java.util.ArrayList;
+import java.util.Arrays;
+
+/**
+ * https://leetcode-cn.com/problems/sliding-window-maximum/solution/dan-diao-dui-lie-by-labuladong/
+ *
+ * @author : chen weijie
+ * @Date: 2020-09-19 19:43
+ */
+public class Solution3 {
+
+ class SlidWindow {
+
+ ArrayDeque deque;
+
+ public SlidWindow(){
+ deque = new ArrayDeque<>();
+ }
+
+ public Integer getMax (){
+ return deque.peekFirst();
+ }
+
+ public void push(int val){
+
+ while (!deque.isEmpty() && deque.peekLast() < val) {
+ deque.pollLast();
+ }
+ deque.addLast(val);
+ }
+
+
+ public void pop(int val) {
+ if (!deque.isEmpty() && deque.peekFirst() == val) {
+ deque.pollFirst();
+ }
+ }
+
+
+
+ }
+
+ public int [] maxSlidingWindow(int [] nums, int k){
+
+ if (nums == null || nums.length < k){
+ return new int[0];
+ }
+ ArrayList resList = new ArrayList<>();
+ SlidWindow slidWindow = new SlidWindow();
+
+ for (int i = 0; i < nums.length; i++) {
+ if (i < k-1){
+ slidWindow.push(nums[i]);
+ }else {
+ slidWindow.push(nums[i]);
+ resList.add(slidWindow.getMax());
+ slidWindow.pop(nums[i - k + 1]);
+ }
+
+ }
+
+ int[] ans = new int[resList.size()];
+ for (int i = 0; i < ans.length; i++) {
+ ans[i] = resList.get(i);
+ }
+
+ return ans;
+
+ }
+
+ @Test
+ public void testCase() {
+ int[] nums = {1, 3, -1, -3, 5, 3, 6, 7};
+ int k = 3;
+
+ int[] res = maxSlidingWindow(nums, k);
+
+ System.out.println(Arrays.toString(res));
+
+
+ }
+
+}
diff --git a/src/main/java/com/chen/algorithm/study/test206/ListNode.java b/src/main/java/com/chen/algorithm/study/test24/ListNode.java
similarity index 61%
rename from src/main/java/com/chen/algorithm/study/test206/ListNode.java
rename to src/main/java/com/chen/algorithm/study/test24/ListNode.java
index 9528fed..831bd41 100644
--- a/src/main/java/com/chen/algorithm/study/test206/ListNode.java
+++ b/src/main/java/com/chen/algorithm/study/test24/ListNode.java
@@ -1,8 +1,8 @@
-package com.chen.algorithm.study.test206;
+package com.chen.algorithm.study.test24;
/**
* @author : chen weijie
- * @Date: 2019-09-06 02:00
+ * @Date: 2019-12-05 00:05
*/
public class ListNode {
@@ -11,7 +11,6 @@ public class ListNode {
ListNode(int x) {
val = x;
+ next = null;
}
-
-
}
diff --git a/src/main/java/com/chen/algorithm/study/test24/Solution.java b/src/main/java/com/chen/algorithm/study/test24/Solution.java
new file mode 100644
index 0000000..80a0b24
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/study/test24/Solution.java
@@ -0,0 +1,65 @@
+package com.chen.algorithm.study.test24;
+
+/**
+ * 给定一个链表,两两交换其中相邻的节点,并返回交换后的链表。
+ *
+ * 你不能只是单纯的改变节点内部的值,而是需要实际的进行节点交换
+ *
+ * @author : chen weijie
+ * @Date: 2020-05-03 11:27
+ */
+public class Solution {
+
+
+ public ListNode swapPairs(ListNode head) {
+
+ if (head == null) {
+ return null;
+ }
+
+ ListNode pre = new ListNode(-1);
+ pre.next = head;
+ ListNode dummy = pre;
+
+
+ // a->b->c->d
+ while (head != null && head.next != null) {
+ ListNode firstNode = head;
+ ListNode secondNode = head.next;
+
+ firstNode.next = secondNode.next;
+ secondNode.next = pre.next;
+ pre.next = secondNode;
+
+ pre = firstNode;
+ head = firstNode.next;
+ }
+ return dummy.next;
+ }
+
+ /**
+ * 自己写的 错误的,等自己熟悉后,把这个改对
+ *
+ * @param head
+ * @return
+ */
+ public ListNode swapPairs2(ListNode head) {
+
+ ListNode curr = head;
+ ListNode next = head.next;
+ ListNode nextNext = null;
+
+ while (curr != null && next != null) {
+ nextNext = next.next;
+ next.next = curr;
+ curr.next = nextNext;
+ curr = nextNext.next;
+ if (curr != null) {
+ next = curr.next;
+ }
+ }
+ return head.next;
+ }
+
+
+}
diff --git a/src/main/java/com/chen/algorithm/study/test24/Solution2.java b/src/main/java/com/chen/algorithm/study/test24/Solution2.java
new file mode 100644
index 0000000..1efe262
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/study/test24/Solution2.java
@@ -0,0 +1,62 @@
+package com.chen.algorithm.study.test24;
+
+import org.junit.Test;
+
+/**
+ * 给定一个链表,两两交换其中相邻的节点,并返回交换后的链表。
+ *
+ * 你不能只是单纯的改变节点内部的值,而是需要实际的进行节点交换
+ *
+ * @author : chen weijie
+ * @Date: 2020-05-03 11:27
+ */
+public class Solution2 {
+
+
+ public ListNode swapPairs(ListNode head) {
+
+ if (head == null) {
+ return null;
+ }
+
+ ListNode dummy = new ListNode(-1);
+ dummy.next = head;
+
+ ListNode prev = dummy;
+
+ while (head != null && head.next != null) {
+
+ ListNode firstNode = head;
+ ListNode secondNode = head.next;
+
+ firstNode.next = secondNode.next;
+ secondNode.next = prev.next;
+ prev.next = secondNode;
+
+ prev = firstNode;
+ head = firstNode.next;
+ }
+
+ return dummy.next;
+ }
+
+
+ @Test
+ public void test(){
+ ListNode l1_1 = new ListNode(1);
+ ListNode l1_2 = new ListNode(2);
+ ListNode l1_3 = new ListNode(3);
+ ListNode l1_4 = new ListNode(4);
+
+ l1_1.next = l1_2;
+ l1_2.next = l1_3;
+ l1_3.next = l1_4;
+
+ ListNode result = swapPairs(l1_1);
+
+ System.out.println(result.val);
+ System.out.println(result.next.val);
+ System.out.println(result.next.next.val);
+ System.out.println(result.next.next.next.val);
+ }
+}
diff --git a/src/main/java/com/chen/algorithm/study/test24/Solution3.java b/src/main/java/com/chen/algorithm/study/test24/Solution3.java
new file mode 100644
index 0000000..46f6bbc
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/study/test24/Solution3.java
@@ -0,0 +1,104 @@
+package com.chen.algorithm.study.test24;
+
+import org.junit.Test;
+
+/**
+ * @Auther: zhunn
+ * @Date: 2020/10/23 10:48
+ * @Description: 两两交换链表中结点:1-递归,2-迭代
+ */
+public class Solution3 {
+
+
+ /**
+ * 1-递归
+ * @param head
+ * @return
+ */
+ public ListNode swapPairs1(ListNode head) {
+ if (head == null || head.next == null) {
+ return head;
+ }
+ ListNode newHead = head.next;
+ head.next = swapPairs1(newHead.next);
+ newHead.next = head;
+ return newHead;
+ }
+
+ /**
+ * 2-迭代
+ * @param head
+ * @return
+ */
+ public ListNode swapPairs2(ListNode head) {
+ if (head == null || head.next == null) {
+ return head;
+ }
+
+ ListNode dummyHead = new ListNode(-1);
+ dummyHead.next = head;
+ ListNode temp = dummyHead;
+
+ while (temp.next != null && temp.next.next != null) {
+ ListNode node1 = temp.next;
+ ListNode node2 = temp.next.next;
+
+ temp.next = node2;
+ node1.next = node2.next;
+ node2.next = node1;
+
+ temp = node1;
+ }
+ return dummyHead.next;
+ }
+
+ /**
+ * 2-迭代(操作head)
+ * @param head
+ * @return
+ */
+ public ListNode swapPairs3(ListNode head) {
+ if (head == null || head.next == null) {
+ return head;
+ }
+
+ ListNode dummyHead = new ListNode(-1);
+ dummyHead.next = head;
+ ListNode temp = dummyHead;
+
+ while (head != null && head.next != null) {
+ ListNode node1 = head;
+ ListNode node2 = head.next;
+
+ temp.next = node2;
+ node1.next = node2.next;
+ node2.next = node1;
+
+ temp = node1;
+ head = node1.next;
+ }
+ return dummyHead.next;
+ }
+
+ @Test
+ public void test() {
+ ListNode l1_1 = new ListNode(1);
+ ListNode l1_2 = new ListNode(2);
+ ListNode l1_3 = new ListNode(3);
+ ListNode l1_4 = new ListNode(4);
+ ListNode l1_5 = new ListNode(5);
+
+ l1_1.next = l1_2;
+ l1_2.next = l1_3;
+ l1_3.next = l1_4;
+ l1_4.next = l1_5;
+
+ ListNode result = swapPairs3(l1_1);
+
+ System.out.println(result.val);
+ System.out.println(result.next.val);
+ System.out.println(result.next.next.val);
+ System.out.println(result.next.next.next.val);
+ System.out.println(result.next.next.next.next.val);
+ }
+}
diff --git a/src/main/java/com/chen/algorithm/study/test240/Solution.java b/src/main/java/com/chen/algorithm/study/test240/Solution.java
new file mode 100644
index 0000000..c15eb5a
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/study/test240/Solution.java
@@ -0,0 +1,59 @@
+package com.chen.algorithm.study.test240;
+
+/**
+ * https://leetcode-cn.com/problems/search-a-2d-matrix-ii/solution/er-fen-fa-pai-chu-fa-python-dai-ma-java-dai-ma-by-/
+ *
+ * @author : chen weijie
+ * @Date: 2019-12-22 14:26
+ * @Description: zhunn 搜索二维矩阵
+ */
+public class Solution {
+
+
+ /**
+ * 从左下角开始
+ *
+ * 如果当前数比目标元素小,当前列就不可能存在目标值,“指针”就向右移一格(纵坐标加 11);
+ * 如果当前数比目标元素大,当前行就不可能存在目标值,“指针”就向上移一格(横坐标减 11)。
+ *
+ * @param matrix
+ * @param target
+ * @return
+ */
+ public boolean searchMatrix(int[][] matrix, int target) {
+
+ if (matrix == null) {
+ return false;
+ }
+
+ int rows = matrix.length;
+ if (rows == 0) {
+ return false;
+ }
+
+ int col = matrix[0].length;
+
+ if (col == 0) {
+ return false;
+ }
+
+ int x = rows - 1;
+ int y = 0;
+ int value;
+
+ while (x >= 0 && y < col) {
+ value = matrix[x][y];
+ if (value > target) {
+ x--;
+ } else if (value < target) {
+ y++;
+ } else {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+
+}
diff --git a/src/main/java/com/chen/algorithm/study/test242/Solution.java b/src/main/java/com/chen/algorithm/study/test242/Solution.java
new file mode 100644
index 0000000..75d2169
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/study/test242/Solution.java
@@ -0,0 +1,40 @@
+package com.chen.algorithm.study.test242;
+
+import org.junit.Test;
+
+/**
+ * @author : chen weijie
+ * @Date: 2020-05-03 22:12
+ * @Description: zhunn 有效的字母异位词。哈希表
+ */
+public class Solution {
+
+ public boolean isAnagram(String s, String t) {
+
+ if (s == null || t == null || s.length() != t.length()) {
+ return false;
+ }
+
+ int[] counter = new int[26];
+ for (int i = 0; i < s.length(); i++) {
+ counter[s.charAt(i) - 'a']++;
+ counter[t.charAt(i) - 'a']--;
+ }
+
+ for (int n : counter) {
+ if (n != 0) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+
+ @Test
+ public void testCase() {
+
+ System.out.println(isAnagram("anagram", "nagaram"));
+
+ }
+
+}
diff --git a/src/main/java/com/chen/algorithm/study/test242/Solution2.java b/src/main/java/com/chen/algorithm/study/test242/Solution2.java
new file mode 100644
index 0000000..689a35a
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/study/test242/Solution2.java
@@ -0,0 +1,30 @@
+package com.chen.algorithm.study.test242;
+
+/**
+ * @author : chen weijie
+ * @Date: 2020-08-30 16:21
+ */
+public class Solution2 {
+
+
+ public boolean isAnagram(String s, String t) {
+
+ if (s.length() != t.length()) {
+ return false;
+ }
+
+ int[] counter = new int[26];
+
+ for (int i = 0; i < s.length(); i++) {
+ counter[s.charAt(i) - 'a']++;
+ counter[t.charAt(i) - 'a']--;
+ }
+
+ for (int count : counter) {
+ if (count != 0) {
+ return false;
+ }
+ }
+ return true;
+ }
+}
diff --git a/src/main/java/com/chen/algorithm/study/test25/ListNode.java b/src/main/java/com/chen/algorithm/study/test25/ListNode.java
new file mode 100644
index 0000000..f3f415a
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/study/test25/ListNode.java
@@ -0,0 +1,26 @@
+package com.chen.algorithm.study.test25;
+
+/**
+ * @author : chen weijie
+ * @Date: 2019-09-02 23:06
+ * 参考 Solution3
+ */
+public class ListNode {
+
+ int val;
+
+ ListNode next;
+
+ ListNode() {
+ }
+
+ ListNode(int val) {
+ this.val = val;
+ }
+
+ ListNode(int val, ListNode next) {
+ this.val = val;
+ this.next = next;
+ }
+
+}
diff --git a/src/main/java/com/chen/algorithm/study/test25/Solution.java b/src/main/java/com/chen/algorithm/study/test25/Solution.java
new file mode 100644
index 0000000..3ea0332
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/study/test25/Solution.java
@@ -0,0 +1,58 @@
+package com.chen.algorithm.study.test25;
+
+/**
+ * https://leetcode-cn.com/problems/reverse-nodes-in-k-group/solution/tu-jie-kge-yi-zu-fan-zhuan-lian-biao-by-user7208t/
+ *
+ * @author : chen weijie
+ * @Date: 2020-09-20 01:29
+ */
+public class Solution {
+
+ class ListNode {
+ int val;
+ ListNode next;
+
+ ListNode(int x) {
+ val = x;
+ }
+ }
+
+ public ListNode reverseKGroup(ListNode head, int k) {
+
+ ListNode dummy = new ListNode(0);
+ dummy.next = head;
+
+ ListNode pre = dummy;
+ ListNode end = dummy;
+
+ while (end.next != null) {
+ for (int i = 0; i < k && end != null; i++) {
+ end = end.next;
+ }
+ if (end == null) {
+ break;
+ }
+ ListNode start = pre.next;
+ ListNode next = end.next;
+ end.next = null;
+ pre.next = reverse(start);
+ start.next = next;
+ pre = start;
+ end = pre;
+ }
+ return dummy.next;
+ }
+
+ private ListNode reverse(ListNode head) {
+ ListNode pre = null;
+ ListNode curr = head;
+ while (curr != null) {
+ ListNode next = curr.next;
+ curr.next = pre;
+ pre = curr;
+ curr = next;
+ }
+ return pre;
+ }
+
+}
diff --git a/src/main/java/com/chen/algorithm/study/test25/Solution1.java b/src/main/java/com/chen/algorithm/study/test25/Solution1.java
new file mode 100644
index 0000000..aad834a
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/study/test25/Solution1.java
@@ -0,0 +1,79 @@
+package com.chen.algorithm.study.test25;
+
+import org.junit.Test;
+
+/**
+ * https://leetcode-cn.com/problems/reverse-nodes-in-k-group/solution/kge-yi-zu-fan-zhuan-lian-biao-by-powcai/
+ *
+ * 递归
+ *
+ * @author : chen weijie
+ * @Date: 2020-09-20 01:29
+ */
+public class Solution1 {
+
+ class ListNode {
+ int val;
+ ListNode next;
+
+ ListNode(int x) {
+ val = x;
+ }
+ }
+
+ public ListNode reverseKGroup(ListNode head, int k) {
+
+ ListNode dummy = new ListNode(-1);
+ dummy.next = head;
+ ListNode pre = dummy;
+ ListNode tail = dummy;
+
+ while (true) {
+ int count = 0;
+ while (tail != null && count != k) {
+ tail = tail.next;
+ count++;
+ }
+
+ if (tail == null) {
+ break;
+ }
+
+ ListNode head1 = pre.next;
+
+ while (pre.next != tail) {
+ ListNode curr = pre.next;
+ pre.next = curr.next;
+ curr.next = tail.next;
+ tail.next = curr;
+ }
+
+ pre = head1;
+ tail = head1;
+ }
+
+
+ return dummy.next;
+ }
+
+
+ @Test
+ public void testCase() {
+
+ ListNode l1_1 = new ListNode(1);
+ ListNode l1_2 = new ListNode(2);
+ ListNode l1_3 = new ListNode(3);
+ ListNode l1_4 = new ListNode(4);
+ ListNode l1_5 = new ListNode(5);
+
+ l1_1.next = l1_2;
+ l1_2.next = l1_3;
+ l1_3.next = l1_4;
+ l1_4.next = l1_5;
+
+ reverseKGroup(l1_1, 3);
+ System.out.println("end");
+ }
+
+
+}
diff --git a/src/main/java/com/chen/algorithm/study/test25/Solution2.java b/src/main/java/com/chen/algorithm/study/test25/Solution2.java
new file mode 100644
index 0000000..3337a18
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/study/test25/Solution2.java
@@ -0,0 +1,49 @@
+package com.chen.algorithm.study.test25;
+
+/**
+ * https://leetcode-cn.com/problems/reverse-nodes-in-k-group/solution/kge-yi-zu-fan-zhuan-lian-biao-by-powcai/
+ *
+ * @author : chen weijie
+ * @Date: 2020-09-20 01:29
+ */
+public class Solution2 {
+
+ class ListNode {
+ int val;
+ ListNode next;
+
+ ListNode(int x) {
+ val = x;
+ }
+ }
+
+ public ListNode reverseKGroup(ListNode head, int k) {
+ ListNode dummy = new ListNode(0);
+ dummy.next = head;
+ ListNode pre = dummy;
+ ListNode tail = dummy;
+ while (true) {
+ int count = 0;
+ while (tail != null && count != k) {
+ count++;
+ tail = tail.next;
+ }
+ if (tail == null) {
+ break;
+ }
+ ListNode head1 = pre.next;
+ while (pre.next != tail) {
+ ListNode cur = pre.next;
+ pre.next = cur.next;
+ cur.next = tail.next;
+ tail.next = cur;
+ }
+ pre = head1;
+ tail = head1;
+ }
+ return dummy.next;
+ }
+
+
+
+}
diff --git a/src/main/java/com/chen/algorithm/study/test25/Solution3.java b/src/main/java/com/chen/algorithm/study/test25/Solution3.java
new file mode 100644
index 0000000..dc2e09c
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/study/test25/Solution3.java
@@ -0,0 +1,53 @@
+package com.chen.algorithm.study.test25;
+
+/**
+ * https://leetcode-cn.com/problems/reverse-nodes-in-k-group/solution/tu-jie-kge-yi-zu-fan-zhuan-lian-biao-by-user7208t/
+ *
+ * @author : chen weijie
+ * @Date: 2020-09-20 01:29
+ */
+public class Solution3 {
+
+ class ListNode {
+ int val;
+ ListNode next;
+
+ ListNode(int x) {
+ val = x;
+ }
+ }
+
+ public ListNode reverseKGroup(ListNode head, int k) {
+
+ ListNode dummy = new ListNode(-1);
+ dummy.next = head;
+ ListNode pre = dummy;
+ ListNode tail = dummy;
+
+ while (true) {
+
+ int count = 0;
+ while (tail != null && count != k) {
+ count++;
+ tail = tail.next;
+ }
+
+ if (tail == null) {
+ break;
+ }
+
+ ListNode head1 = pre.next;
+ while (pre.next != tail) {
+ ListNode curr = pre.next;
+ pre.next = curr.next;
+ curr.next = tail.next;
+ tail.next = curr;
+ }
+ pre = head1;
+ tail = head1;
+ }
+
+ return dummy.next;
+ }
+
+}
diff --git a/src/main/java/com/chen/algorithm/study/test25/Solution4.java b/src/main/java/com/chen/algorithm/study/test25/Solution4.java
new file mode 100644
index 0000000..eef3cb7
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/study/test25/Solution4.java
@@ -0,0 +1,60 @@
+package com.chen.algorithm.study.test25;
+
+/**
+ * https://leetcode-cn.com/problems/reverse-nodes-in-k-group/solution/tu-jie-kge-yi-zu-fan-zhuan-lian-biao-by-user7208t/
+ *
+ * @author : chen weijie
+ * @Date: 2020-09-20 01:29
+ */
+public class Solution4 {
+
+ class ListNode {
+ int val;
+ ListNode next;
+
+ ListNode(int x) {
+ val = x;
+ }
+ }
+
+ public ListNode reverseKGroup(ListNode head, int k) {
+
+ if (head == null) {
+ return head;
+ }
+
+ ListNode dummy = new ListNode(-1);
+ dummy.next = head;
+ ListNode pre = dummy;
+ ListNode tail = dummy;
+
+
+ while (true) {
+ int count = 0;
+ while (tail != null && count != k) {
+ tail = tail.next;
+ count++;
+ }
+
+ if (tail == null) {
+ break;
+ }
+
+ ListNode head1 = pre.next;
+
+ while (pre.next != tail) {
+ ListNode curr = pre.next;
+ pre.next = curr.next;
+ curr.next = tail.next;
+ tail.next = curr;
+ }
+
+ tail = head1;
+ pre = head1;
+ }
+
+ return dummy.next;
+ }
+
+
+}
diff --git a/src/main/java/com/chen/algorithm/study/test25/Solution5.java b/src/main/java/com/chen/algorithm/study/test25/Solution5.java
new file mode 100644
index 0000000..7f02d9d
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/study/test25/Solution5.java
@@ -0,0 +1,92 @@
+package com.chen.algorithm.study.test25;
+
+/**
+ * @Auther: zhunn
+ * @Date: 2020/10/24 17:23
+ * @Description: K个一组翻转链表
+ */
+public class Solution5 {
+
+ /**
+ * 官网解法
+ * @param head
+ * @param k
+ * @return
+ */
+ public ListNode reverseKGroup(ListNode head, int k) {
+ ListNode hair = new ListNode(0);
+ hair.next = head;
+ ListNode pre = hair;
+
+ while (head != null) {
+ ListNode tail = pre;
+ // 查看剩余部分长度是否大于等于 k
+ for (int i = 0; i < k; ++i) {
+ tail = tail.next;
+ if (tail == null) {
+ return hair.next;
+ }
+ }
+ ListNode nextTemp = tail.next;
+ ListNode[] reverse = myReverse(head, tail);
+ head = reverse[0];
+ tail = reverse[1];
+ // 把子链表重新接回原链表
+ pre.next = head;
+ tail.next = nextTemp;
+ pre = tail;
+ head = tail.next;
+ }
+
+ return hair.next;
+ }
+
+ private ListNode[] myReverse(ListNode head, ListNode tail) {
+ ListNode prev = tail.next;
+ ListNode p = head;
+ while (prev != tail) {
+ ListNode nex = p.next;
+ p.next = prev;
+ prev = p;
+ p = nex;
+ }
+ return new ListNode[]{tail, head};
+ }
+
+
+ public ListNode reverseKGroup1(ListNode head, int k) {
+ ListNode dummy = new ListNode(0);
+ dummy.next = head;
+
+ ListNode pre = dummy;
+ ListNode end = dummy;
+
+ while (end.next != null) {
+ for (int i = 0; i < k && end != null; i++){end = end.next;}
+ if (end == null) {break;}
+ ListNode start = pre.next;
+ ListNode next = end.next;
+ end.next = null;
+ pre.next = reverse(start);
+ start.next = next;
+ pre = start;
+
+ end = pre;
+ }
+ return dummy.next;
+ }
+
+ private ListNode reverse(ListNode head) {
+ ListNode pre = null;
+ ListNode curr = head;
+ while (curr != null) {
+ ListNode next = curr.next;
+ curr.next = pre;
+ pre = curr;
+ curr = next;
+ }
+ return pre;
+ }
+
+
+}
diff --git a/src/main/java/com/chen/algorithm/study/test26/Solution3.java b/src/main/java/com/chen/algorithm/study/test26/Solution3.java
new file mode 100644
index 0000000..0a3894a
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/study/test26/Solution3.java
@@ -0,0 +1,38 @@
+package com.chen.algorithm.study.test26;
+
+import org.junit.Test;
+
+import java.util.Arrays;
+
+/**
+ * @Auther: zhunn
+ * @Date: 2020/10/10 16:23
+ * @Description: 删除排序数组中的重复项,返回新数组长度。双指针法
+ */
+public class Solution3 {
+
+ /**
+ * 双指针法 ,数组是一个引用
+ *
+ * @param nums
+ * @return
+ */
+ public int removeDuplicates(int[] nums) {
+ if (nums == null || nums.length == 0) return 0;
+
+ int i = 0;
+ for (int j = 0; j < nums.length; j++) {
+ if (nums[j] != nums[i]) {
+ i++;
+ nums[i] = nums[j];
+ }
+ }
+ //System.out.println(Arrays.toString(nums));
+ return i + 1;
+ }
+
+ @Test
+ public void test() {
+ System.out.println(removeDuplicates(new int[]{0, 0, 1, 1, 2, 3, 4, 5, 5, 6}));
+ }
+}
diff --git a/src/main/java/com/chen/algorithm/study/test27/Solution2.java b/src/main/java/com/chen/algorithm/study/test27/Solution2.java
new file mode 100644
index 0000000..24cbd15
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/study/test27/Solution2.java
@@ -0,0 +1,32 @@
+package com.chen.algorithm.study.test27;
+
+import org.junit.Test;
+
+import java.util.Arrays;
+
+/**
+ * @Auther: zhunn
+ * @Date: 2020/10/10 16:40
+ * @Description: 移除元素,双指针法
+ */
+public class Solution2 {
+
+ public int removeElement(int[] nums, int val) {
+ if (nums == null || nums.length == 0) return 0;
+
+ int i = 0;
+ for (int j = 0; j < nums.length; j++) {
+ if (nums[j] != val) {
+ nums[i] = nums[j];
+ i++;
+ }
+ }
+ System.out.println(Arrays.toString(nums));
+ return i;
+ }
+
+ @Test
+ public void test() {
+ System.out.println(removeElement(new int[]{1, 1, 2, 2, 3, 5, 6, 7, 8}, 2));
+ }
+}
diff --git a/src/main/java/com/chen/algorithm/study/test279/Solution.java b/src/main/java/com/chen/algorithm/study/test279/Solution.java
new file mode 100644
index 0000000..0649d49
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/study/test279/Solution.java
@@ -0,0 +1,24 @@
+package com.chen.algorithm.study.test279;
+
+/**
+ * @author : chen weijie
+ * @Date: 2019-12-22 15:13
+ */
+public class Solution {
+
+
+ public int numSquares(int n) {
+
+ int[] dp = new int[n + 1];
+ for (int i = 1; i <= n; i++) {
+ dp[i] = i;
+ for (int j = 0; i - j * j >= 0; j++) {
+ dp[i] = Math.min(dp[i], dp[i - j * j] + 1);
+ }
+ }
+
+ return dp[n];
+
+ }
+
+}
diff --git a/src/main/java/com/chen/algorithm/study/test279/Solution1.java b/src/main/java/com/chen/algorithm/study/test279/Solution1.java
new file mode 100644
index 0000000..e216ea6
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/study/test279/Solution1.java
@@ -0,0 +1,24 @@
+package com.chen.algorithm.study.test279;
+
+/**
+ * @author : chen weijie
+ * @Date: 2019-12-22 15:13
+ */
+public class Solution1 {
+
+
+ public int numSquares(int n) {
+
+ int[] dp = new int[n + 1];
+
+ for (int i = 1; i <= n; i++) {
+ dp[i] = i;
+ for (int j = 1; i - j * j >= 0; j++) {
+ dp[i] = Math.min(dp[i], dp[i - j * j] + 1);
+ }
+ }
+ return dp[n];
+ }
+
+
+}
diff --git a/src/main/java/com/chen/algorithm/study/test283/Solution.java b/src/main/java/com/chen/algorithm/study/test283/Solution.java
new file mode 100644
index 0000000..747160c
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/study/test283/Solution.java
@@ -0,0 +1,46 @@
+package com.chen.algorithm.study.test283;
+
+import org.junit.Test;
+
+/**
+ * wrong.......wrong.......wrong.......
+ *
+ * @author : chen weijie
+ * @Date: 2019-11-03 18:44
+ */
+public class Solution {
+
+ public void moveZeroes(int[] nums) {
+
+ if (nums.length == 0 || nums.length == 1) {
+ return;
+ }
+
+ int j = nums.length - 1;
+ for (int i = 0; i < nums.length; i++) {
+ if (i == j) {
+ return;
+ }
+ if (nums[i] == 0) {
+ while (nums[j] == 0) {
+ j--;
+ }
+ int tem = nums[i];
+ nums[i] = nums[j];
+ nums[j] = tem;
+ }
+ }
+ }
+
+ @Test
+ public void testCase() {
+
+ int[] n = {0, 1, 0, 3, 12};
+ moveZeroes(n);
+ System.out.println(n);
+
+
+ }
+
+
+}
diff --git a/src/main/java/com/chen/algorithm/study/test283/Solution1.java b/src/main/java/com/chen/algorithm/study/test283/Solution1.java
new file mode 100644
index 0000000..755c20a
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/study/test283/Solution1.java
@@ -0,0 +1,42 @@
+package com.chen.algorithm.study.test283;
+
+import org.junit.Test;
+
+/**
+ * https://leetcode-cn.com/problems/move-zeroes/solution/javashuang-zhi-zhen-zuo-fa-by-arthur-24/
+ *
+ * @author : chen weijie
+ * @Date: 2019-11-03 18:44
+ */
+public class Solution1 {
+
+ public void moveZeroes(int[] nums) {
+
+ int i = 0;
+ for (int j = 0; j < nums.length; j++) {
+ if (nums[j] != 0) {
+ if (i != j) {
+ nums[i] = nums[j];
+ }
+ i++;
+ }
+ }
+
+ for (; i < nums.length; i++) {
+ nums[i] = 0;
+ }
+
+ }
+
+ @Test
+ public void testCase() {
+
+ int[] n = {0, 1, 0, 3, 12};
+ moveZeroes(n);
+ System.out.println(n);
+
+
+ }
+
+
+}
diff --git a/src/main/java/com/chen/algorithm/study/test283/Solution2.java b/src/main/java/com/chen/algorithm/study/test283/Solution2.java
new file mode 100644
index 0000000..e066b48
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/study/test283/Solution2.java
@@ -0,0 +1,70 @@
+package com.chen.algorithm.study.test283;
+
+import org.junit.Test;
+
+import java.util.Arrays;
+
+/**
+ * 移动0
+ * @author : chen weijie
+ * @Date: 2019-11-03 18:44
+ * @Description: zhunn 移动0至末尾
+ */
+public class Solution2 {
+
+ public void moveZeroes(int[] nums) {
+
+ if (nums.length == 0 || nums.length == 1) {
+ return;
+ }
+
+ int i = 0;
+
+ for (int k = 0; k < nums.length; k++) {
+ if (nums[k] != 0) {
+ nums[i++] = nums[k];
+ }
+ }
+
+ for (int j = i; j < nums.length; j++) {
+ nums[j] = 0;
+ }
+
+
+ }
+
+ @Test
+ public void testCase() {
+
+ int[] n = {0, 1, 0, 3, 12};
+ moveZeroes(n);
+ System.out.println(Arrays.toString(n));
+
+
+ }
+
+
+ /**
+ * @author: zhunn
+ * @param nums
+ * @return
+ */
+ public int[] moveZeroes1(int[] nums) {
+ if (nums == null || nums.length == 0) {
+ return nums;
+ }
+
+ int i = 0;
+ for (int j = 0; j < nums.length; j++) {
+ if (nums[j] != 0) {
+ nums[i] = nums[j];
+ i++;
+ }
+ }
+
+ for (int k = i; k < nums.length; k++) {
+ nums[k] = 0;
+ }
+ return nums;
+ }
+}
diff --git a/src/main/java/com/chen/algorithm/study/test287/Solution.java b/src/main/java/com/chen/algorithm/study/test287/Solution.java
new file mode 100644
index 0000000..b34a21d
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/study/test287/Solution.java
@@ -0,0 +1,25 @@
+package com.chen.algorithm.study.test287;
+
+import java.util.Arrays;
+
+/**
+ * @author : chen weijie
+ * @Date: 2019-12-22 16:22
+ */
+public class Solution {
+
+
+ public int findDuplicate(int[] nums) {
+
+ Arrays.sort(nums);
+
+ for (int i = 1; i < nums.length; i++) {
+ if (nums[i] == nums[i - 1]) {
+ return nums[i];
+ }
+ }
+ return -1;
+ }
+
+
+}
diff --git a/src/main/java/com/chen/algorithm/study/test3/Solution.java b/src/main/java/com/chen/algorithm/study/test3/Solution.java
index e3bf356..8580773 100644
--- a/src/main/java/com/chen/algorithm/study/test3/Solution.java
+++ b/src/main/java/com/chen/algorithm/study/test3/Solution.java
@@ -46,7 +46,7 @@ public int lengthOfLongestSubstring(String s) {
@Test
public void testCase() {
- System.out.println(lengthOfLongestSubstring("cdfg"));
+ System.out.println(lengthOfLongestSubstring("cdfcg"));
}
diff --git a/src/main/java/com/chen/algorithm/study/test3/Solution1.java b/src/main/java/com/chen/algorithm/study/test3/Solution1.java
new file mode 100644
index 0000000..bd87efb
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/study/test3/Solution1.java
@@ -0,0 +1,44 @@
+package com.chen.algorithm.study.test3;
+
+import org.junit.Test;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * 写的不简洁
+ *
+ * @author : chen weijie
+ * @Date: 2019-09-03 00:00
+ */
+public class Solution1 {
+
+ public int lengthOfLongestSubstring(String s) {
+
+ if (s == null || "".equals(s) || s.length() == 0) {
+ return 0;
+ }
+ int max = 1;
+ int left = 0;
+ Map map = new HashMap<>();
+
+ for (int i = 0; i < s.length(); i++) {
+ char c = s.charAt(i);
+
+ if (map.containsKey(c)) {
+ left = Math.max(left, i - map.get(c) + 1);
+ }
+ max = Math.max(max, i - left + 1);
+ map.put(c, i);
+ }
+ return max;
+ }
+
+
+ @Test
+ public void testCase() {
+ System.out.println(lengthOfLongestSubstring("cdfcg"));
+ }
+
+
+}
diff --git a/src/main/java/com/chen/algorithm/study/test3/Solution3.java b/src/main/java/com/chen/algorithm/study/test3/Solution3.java
index a32fccf..aa4f93d 100644
--- a/src/main/java/com/chen/algorithm/study/test3/Solution3.java
+++ b/src/main/java/com/chen/algorithm/study/test3/Solution3.java
@@ -17,17 +17,15 @@ public int lengthOfLongestSubstring(String s) {
if (s == null || s.length() == 0) {
return 0;
}
-
- Map map = new HashMap<>(s.length());
- int max = 0;
- for (int i = 0, j = 0; i < s.length(); i++) {
-
- if (map.containsKey(s.charAt(i))) {
- j = Math.max(j, map.get(s.charAt(i)) + 1);
+ Map map = new HashMap<>();
+ int max = 0, left = 0;
+ for (int i = 0; i < s.length(); i++) {
+ Character c = s.charAt(i);
+ if (map.containsKey(c)) {
+ left = Math.max(left, map.get(s.charAt(i)) + 1);
}
- map.put(s.charAt(i), i);
- max = Math.max(max, i - j + 1);
-
+ map.put(c, i);
+ max = Math.max(max, i - left + 1);
}
return max;
}
diff --git a/src/main/java/com/chen/algorithm/study/test3/Solution4.java b/src/main/java/com/chen/algorithm/study/test3/Solution4.java
new file mode 100644
index 0000000..3e6daf1
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/study/test3/Solution4.java
@@ -0,0 +1,45 @@
+package com.chen.algorithm.study.test3;
+
+import org.junit.Test;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * 写的不简洁
+ *
+ * @author : chen weijie
+ * @Date: 2019-09-03 00:00
+ */
+public class Solution4 {
+
+ public int lengthOfLongestSubstring(String s) {
+
+ if (s == null || "".equals(s)) {
+ return 0;
+ }
+ Map map = new HashMap<>();
+
+ int max = 0;
+ int left = 0;
+
+ for (int i = 0; i < s.length(); i++) {
+ char c = s.charAt(i);
+
+ if (map.containsKey(c)) {
+ left = Math.max(left, map.get(c));
+ }
+ max = Math.max(max, i - left);
+ map.put(c, i);
+ }
+ return max;
+ }
+
+
+ @Test
+ public void testCase() {
+ System.out.println(lengthOfLongestSubstring("cdfcg"));
+ }
+
+
+}
diff --git a/src/main/java/com/chen/algorithm/study/test300/Solution.java b/src/main/java/com/chen/algorithm/study/test300/Solution.java
new file mode 100644
index 0000000..4471720
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/study/test300/Solution.java
@@ -0,0 +1,46 @@
+package com.chen.algorithm.study.test300;
+
+import org.junit.Test;
+
+import java.util.Arrays;
+
+/**
+ * https://leetcode-cn.com/problems/longest-increasing-subsequence/solution/zui-chang-shang-sheng-zi-xu-lie-dong-tai-gui-hua-2/
+ *
+ * @author : chen weijie
+ * @Date: 2019-12-22 16:28
+ */
+public class Solution {
+
+ public int lengthOfList(int[] nums) {
+
+ if (nums.length == 0) {
+ return 0;
+ }
+
+ int[] dp = new int[nums.length];
+ int res = 0;
+ Arrays.fill(dp, 1);
+ for (int i = 0; i < nums.length; i++) {
+ for (int j = 0; j < i; j++) {
+ if (nums[j] < nums[i]) {
+ dp[i] = Math.max(dp[i], dp[j] + 1);
+ }
+ }
+ res = Math.max(res, dp[i]);
+ }
+ return res;
+ }
+
+
+ @Test
+ public void testCase() {
+ int[] n = {4, 1, -4, 7, -2, 9, 0};
+
+ System.out.println(lengthOfList(n));
+
+
+ }
+
+
+}
diff --git a/src/main/java/com/chen/algorithm/study/test300/Solution1.java b/src/main/java/com/chen/algorithm/study/test300/Solution1.java
new file mode 100644
index 0000000..f676ca9
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/study/test300/Solution1.java
@@ -0,0 +1,39 @@
+package com.chen.algorithm.study.test300;
+
+import java.util.Arrays;
+
+/**
+ * @author : chen weijie
+ * @Date: 2020-09-05 11:27
+ */
+public class Solution1 {
+
+
+ /**
+ * 10 9 2 5 3 7 101 18
+ *
+ * @param nums
+ * @return
+ */
+ public int lengthOfList(int[] nums) {
+
+ if (nums == null || nums.length == 0) {
+ return 0;
+ }
+
+ int[] dp = new int[nums.length - 1];
+
+ Arrays.fill(dp, 1);
+ int max = dp[0];
+ for (int i = 1; i < nums.length; i++) {
+ for (int j = 0; j <= i; j++) {
+ if (nums[j] < nums[i]) {
+ dp[i] = Math.max(dp[j] + 1, dp[i]);
+ }
+ }
+
+ max = Math.max(dp[i], max);
+ }
+ return max;
+ }
+}
diff --git a/src/main/java/com/chen/algorithm/study/test300/Solution2.java b/src/main/java/com/chen/algorithm/study/test300/Solution2.java
new file mode 100644
index 0000000..65c0a4b
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/study/test300/Solution2.java
@@ -0,0 +1,42 @@
+package com.chen.algorithm.study.test300;
+
+import org.junit.Test;
+
+/**
+ * https://leetcode-cn.com/problems/longest-increasing-subsequence/solution/zui-chang-shang-sheng-zi-xu-lie-dong-tai-gui-hua-2/
+ *
+ * @author : chen weijie
+ * @Date: 2019-12-22 16:28
+ */
+public class Solution2 {
+
+ public int lengthOfList(int[] nums) {
+
+ if (nums == null || nums.length == 0) {
+ return 0;
+ }
+ int[] dp = new int[nums.length];
+ dp[0] = 1;
+ int max = 1;
+ for (int i = 1; i < dp.length; i++) {
+ int tem = 0;
+ for (int j = 0; j < i; j++) {
+ if (nums[j] < nums[i]) {
+ tem = Math.max(tem, dp[j]);
+ }
+ }
+ dp[i] = tem + 1;
+ max = Math.max(dp[i], max);
+ }
+ return max;
+ }
+
+
+ @Test
+ public void testCase() {
+ int[] n = {4, 1, -4, 7, -2, 9, 0};
+ System.out.println(lengthOfList(n));
+ }
+
+
+}
diff --git a/src/main/java/com/chen/algorithm/study/test300/Solution3.java b/src/main/java/com/chen/algorithm/study/test300/Solution3.java
new file mode 100644
index 0000000..d936eca
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/study/test300/Solution3.java
@@ -0,0 +1,48 @@
+package com.chen.algorithm.study.test300;
+
+import org.junit.Test;
+
+import java.util.Arrays;
+
+/**
+ * https://leetcode-cn.com/problems/longest-increasing-subsequence/solution/zui-chang-shang-sheng-zi-xu-lie-dong-tai-gui-hua-2/
+ *
+ * @author : chen weijie
+ * @Date: 2019-12-22 16:28
+ */
+public class Solution3 {
+
+ public int lengthOfList(int[] nums) {
+
+ if (nums == null || nums.length == 0) {
+ return 0;
+ }
+ int len = nums.length;
+
+ int[] dp = new int[len];
+ int max = 1;
+ Arrays.fill(dp, 1);
+ for (int i = 1; i < len; i++) {
+ for (int j = 0; j < i; j++) {
+ if (nums[i] > nums[j]) {
+ dp[i] = Math.max(dp[i], dp[j] + 1);
+ }
+ }
+ max = Math.max(dp[i], max);
+ }
+
+ return max;
+ }
+
+
+ @Test
+ public void testCase() {
+ int[] n = {4, 1, -4, 7, -2, 9, 0};
+
+ System.out.println(lengthOfList(n));
+
+
+ }
+
+
+}
diff --git a/src/main/java/com/chen/algorithm/study/test309/Solution.java b/src/main/java/com/chen/algorithm/study/test309/Solution.java
new file mode 100644
index 0000000..adf2974
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/study/test309/Solution.java
@@ -0,0 +1,44 @@
+package com.chen.algorithm.study.test309;
+
+/**
+ * https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock-with-cooldown/solution/dong-tai-gui-hua-by-liweiwei1419-5/
+ *
+ * @author : chen weijie
+ * @Date: 2020-04-12 17:53
+ */
+public class Solution {
+
+ public int maxProfit(int[] prices) {
+ int len = prices.length;
+ // 特判
+ if (len < 2) {
+ return 0;
+ }
+
+ int[][] dp = new int[len][3];
+// 不持股可以由这两个状态转换而来:
+// 昨天不持股,今天什么都不操作,仍然不持股;
+// 昨天持股,今天卖了一股。
+// 持股可以由这两个状态转换而来:
+// 昨天持股,今天什么都不操作,仍然持股;
+// 昨天处在冷冻期,今天买了一股;
+// 处在冷冻期只可以由不持股转换而来,因为题目中说,刚刚把股票卖了,需要冷冻 1 天。
+
+ // 初始化
+// 0 表示不持股;
+// 1 表示持股;
+// 2 表示处在冷冻期。
+ dp[0][0] = 0;
+ dp[0][1] = -prices[0];
+ dp[0][2] = 0;
+
+ for (int i = 1; i < prices.length; i++) {
+ dp[i][0] = Math.max(dp[i - 1][0], dp[i - 1][1] + prices[i]);
+ dp[i][1] = Math.max(dp[i - 1][1], dp[i - 1][2] - prices[i]);
+ dp[i][2] = dp[i-1][0];
+ }
+
+ return Math.max(dp[len - 1][2], dp[len - 1][0]);
+ }
+
+}
diff --git a/src/main/java/com/chen/algorithm/study/test309/Solution1.java b/src/main/java/com/chen/algorithm/study/test309/Solution1.java
new file mode 100644
index 0000000..6a8e06c
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/study/test309/Solution1.java
@@ -0,0 +1,31 @@
+package com.chen.algorithm.study.test309;
+
+/**
+ * https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock-with-cooldown/solution/dong-tai-gui-hua-by-liweiwei1419-5/
+ *
+ * @author : chen weijie
+ * @Date: 2020-04-12 17:53
+ */
+public class Solution1 {
+
+ public int maxProfit(int[] prices) {
+
+ if (prices == null || prices.length < 2) {
+ return 0;
+ }
+ int length = prices.length;
+ int[][] dp = new int[length][3];
+ dp[0][0] = 0;
+ dp[0][1] = -prices[0];
+ dp[0][2] = 0;
+
+ for (int i = 1; i < length; i++) {
+ dp[i][0] = Math.max(dp[i - 1][0], dp[i - 1][1] + prices[i]);
+ dp[i][1] = Math.max(dp[i - 1][1], dp[i - 1][2] - prices[i]);
+ dp[i][2] = dp[i - 1][0];
+ }
+
+ return Math.max(dp[length - 1][0], dp[length - 1][2]);
+ }
+
+}
diff --git a/src/main/java/com/chen/algorithm/study/test31/Solution.java b/src/main/java/com/chen/algorithm/study/test31/Solution.java
new file mode 100644
index 0000000..02ff5c4
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/study/test31/Solution.java
@@ -0,0 +1,47 @@
+package com.chen.algorithm.study.test31;
+
+/**
+ * https://leetcode-cn.com/problems/next-permutation/solution/xia-yi-ge-pai-lie-by-leetcode/ *
+ * 排列,离散数学
+ *
+ * @author : chen weijie
+ * @Date: 2019-11-10 15:43
+ */
+public class Solution {
+
+
+ public void nextPermutation(int[] nums) {
+ int i = nums.length - 2;
+ while (i >= 0 && nums[i + 1] <= nums[i]) {
+ i--;
+ }
+
+ if (i >= 0) {
+ int j = nums.length - 1;
+ while (j >= 0 && nums[j] <= nums[i]) {
+ j--;
+ }
+ swap(nums, i, j);
+ }
+ revert(nums, i + 1);
+ }
+
+
+ private void revert(int[] nums, int start) {
+ int i = start, j = nums.length - 1;
+ while (i < j) {
+ swap(nums, i, j);
+ i++;
+ j--;
+ }
+ }
+
+
+ private void swap(int[] nums, int i, int j) {
+ int temp = nums[j];
+ nums[i] = nums[j];
+ nums[j] = temp;
+ }
+
+
+}
diff --git a/src/main/java/com/chen/algorithm/study/test322/Solution.java b/src/main/java/com/chen/algorithm/study/test322/Solution.java
new file mode 100644
index 0000000..83cb1c1
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/study/test322/Solution.java
@@ -0,0 +1,42 @@
+package com.chen.algorithm.study.test322;
+
+import org.junit.Test;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * https://leetcode-cn.com/problems/coin-change/solution/322-ling-qian-dui-huan-by-leetcode-solution/
+ *
+ * @author : chen weijie
+ * @Date: 2020-05-24 00:43
+ */
+public class Solution {
+
+ public int coinChange(int[] coins, int amount) {
+ int max = amount + 1;
+ int[] dp = new int[amount + 1];
+ Arrays.fill(dp, max);
+ dp[0] = 0;
+ for (int i = 0; i < dp.length; i++) {
+ for (int coin : coins) {
+ if (coin <= i) {
+ dp[i] = Math.min(dp[i], dp[i - coin] + 1);
+ }
+ }
+ }
+ return dp[amount] > amount ? -1 : dp[amount];
+ }
+
+
+ @Test
+ public void testCase() {
+ int[] coins = {2};
+
+ List list = new ArrayList<>();
+ System.out.println(coinChange(coins, 3));
+ }
+
+
+}
diff --git a/src/main/java/com/chen/algorithm/study/test322/Solution1.java b/src/main/java/com/chen/algorithm/study/test322/Solution1.java
new file mode 100644
index 0000000..938f497
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/study/test322/Solution1.java
@@ -0,0 +1,38 @@
+package com.chen.algorithm.study.test322;
+
+import org.junit.Test;
+
+import java.util.Arrays;
+
+/**
+ * @author : chen weijie
+ * @Date: 2020-09-05 15:09
+ */
+public class Solution1 {
+
+
+ public int coinChange(int[] coins, int amount) {
+
+ int max = amount + 1;
+ int[] dp = new int[amount + 1];
+ Arrays.fill(dp, max);
+ dp[0] = 0;
+ for (int i = 1; i <= amount; i++) {
+
+ for (int coin : coins) {
+ if (coin <= i) {
+ dp[i] = Math.min(dp[i], dp[i - coin] + 1);
+ }
+ }
+ }
+ return dp[amount] > amount ? -1 : dp[amount];
+ }
+
+ @Test
+ public void testCase() {
+ int[] coins = {1, 2, 5};
+ System.out.println(coinChange(coins, 11));
+ }
+
+
+}
diff --git a/src/main/java/com/chen/algorithm/study/test33/Solution.java b/src/main/java/com/chen/algorithm/study/test33/Solution.java
new file mode 100644
index 0000000..6fd5356
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/study/test33/Solution.java
@@ -0,0 +1,68 @@
+package com.chen.algorithm.study.test33;
+
+import org.junit.Test;
+
+/**
+ * https://leetcode-cn.com/problems/search-in-rotated-sorted-array/solution/ji-bai-liao-9983de-javayong-hu-by-reedfan/
+ *
+ * @author : chen weijie
+ * @Date: 2019-11-10 16:32
+ */
+public class Solution {
+
+
+ public int search(int[] nums, int target) {
+
+
+ if (nums == null || nums.length == 0) {
+ return -1;
+ }
+
+
+ int start = 0, end = nums.length - 1;
+ int mid;
+ while (start <= end) {
+ mid = (end + start) / 2;
+ if (nums[mid] == target) {
+ return mid;
+ }
+ if (nums[start] <= nums[mid]) {
+
+ if (target >= nums[start] && target < nums[mid]) {
+ end = mid - 1;
+ } else {
+ start = mid + 1;
+ }
+ } else {
+ if (target <= nums[end] && target > nums[mid]) {
+ start = mid + 1;
+ } else {
+ end = mid - 1;
+ }
+ }
+ }
+ return -1;
+ }
+
+
+ @Test
+ public void testCase(){
+
+ int [] n1 = {2 ,3, 4, 5, 6, 7, 1};
+
+ int [] n2 = {6 ,7, 1, 2, 3, 4, 5};
+
+
+// System.out.println(search(n1,4));
+
+ System.out.println(search(n2,4));
+
+
+
+
+ }
+
+
+
+
+}
diff --git a/src/main/java/com/chen/algorithm/study/test338/Solution.java b/src/main/java/com/chen/algorithm/study/test338/Solution.java
new file mode 100644
index 0000000..9efa33f
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/study/test338/Solution.java
@@ -0,0 +1,28 @@
+package com.chen.algorithm.study.test338;
+
+/**
+ * @author : chen weijie
+ * @Date: 2020-09-02 02:11
+ */
+public class Solution {
+
+ public int[] countBits(int num) {
+
+ int[] nums = new int[num + 1];
+ for (int i = 0; i <= num; i++) {
+ nums[i] = countBit(i);
+ }
+ return nums;
+ }
+
+
+ public int countBit(int n) {
+ int count = 0;
+ while (n != 0) {
+ count++;
+ n = n & (n - 1);
+ }
+ return count;
+ }
+
+}
diff --git a/src/main/java/com/chen/algorithm/study/test338/Solution1.java b/src/main/java/com/chen/algorithm/study/test338/Solution1.java
new file mode 100644
index 0000000..98bd062
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/study/test338/Solution1.java
@@ -0,0 +1,19 @@
+package com.chen.algorithm.study.test338;
+
+/**
+ * @author : chen weijie
+ * @Date: 2020-09-02 02:11
+ */
+public class Solution1 {
+
+ public int[] countBits(int num) {
+
+ int[] count = new int[num + 1];
+ for (int i = 0; i <= num; i++) {
+ count[i] = count[i & (i - 1)] + 1;
+ }
+ return count;
+ }
+
+
+}
diff --git a/src/main/java/com/chen/algorithm/study/test34/Solution.java b/src/main/java/com/chen/algorithm/study/test34/Solution.java
new file mode 100644
index 0000000..4c10784
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/study/test34/Solution.java
@@ -0,0 +1,84 @@
+package com.chen.algorithm.study.test34;
+
+import com.alibaba.fastjson.JSONObject;
+import org.junit.Test;
+
+/**
+ * 自己写的,比较复杂
+ *
+ * @author : chen weijie
+ * @Date: 2019-11-10 17:15
+ */
+public class Solution {
+
+
+ public int[] searchRange(int[] nums, int target) {
+
+
+ int[] result = {Integer.MAX_VALUE, -Integer.MAX_VALUE};
+ boolean modify = false;
+
+ int start = 0, end = nums.length - 1;
+ int mid;
+
+ while (start <= end) {
+
+ // mid=left+(right-left)/2 优化取中值
+ mid = (start + end) / 2;
+
+ if (nums[mid] == target) {
+ modify = true;
+ result[0] = Math.min(result[0], mid);
+ result[1] = Math.max(result[1], mid);
+
+ while (mid >= 0 && mid < nums.length && nums[mid] == target) {
+ mid--;
+ if (mid >= 0 && mid < nums.length && nums[mid] == target) {
+ result[0] = Math.min(result[0], mid);
+ } else {
+ break;
+ }
+ }
+
+ // 由于上面while循环后可能越界,所以必须重新找到原先的位置;
+ mid = (start + end) / 2;
+
+ while (mid >= 0 && mid < nums.length && nums[mid] == target) {
+ mid++;
+ if (mid >= 0 && mid < nums.length && nums[mid] == target) {
+ result[1] = Math.max(result[1], mid);
+ } else {
+ break;
+ }
+ }
+ break;
+ } else if (nums[mid] > target) {
+ end = mid - 1;
+ } else if (nums[mid] < target) {
+ start = mid + 1;
+ }
+ }
+
+ if (modify) {
+ return result;
+ } else {
+ return new int[]{-1, -1};
+ }
+
+ }
+
+
+ @Test
+ public void testCase() {
+
+
+ int[] n = {2, 2};
+
+ int[] result = searchRange(n, 2);
+
+ System.out.println(JSONObject.toJSONString(result));
+
+ }
+
+
+}
diff --git a/src/main/java/com/chen/algorithm/study/test34/Solution1.java b/src/main/java/com/chen/algorithm/study/test34/Solution1.java
new file mode 100644
index 0000000..a0847c7
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/study/test34/Solution1.java
@@ -0,0 +1,69 @@
+package com.chen.algorithm.study.test34;
+
+import com.alibaba.fastjson.JSONObject;
+import org.junit.Test;
+
+/**
+ * https://leetcode-cn.com/problems/find-first-and-last-position-of-element-in-sorted-array/solution/er-fen-cha-zhao-suan-fa-xi-jie-xiang-jie-by-labula/
+ *
+ * @author : chen weijie
+ * @Date: 2019-11-10 17:56
+ */
+public class Solution1 {
+
+
+ public int[] searchRange(int[] nums, int target) {
+ if (nums.length == 0) {
+ return new int[]{-1, -1};
+ }
+ return new int[]{searchLeft(nums, target), searchRight(nums, target)};
+ }
+
+ public int searchLeft(int[] nums, int target) {
+ int left = 0;
+ int right = nums.length;
+ while (left < right) {
+ int mid = (left + right) >>> 1;
+ if (nums[mid] == target) {
+ right = mid;
+ } else if (nums[mid] < target) {
+ left = mid + 1;
+ } else if (nums[mid] > target) {
+ right = mid;
+ }
+ }
+ int pos = (left < nums.length) ? left : nums.length - 1;
+ if (nums[pos] != target) {
+ return -1;
+ }
+ return left;
+ }
+
+ public int searchRight(int[] nums, int target) {
+ int left = 0;
+ int right = nums.length;
+ while (left < right) {
+ int mid = (left + right) >>> 1;
+ if (nums[mid] == target) left = mid + 1;
+ else if (nums[mid] < target) left = mid + 1;
+ else if (nums[mid] > target) right = mid;
+ }
+ int pos = (left - 1 >= 0) ? left - 1 : 0;
+ if (nums[pos] != target) return -1;
+ return left - 1;
+ }
+
+ @Test
+ public void testCase() {
+
+
+ int[] n = {5, 7, 7, 8, 8, 10};
+
+ int[] result = searchRange(n, 6);
+
+ System.out.println(JSONObject.toJSONString(result));
+
+ }
+
+
+}
diff --git a/src/main/java/com/chen/algorithm/study/test34/Solution3.java b/src/main/java/com/chen/algorithm/study/test34/Solution3.java
new file mode 100644
index 0000000..bf02590
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/study/test34/Solution3.java
@@ -0,0 +1,66 @@
+package com.chen.algorithm.study.test34;
+
+import org.junit.Test;
+
+import java.util.Arrays;
+
+/**
+ * @author : chen weijie
+ * @Date: 2020-09-14 01:34
+ */
+public class Solution3 {
+
+
+ public int[] searchRange(int[] nums, int target) {
+
+ int[] res = new int[2];
+
+ res[0] = leftIndex(target, nums);
+ res[1] = rightIndex(target, nums);
+
+ return res;
+ }
+
+
+ private int leftIndex(int target, int[] nums) {
+ int left = 0, right = nums.length - 1;
+ while (left <= right) {
+ int mid = (right - left) / 2 + left;
+ if (nums[mid] < target) {
+ left = mid + 1;
+ } else {
+ right = mid - 1;
+ }
+ }
+ if (left <= nums.length - 1 && nums[left] == target) {
+ return left;
+ }
+
+ return -1;
+ }
+
+ private int rightIndex(int target, int[] nums) {
+ int left = 0, right = nums.length - 1;
+ while (left <= right) {
+ int mid = (right - left) / 2 + left;
+ if (nums[mid] <= target) {
+ left = mid + 1;
+ } else {
+ right = mid - 1;
+ }
+ }
+ if (right >= 0 && nums[right] == target) {
+ return right;
+ }
+
+ return -1;
+ }
+
+ @Test
+ public void testCase() {
+ int[] nums = {5, 7, 7, 8, 8, 10};
+ int[] res = searchRange(nums, 8);
+ System.out.println(Arrays.toString(res));
+
+ }
+}
diff --git a/src/main/java/com/chen/algorithm/study/test34/Solution4.java b/src/main/java/com/chen/algorithm/study/test34/Solution4.java
new file mode 100644
index 0000000..bf8ea9c
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/study/test34/Solution4.java
@@ -0,0 +1,83 @@
+package com.chen.algorithm.study.test34;
+
+import org.junit.Test;
+
+import java.util.Arrays;
+
+/**
+ * @Auther: zhunn
+ * @Date: 2020/10/10 17:04
+ * @Description: 在排序数组中查找元素的第一个和最后一个位置
+ * (可使用二分查找到第一个与target相等元素和最后一个与target相等元素 方式,返回下标)
+ */
+public class Solution4 {
+
+ /**
+ * 当key=array[mid]时, 往左边一个一个逼近,right = mid -1; 返回left
+ *
+ * @param nums
+ * @param target
+ * @return
+ */
+ private int leftIndex(int[] nums, int target) {
+ if (nums == null || nums.length == 0) {
+ return -1;
+ }
+
+ int left = 0, right = nums.length - 1;
+ while (left <= right) {
+ int mid = (right - left) / 2 + left;
+ if (nums[mid] >= target) {
+ right = mid - 1;
+ } else {
+ left = mid + 1;
+ }
+ }
+
+ if (left <= nums.length - 1 && nums[left] == target) {
+ return left;
+ }
+ return -1;
+ }
+
+ /**
+ * 当key=array[mid]时, 往右边一个一个逼近,left = mid + 1; 返回right
+ *
+ * @param nums
+ * @param target
+ * @return
+ */
+ private int rightIndex(int[] nums, int target) {
+ if (nums == null || nums.length == 0) {
+ return -1;
+ }
+ int left = 0, right = nums.length - 1;
+ while (left <= right) {
+ int mid = (right - left) / 2 + left;
+ if (nums[mid] <= target) {
+ left = mid + 1;
+ } else {
+ right = mid - 1;
+ }
+ }
+ if (right >= 0 && nums[right] == target) {
+ return right;
+ }
+ return -1;
+ }
+
+ public int[] find(int[] nums, int target) {
+ int[] res = new int[2];
+ res[0] = leftIndex(nums, target);
+ res[1] = rightIndex(nums, target);
+ return res;
+ }
+
+ @Test
+ public void test() {
+ int[] nums = new int[]{5, 7, 7, 8, 8, 8, 10};
+ int[] res = find(nums, 8);
+ System.out.println(Arrays.toString(res));
+ }
+
+}
diff --git a/src/main/java/com/chen/algorithm/study/test343/Solution.java b/src/main/java/com/chen/algorithm/study/test343/Solution.java
new file mode 100644
index 0000000..909f7e3
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/study/test343/Solution.java
@@ -0,0 +1,22 @@
+package com.chen.algorithm.study.test343;
+
+/**
+ * @author : chen weijie
+ * @Date: 2020-09-17 01:12
+ */
+public class Solution {
+
+
+ public int integerBreak(int n) {
+ int[] dp = new int[n + 1];
+
+ for (int i = 2; i <= n; i++) {
+ int curMax = 0;
+ for (int j = 1; j < i; j++) {
+ curMax = Math.max(curMax, Math.max(j * (i - j), j * dp[i - j]));
+ }
+ dp[i] = curMax;
+ }
+ return dp[n];
+ }
+}
diff --git a/src/main/java/com/chen/algorithm/study/test343/Solution1.java b/src/main/java/com/chen/algorithm/study/test343/Solution1.java
new file mode 100644
index 0000000..2731800
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/study/test343/Solution1.java
@@ -0,0 +1,26 @@
+package com.chen.algorithm.study.test343;
+
+/**
+ * @author : chen weijie
+ * @Date: 2020-09-17 01:12
+ */
+public class Solution1 {
+
+
+ public int integerBreak(int n) {
+
+ int[] dp = new int[n + 1];
+
+
+ for (int i = 2; i <= n; i++) {
+ int curMax = 0;
+ for (int j = 1; j < i; j++) {
+ curMax = Math.max(curMax, Math.max(dp[i - j] * j, j * (i - j)));
+ }
+ dp[i] = curMax;
+ }
+
+
+ return dp[n];
+ }
+}
diff --git a/src/main/java/com/chen/algorithm/study/test347/Solution.java b/src/main/java/com/chen/algorithm/study/test347/Solution.java
new file mode 100644
index 0000000..1ea2287
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/study/test347/Solution.java
@@ -0,0 +1,61 @@
+package com.chen.algorithm.study.test347;
+
+import org.junit.Test;
+
+import java.util.*;
+
+/**
+ * @author : chen weijie
+ * @Date: 2020-09-19 15:10
+ */
+public class Solution {
+
+ public int[] topKFrequent(int[] nums, int k) {
+
+ Map map = new HashMap<>();
+
+ for (int num : nums) {
+ if (!map.containsKey(num)) {
+ map.put(num, 1);
+ } else {
+ map.put(num, map.get(num) + 1);
+ }
+ }
+
+ PriorityQueue queue = new PriorityQueue<>(new Comparator() {
+ @Override
+ public int compare(Integer o1, Integer o2) {
+ return map.get(o1) - map.get(o2);
+ }
+ });
+
+
+ for (int num : map.keySet()) {
+
+ if (queue.size() < k) {
+ queue.add(num);
+ } else if (map.get(queue.peek()) < map.get(num)) {
+ queue.remove();
+ queue.add(num);
+ }
+ }
+
+ int[] res = new int[k];
+ int i = 0;
+ while (!queue.isEmpty()) {
+ res[i++] = queue.poll();
+ }
+
+ return res;
+ }
+
+ @Test
+ public void testCase() {
+
+ int[] nums = {5, 2, 5, 3, 5, 3, 1, 1, 3};
+ int k = 2;
+ int[] res = topKFrequent(nums, k);
+ System.out.println(Arrays.toString(res));
+ }
+
+}
diff --git a/src/main/java/com/chen/algorithm/study/test347/Solution1.java b/src/main/java/com/chen/algorithm/study/test347/Solution1.java
new file mode 100644
index 0000000..82dfe46
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/study/test347/Solution1.java
@@ -0,0 +1,60 @@
+package com.chen.algorithm.study.test347;
+
+import org.junit.Test;
+
+import java.util.*;
+
+/**
+ * @author : chen weijie
+ * @Date: 2020-09-19 15:10
+ */
+public class Solution1 {
+
+ public int[] topKFrequent(int[] nums, int k) {
+
+ Map map = new HashMap<>();
+
+ for (int num : nums) {
+ if (!map.containsKey(num)) {
+ map.put(num, 1);
+ } else {
+ map.put(num, map.get(num) + 1);
+ }
+ }
+
+ PriorityQueue priorityQueue = new PriorityQueue<>(new Comparator() {
+ @Override
+ public int compare(Integer o1, Integer o2) {
+ return map.get(o1) - map.get(o2);
+ }
+ });
+
+ for (Integer num : map.keySet()) {
+
+ if (priorityQueue.size() < k) {
+ priorityQueue.add(num);
+ } else if (map.get(priorityQueue.peek()) < map.get(num)) {
+ priorityQueue.remove();
+ priorityQueue.add(num);
+ }
+ }
+
+ int[] res = new int[k];
+ int i = 0;
+ while (!priorityQueue.isEmpty()) {
+ res[i++] = priorityQueue.poll();
+ }
+
+ return res;
+ }
+
+ @Test
+ public void testCase() {
+
+ int[] nums = {5, 2, 5, 3, 5, 3, 1, 1, 3};
+ int k = 2;
+ int[] res = topKFrequent(nums, k);
+ System.out.println(Arrays.toString(res));
+ }
+
+}
diff --git a/src/main/java/com/chen/algorithm/study/test39/Solution.java b/src/main/java/com/chen/algorithm/study/test39/Solution.java
new file mode 100644
index 0000000..16c7b2f
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/study/test39/Solution.java
@@ -0,0 +1,73 @@
+package com.chen.algorithm.study.test39;
+
+import com.alibaba.fastjson.JSONObject;
+import org.junit.Test;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Stack;
+
+/**
+ * 不会。。。
+ *
+ * https://leetcode-cn.com/problems/combination-sum/solution/hui-su-suan-fa-jian-zhi-python-dai-ma-java-dai-m-2/
+ *
+ * @author : chen weijie
+ * @Date: 2019-11-10 18:40
+ */
+public class Solution {
+
+
+ private List> res = new ArrayList<>();
+ private int[] candidates;
+ private int len;
+
+ /**
+ * @param candidates
+ * @param target
+ * @return
+ */
+ public List> combinationSum(int[] candidates, int target) {
+
+ int len = candidates.length;
+ if (len == 0) {
+ return res;
+ }
+
+ this.candidates = candidates;
+ this.len = len;
+ findCombinationSum(target, 0, new Stack<>());
+ return res;
+ }
+
+
+ private void findCombinationSum(int residue, int start, Stack pre) {
+ if (residue < 0) {
+ return;
+ }
+
+ if (residue == 0) {
+ res.add(new ArrayList<>(pre));
+ }
+
+ for (int i = start; i < len; i++) {
+ pre.add(candidates[i]);
+ findCombinationSum(residue - candidates[i], i, pre);
+ pre.pop();
+ }
+ }
+
+ @Test
+ public void testCase() {
+
+ int[] candidates = {2, 3, 6, 7};
+ int target = 7;
+
+
+ System.out.println(JSONObject.toJSONString(combinationSum(candidates, target)));
+
+
+ }
+
+
+}
diff --git a/src/main/java/com/chen/algorithm/study/test39/Solution1.java b/src/main/java/com/chen/algorithm/study/test39/Solution1.java
new file mode 100644
index 0000000..8008662
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/study/test39/Solution1.java
@@ -0,0 +1,71 @@
+package com.chen.algorithm.study.test39;
+
+import com.alibaba.fastjson.JSONObject;
+import org.junit.Test;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * 不会。。。
+ *
+ * https://leetcode-cn.com/problems/combination-sum/solution/hui-su-suan-fa-jian-zhi-python-dai-ma-java-dai-m-2/
+ *
+ * @author : chen weijie
+ * @Date: 2019-11-10 18:40
+ */
+public class Solution1 {
+
+
+ /**
+ * @param candidates
+ * @param target
+ * @return
+ */
+ public List> combinationSum(int[] candidates, int target) {
+
+ List> res = new ArrayList<>();
+ List currentList = new ArrayList<>();
+ Arrays.sort(candidates);
+ findCombinationSum(candidates, target, 0, currentList, res);
+ return res;
+ }
+
+
+ private void findCombinationSum(int[] candidates, int target, int start, List currentList, List> res) {
+
+ if (target == 0) {
+ res.add(new ArrayList<>(currentList));
+ return;
+ }
+
+ if (target < 0) {
+ return;
+ }
+
+ for (int i = start; i < candidates.length; i++) {
+
+ if (target < candidates[i]) {
+ continue;
+ }
+ currentList.add(candidates[i]);
+ findCombinationSum(candidates, target - candidates[i], i, currentList, res);
+ currentList.remove(currentList.size() - 1);
+ }
+ }
+
+ @Test
+ public void testCase() {
+
+ int[] candidates = {2, 3, 6, 7};
+ int target = 7;
+
+
+ System.out.println(JSONObject.toJSONString(combinationSum(candidates, target)));
+
+
+ }
+
+
+}
diff --git a/src/main/java/com/chen/algorithm/study/test39/Solution2.java b/src/main/java/com/chen/algorithm/study/test39/Solution2.java
new file mode 100644
index 0000000..ef9cac8
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/study/test39/Solution2.java
@@ -0,0 +1,42 @@
+package com.chen.algorithm.study.test39;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Stack;
+
+/**
+ * https://leetcode-cn.com/problems/combination-sum/solution/di-gui-hui-su-tu-wen-fen-xi-ji-bai-liao-9987de-yon/
+ *
+ * @author : chen weijie
+ * @Date: 2020-08-22 19:19
+ */
+public class Solution2 {
+
+
+ public List> combinationSum(int[] candidates, int target) {
+
+ List> res = new ArrayList<>();
+ Arrays.sort(candidates);
+ backtrack(res, candidates, target, new ArrayList<>(), 0);
+ return res;
+ }
+
+ public void backtrack(List> res, int[] candidates, int target, List curList, int start) {
+ if (target == 0) {
+ res.add(new ArrayList<>(new Stack<>()));
+ return;
+ }
+
+ for (int i = start; i < candidates.length; i++) {
+ //如果当前节点大于target我们就不要选了
+ if (target < candidates[i]) {
+ continue;
+ }
+ curList.add(candidates[i]);
+ backtrack(res, candidates, (target - candidates[i]), curList, i);
+ curList.remove(curList.size() - 1);
+ }
+ }
+
+}
diff --git a/src/main/java/com/chen/algorithm/study/test40/Solution.java b/src/main/java/com/chen/algorithm/study/test40/Solution.java
new file mode 100644
index 0000000..91ecb70
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/study/test40/Solution.java
@@ -0,0 +1,68 @@
+package com.chen.algorithm.study.test40;
+
+import com.alibaba.fastjson.JSONObject;
+import org.junit.Test;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * @author : chen weijie
+ * @Date: 2020-09-18 17:21
+ */
+public class Solution {
+
+
+ public List> combinationSum2(int[] candidates, int target) {
+ List> res = new ArrayList<>();
+ if (candidates.length == 0) {
+ return res;
+ }
+ Arrays.sort(candidates);
+ backtrack(res, candidates, target, 0, new ArrayList<>());
+ return res;
+
+ }
+
+
+ private void backtrack(List> res, int[] candidates, int target, int start, List path) {
+
+ if (target == 0) {
+ res.add(new ArrayList<>(path));
+ return;
+ }
+
+ if (target < 0) {
+ return;
+ }
+
+
+ for (int i = start; i < candidates.length; i++) {
+
+ if (target < candidates[i]) {
+ break;
+ }
+
+ if (i > start && candidates[i - 1] == candidates[i]) {
+ continue;
+ }
+ path.add(candidates[i]);
+ backtrack(res, candidates, target - candidates[i], i + 1, path);
+ path.remove(path.size() - 1);
+ }
+ }
+
+ @Test
+ public void testCase() {
+ int[] nums = {10, 1, 2, 7, 6, 1, 5};
+ int target = 8;
+
+ List> res = combinationSum2(nums, target);
+
+ System.out.println(JSONObject.toJSONString(res));
+
+
+ }
+
+}
diff --git a/src/main/java/com/chen/algorithm/study/test415/Solution.java b/src/main/java/com/chen/algorithm/study/test415/Solution.java
new file mode 100644
index 0000000..433cef4
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/study/test415/Solution.java
@@ -0,0 +1,42 @@
+package com.chen.algorithm.study.test415;
+
+/**
+ * @author : chen weijie
+ * @Date: 2020-09-23 17:01
+ */
+public class Solution {
+
+ public String addStrings(String num1, String num2) {
+
+ if (num1 == null) {
+ return num2;
+ }
+
+ if (num2 == null) {
+ return num1;
+ }
+
+ int add = 0;
+ int i = num1.length() - 1, j = num2.length() - 1;
+ StringBuilder sb = new StringBuilder();
+
+ while (i >= 0 || j >= 0 || add > 0) {
+
+ if (i >= 0) {
+ add += num1.charAt(i) - '0';
+ i--;
+ }
+
+ if (j >= 0) {
+ add += num2.charAt(j) - '0';
+ j--;
+ }
+
+ sb.append(add % 10);
+ add = add / 10;
+ }
+
+
+ return sb.reverse().toString();
+ }
+}
diff --git a/src/main/java/com/chen/algorithm/study/test415/Solution36.java b/src/main/java/com/chen/algorithm/study/test415/Solution36.java
new file mode 100644
index 0000000..a09875b
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/study/test415/Solution36.java
@@ -0,0 +1,60 @@
+package com.chen.algorithm.study.test415;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.Scanner;
+
+/**
+ * @author : chen weijie
+ * @Date: 2020-09-23 17:01
+ */
+public class Solution36 {
+
+ public static void main(String[] args) {
+ Scanner scan = new Scanner(System.in);
+ String str1 = scan.next();
+ String str2 = scan.next();
+ String r = addStrings(str1, str2);
+ System.out.println(r);
+ }
+
+ public static String addStrings(String num1, String num2) {
+
+ if (num1 == null) {
+ return num2;
+ }
+
+ if (num2 == null) {
+ return num1;
+ }
+
+ Character[] chars = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'};
+ List list = Arrays.asList(chars);
+
+
+ int add = 0;
+ int i = num1.length() - 1, j = num2.length() - 1;
+ StringBuilder sb = new StringBuilder();
+
+ while (i >= 0 || j >= 0 || add > 0) {
+
+ if (i >= 0) {
+ char c = num1.charAt(i);
+ add += list.indexOf(c);
+ i--;
+ }
+
+ if (j >= 0) {
+ char c = num2.charAt(j);
+ add += list.indexOf(c);
+ j--;
+ }
+
+ sb.append(list.get(add % 36));
+ add = add / 36;
+ }
+
+
+ return sb.reverse().toString();
+ }
+}
diff --git a/src/main/java/com/chen/algorithm/study/test416/Solution.java b/src/main/java/com/chen/algorithm/study/test416/Solution.java
new file mode 100644
index 0000000..c3958b3
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/study/test416/Solution.java
@@ -0,0 +1,53 @@
+package com.chen.algorithm.study.test416;
+
+/**
+ * https://leetcode-cn.com/problems/partition-equal-subset-sum/solution/0-1-bei-bao-wen-ti-xiang-jie-zhen-dui-ben-ti-de-yo/
+ *
+ * @author : chen weijie
+ * @Date: 2020-09-22 00:45
+ */
+public class Solution {
+
+
+ public boolean canPartition(int[] nums) {
+ int len = nums.length;
+ if (len == 0) {
+ return false;
+ }
+ int sum = 0;
+ for (int num : nums) {
+ sum += num;
+ }
+
+ // 特判:如果是奇数,就不符合要求
+ if ((sum % 2) == 1) {
+ return false;
+ }
+
+ int target = sum / 2;
+ // 创建二维状态数组,行:物品索引,列:容量(包括 0)
+ boolean[][] dp = new boolean[len][target + 1];
+
+ // 先填表格第 0 行,第 1 个数只能让容积为它自己的背包恰好装满
+ if (nums[0] <= target) {
+ dp[0][nums[0]] = true;
+ }
+ // 再填表格后面几行
+ for (int i = 1; i < len; i++) {
+ for (int j = 0; j <= target; j++) {
+ // 直接从上一行先把结果抄下来,然后再修正
+ dp[i][j] = dp[i - 1][j];
+
+ if (nums[i] == j) {
+ dp[i][j] = true;
+ continue;
+ }
+ if (nums[i] < j) {
+ dp[i][j] = dp[i - 1][j] || dp[i - 1][j - nums[i]];
+ }
+ }
+ }
+ return dp[len - 1][target];
+ }
+
+}
diff --git a/src/main/java/com/chen/algorithm/study/test437/Solution.java b/src/main/java/com/chen/algorithm/study/test437/Solution.java
new file mode 100644
index 0000000..5606f48
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/study/test437/Solution.java
@@ -0,0 +1,93 @@
+package com.chen.algorithm.study.test437;
+
+import org.junit.Test;
+
+/**
+ * https://www.jianshu.com/p/2c2efb9bf25c
+ *
+ *
+ * @author : chen weijie
+ * @Date: 2019-11-03 23:25
+ */
+public class Solution {
+
+
+ class TreeNode {
+ int val;
+ TreeNode left;
+ TreeNode right;
+
+ TreeNode(int x) {
+ val = x;
+ }
+ }
+
+
+ /**
+ * 求以 root 为根的二叉树,所有和为 sum 的路径;
+ * 路径的开头不一定是 root,结尾也不一定是叶子节点;
+ *
+ * @param root
+ * @param sum
+ * @return
+ */
+
+ public int pathSum(TreeNode root, int sum) {
+ if (root == null) {
+ return 0;
+ }
+ return paths(root, sum) + pathSum(root.left, sum) + pathSum(root.right, sum);
+ }
+
+
+ private int paths(TreeNode root, int sum) {
+ if (root == null) {
+ return 0;
+ }
+
+ int res = 0;
+ if (root.val == sum) {
+ res += 1;
+ }
+ res += paths(root.left, sum - root.val);
+ res += paths(root.right, sum - root.val);
+ return res;
+ }
+
+
+
+
+ @Test
+ public void testCase(){
+
+ TreeNode treeNode3 = new TreeNode(3);
+ treeNode3.left = new TreeNode(3);
+ treeNode3.right = new TreeNode(-2);
+
+ TreeNode treeNode2 = new TreeNode(2);
+ treeNode2.right = new TreeNode(1);
+
+ TreeNode treeNode5 = new TreeNode(5);
+ treeNode5.right =treeNode2;
+ treeNode5.left =treeNode3;
+
+ TreeNode treeNode3_ = new TreeNode(-3);
+ treeNode3_.right = new TreeNode(11);
+
+ TreeNode root = new TreeNode(10);
+ root.left = treeNode5;
+ root.right = treeNode3_;
+
+ System.out.println(pathSum(root,7));
+
+ }
+
+
+
+
+
+
+
+
+
+}
diff --git a/src/main/java/com/chen/algorithm/study/test448/Solution.java b/src/main/java/com/chen/algorithm/study/test448/Solution.java
new file mode 100644
index 0000000..e31b14f
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/study/test448/Solution.java
@@ -0,0 +1,63 @@
+package com.chen.algorithm.study.test448;
+
+import org.junit.Test;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * https://leetcode-cn.com/problems/find-all-numbers-disappeared-in-an-array/solution/e-wai-liang-ge-intkong-jian-shi-jian-fu-za-du-jin-/
+ *
+ * 不会。。。。。
+ *
+ * @author : chen weijie
+ * @Date: 2019-11-04 00:06
+ * @@Description: zhunn 找到所有数组中消失的数字
+ */
+public class Solution {
+
+
+ public List findDisappearedNumbers(int[] nums) {
+
+ int temp = 0;
+ int nextIndex = 0;
+
+ for (int i = 0; i < nums.length; i++) {
+
+ if (nums[i] > 0) {
+ temp = nums[i];
+ while (temp > 0) {
+ nums[i] = 0;
+ nextIndex = nums[temp - 1];
+ nums[temp - 1] = -1;
+ temp = nextIndex;
+ }
+ }
+
+ }
+
+
+ List result = new ArrayList<>();
+
+ for (int i = 0; i < nums.length; i++) {
+ if (nums[i] == 0) {
+ result.add(i + 1);
+ }
+ }
+
+ return result;
+ }
+
+
+ @Test
+ public void testCase() {
+
+ int[] nums = {4, 3, 2, 7, 8, 2, 3, 1};
+
+ List list = findDisappearedNumbers(nums);
+ list.forEach(System.out::println);
+
+ }
+
+
+}
diff --git a/src/main/java/com/chen/algorithm/study/test46/Solution.java b/src/main/java/com/chen/algorithm/study/test46/Solution.java
new file mode 100644
index 0000000..d7f743f
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/study/test46/Solution.java
@@ -0,0 +1,65 @@
+package com.chen.algorithm.study.test46;
+
+import com.alibaba.fastjson.JSONObject;
+import org.junit.Test;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.LinkedList;
+import java.util.List;
+
+/**
+ * 题解都没看懂
+ *
+ * https://leetcode-cn.com/problems/permutations/solution/hui-su-suan-fa-python-dai-ma-java-dai-ma-by-liweiw/
+ *
+ * @author : chen weijie
+ * @Date: 2019-11-10 19:23
+ */
+public class Solution {
+
+
+ public List> permute(int[] nums) {
+
+ List> output = new LinkedList();
+ ArrayList nums_lst = new ArrayList<>();
+
+ for (int num : nums) {
+ nums_lst.add(num);
+ }
+
+ int n = nums.length;
+ backtrack(n, nums_lst, output, 0);
+ return output;
+
+ }
+
+ public void backtrack(int n, ArrayList nums_lst,
+ List> output,
+ int first) {
+
+ if (first == n) {
+ output.add(new ArrayList<>(nums_lst));
+ return;
+ }
+
+ for (int i = first; i < n; i++) {
+ Collections.swap(nums_lst, first, i);
+ backtrack(n, nums_lst, output, first + 1);
+ Collections.swap(nums_lst, first, i);
+ }
+ }
+
+
+ @Test
+ public void testCase() {
+
+ int[] ints = {1, 2, 3};
+
+ System.out.println(JSONObject.toJSONString(permute(ints)));
+
+
+ }
+
+
+}
diff --git a/src/main/java/com/chen/algorithm/study/test46/Solution1.java b/src/main/java/com/chen/algorithm/study/test46/Solution1.java
new file mode 100644
index 0000000..1c50944
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/study/test46/Solution1.java
@@ -0,0 +1,59 @@
+package com.chen.algorithm.study.test46;
+
+import com.alibaba.fastjson.JSONObject;
+import org.junit.Test;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * 题解都没看懂
+ *
+ * https://leetcode-cn.com/problems/permutations/solution/hui-su-suan-fa-python-dai-ma-java-dai-ma-by-liweiw/
+ *
+ * @author : chen weijie
+ * @Date: 2019-11-10 19:23
+ */
+public class Solution1 {
+
+
+ public List> permute(int[] nums) {
+
+ List> output = new ArrayList<>();
+ boolean[] used = new boolean[nums.length];
+ backtrack(output, used, new ArrayList<>(), nums);
+ return output;
+
+ }
+
+ public void backtrack(List> output, boolean[] used, List current, int[] nums) {
+
+ if (current.size() == nums.length) {
+ output.add(new ArrayList<>(current));
+ return;
+ }
+
+ for (int i = 0; i < nums.length; i++) {
+ if (!used[i]) {
+ current.add(nums[i]);
+ used[i] = true;
+ backtrack(output, used, current, nums);
+ used[i] = false;
+ current.remove(current.size() - 1);
+ }
+ }
+ }
+
+
+ @Test
+ public void testCase() {
+
+ int[] ints = {1, 2, 3};
+
+ System.out.println(JSONObject.toJSONString(permute(ints)));
+
+
+ }
+
+
+}
diff --git a/src/main/java/com/chen/algorithm/study/test46/Solution2.java b/src/main/java/com/chen/algorithm/study/test46/Solution2.java
new file mode 100644
index 0000000..91dce8b
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/study/test46/Solution2.java
@@ -0,0 +1,70 @@
+package com.chen.algorithm.study.test46;
+
+import org.junit.Test;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * https://leetcode-cn.com/problems/permutations/solution/hui-su-suan-fa-python-dai-ma-java-dai-ma-by-liweiw/
+ *
+ *
+ * 回溯算法的框架:
+ *
+ * result = []
+ * def backtrack(路径, 选择列表):
+ * if 满足结束条件:
+ * result.add(路径)
+ * return
+ *
+ * for 选择 in 选择列表:
+ * 做选择
+ * backtrack(路径, 选择列表)
+ * 撤销选择
+ *
+ *
+ * @author : chen weijie
+ * @Date: 2020-08-05 15:38
+ */
+public class Solution2 {
+
+
+ public List> permute(int[] array) {
+
+ List> res = new ArrayList<>();
+ boolean[] used = new boolean[array.length];
+ backtrack(array, 0, array.length, res, new ArrayList<>(), used);
+ return res;
+ }
+
+
+ private void backtrack(int[] nums, int depth, int len, List> res, List path, boolean[] used) {
+
+ if (depth == len) {
+ res.add(new ArrayList<>(path));
+ return;
+ }
+
+ for (int i = 0; i < len; i++) {
+
+ if (!used[i]) {
+ path.add(nums[i]);
+ used[i] = true;
+
+ backtrack(nums, depth + 1, len, res, path, used);
+ // 注意:这里是状态重置,是从深层结点回到浅层结点的过程,代码在形式上和递归之前是对称的
+ path.remove(path.size() - 1);
+ used[i] = false;
+ }
+ }
+ }
+
+ @Test
+ public void testCase() {
+ int[] nums = {1, 2, 3};
+ List> lists = permute(nums);
+ System.out.println(lists);
+ }
+
+
+}
diff --git a/src/main/java/com/chen/algorithm/study/test461/Solution.java b/src/main/java/com/chen/algorithm/study/test461/Solution.java
new file mode 100644
index 0000000..00b0ee3
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/study/test461/Solution.java
@@ -0,0 +1,28 @@
+package com.chen.algorithm.study.test461;
+
+import org.junit.Test;
+
+/**
+ * https://leetcode-cn.com/problems/hamming-distance/solution/yi-huo-cao-zuo-by-zhang-heng-6/
+ *
+ * @author : chen weijie
+ * @Date: 2019-11-04 22:51
+ */
+public class Solution {
+
+
+ public int hammingDistance(int x, int y) {
+
+ int n = x ^ y;
+
+ return Integer.bitCount(n);
+ }
+
+
+ @Test
+ public void testCase() {
+
+ System.out.println(hammingDistance(1, 4));
+ }
+
+}
diff --git a/src/main/java/com/chen/algorithm/study/test48/Solution.java b/src/main/java/com/chen/algorithm/study/test48/Solution.java
new file mode 100644
index 0000000..82981f5
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/study/test48/Solution.java
@@ -0,0 +1,56 @@
+package com.chen.algorithm.study.test48;
+
+import com.alibaba.fastjson.JSONObject;
+import org.junit.Test;
+
+/**
+ * @author : chen weijie
+ * @Date: 2019-11-12 00:04
+ * @Description: zhunn 顺时针旋转图像90°
+ */
+public class Solution {
+
+
+ public void rotate(int[][] matrix) {
+
+ int n = matrix.length;
+ int m = matrix[0].length;
+
+ //先转置
+ for (int i = 0; i < n; i++) {
+ for (int j = i; j < m; j++) {
+ int temp = matrix[j][i];
+ matrix[j][i] = matrix[i][j];
+ matrix[i][j] = temp;
+ System.out.println("=====" + JSONObject.toJSONString(matrix));
+ }
+ }
+
+ // 反转每一行
+ for (int i = 0; i < n; i++) {
+ for (int j = 0; j < m / 2; j++) {
+ int temp = matrix[i][j];
+ matrix[i][j] = matrix[i][m - j - 1];
+ matrix[i][m - j - 1] = temp;
+ }
+ }
+ }
+
+
+ @Test
+ public void testCase() {
+
+ int[][] matrix = new int[3][3];
+
+ matrix[0] = new int[]{1, 2, 3};
+ matrix[1] = new int[]{4, 5, 6};
+ matrix[2] = new int[]{7, 8, 9};
+
+ rotate(matrix);
+
+ System.out.println("last:" + JSONObject.toJSONString(matrix));
+
+ }
+
+
+}
diff --git a/src/main/java/com/chen/algorithm/study/test49/Solution.java b/src/main/java/com/chen/algorithm/study/test49/Solution.java
new file mode 100644
index 0000000..0a71fdc
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/study/test49/Solution.java
@@ -0,0 +1,50 @@
+package com.chen.algorithm.study.test49;
+
+import java.util.*;
+
+/**
+ * @author : chen weijie
+ * @Date: 2019-11-12 00:34
+ */
+public class Solution {
+
+ public List> groupAnagrams(String[] strs) {
+
+ Map> map = new HashMap<>();
+
+ for (String str : strs) {
+
+ char[] chars = str.toCharArray();
+ Arrays.sort(chars);
+ String key = new String(chars);
+
+ if (!map.containsKey(key)) {
+ map.put(key, new ArrayList<>());
+ }
+ map.get(key).add(str);
+ }
+
+ return new ArrayList<>(map.values());
+ }
+
+ public List> isValid(String[] strs) {
+
+ Map> res = new HashMap<>();
+ for (String str : strs) {
+ char[] chars = str.toCharArray();
+ Arrays.sort(chars);
+ String s = new String(chars);
+
+ if (!res.containsKey(s)) {
+ res.put(s, new ArrayList<>());
+ }
+ res.get(s).add(str);
+
+
+ }
+
+ return new ArrayList<>(res.values());
+ }
+
+
+}
diff --git a/src/main/java/com/chen/algorithm/study/test496/Solution.java b/src/main/java/com/chen/algorithm/study/test496/Solution.java
new file mode 100644
index 0000000..b13359f
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/study/test496/Solution.java
@@ -0,0 +1,36 @@
+package com.chen.algorithm.study.test496;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Stack;
+
+/**
+ * @author : chen weijie
+ * @Date: 2020-09-27 01:31
+ */
+public class Solution {
+
+ public int[] nextGreaterElement(int[] nums1, int[] nums2) {
+
+ Map nextGreatMap = new HashMap<>();
+ Stack stack = new Stack<>();
+
+ for (int i = 0; i < nums2.length; i++) {
+ int num = nums2[i];
+
+ while (!stack.isEmpty() && stack.peek() <= num) {
+ nextGreatMap.put(stack.pop(), num);
+ }
+ stack.push(num);
+ }
+
+ while (!stack.isEmpty()) {
+ nextGreatMap.put(stack.pop(), -1);
+ }
+
+ for (int i = 0; i < nums1.length; i++) {
+ nums1[i] = nextGreatMap.getOrDefault(nums1[i], -1);
+ }
+ return nums1;
+ }
+}
diff --git a/src/main/java/com/chen/algorithm/study/test496/Solution1.java b/src/main/java/com/chen/algorithm/study/test496/Solution1.java
new file mode 100644
index 0000000..e1f2bb9
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/study/test496/Solution1.java
@@ -0,0 +1,35 @@
+package com.chen.algorithm.study.test496;
+
+import java.util.*;
+
+/**
+ * @author : chen weijie
+ * @Date: 2020-09-27 01:31
+ */
+public class Solution1 {
+
+ public int[] nextGreaterElement(int[] nums1, int[] nums2) {
+
+ Map map = new HashMap<>();
+ Stack stack = new Stack<>();
+
+ for (int i = 0; i < nums2.length; i++) {
+ int num = nums2[i];
+ while (!stack.isEmpty() && stack.peek()
+ * 递归
+ *
+ * @author : chen weijie
+ * @Date: 2020-05-16 22:50
+ */
+public class Solution {
+
+
+ public double myPow(double x, int n) {
+
+ long N = n;
+ if (N < 0) {
+ x = 1 / x;
+ N = -N;
+ }
+
+ double result = 1d;
+ double contribute = x;
+
+ while (N > 0) {
+ if (N % 2 == 1) {
+ result = result * contribute;
+ }
+ contribute = contribute * contribute;
+
+ N = N / 2;
+ }
+
+ return result;
+
+ }
+
+}
+
diff --git a/src/main/java/com/chen/algorithm/study/test50/Solution1.java b/src/main/java/com/chen/algorithm/study/test50/Solution1.java
new file mode 100644
index 0000000..4d23218
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/study/test50/Solution1.java
@@ -0,0 +1,44 @@
+package com.chen.algorithm.study.test50;
+
+import org.junit.Test;
+
+/**
+ * 链接:https://leetcode-cn.com/problems/powx-n/solution/powx-n-by-leetcode-solution/
+ *
+ *
+ * @author : chen weijie
+ * @Date: 2020-05-16 22:50
+ */
+public class Solution1 {
+
+
+ public double myPow(double x, int n) {
+
+ long N = n;
+
+ if (N < 0) {
+ N = 1 / N;
+ x = -x;
+ }
+
+ double contribution = x;
+ double res = 1d;
+
+ while (N > 0) {
+ if (N % 2 == 1) {
+ res = res * contribution;
+ }
+ contribution = contribution * contribution;
+ N = N / 2;
+ }
+ return res;
+ }
+
+ @Test
+ public void testCase(){
+ System.out.println(myPow(2.0,4));
+ }
+
+
+}
+
diff --git a/src/main/java/com/chen/algorithm/study/test50/Solution2.java b/src/main/java/com/chen/algorithm/study/test50/Solution2.java
new file mode 100644
index 0000000..6f0db56
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/study/test50/Solution2.java
@@ -0,0 +1,35 @@
+package com.chen.algorithm.study.test50;
+
+import org.junit.Test;
+
+/**
+ * @author : chen weijie
+ * @Date: 2020-05-16 23:15
+ */
+public class Solution2 {
+
+ public double myPow(double x, int n) {
+ long N = n;
+ if (N < 0) {
+ x = 1 / x;
+ N = -N;
+ }
+ double result = 1.0d;
+ double x_contribution = x;
+ while (N > 0) {
+ if (N % 2 == 1) {
+ result = result * x_contribution;
+ }
+
+ x_contribution = x_contribution * x_contribution;
+ N = N / 2;
+ }
+ return result;
+ }
+
+
+ @Test
+ public void testCase(){
+ System.out.println(myPow(2.0,5));
+ }
+}
diff --git a/src/main/java/com/chen/algorithm/study/test50/Solution3.java b/src/main/java/com/chen/algorithm/study/test50/Solution3.java
new file mode 100644
index 0000000..6dc36cc
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/study/test50/Solution3.java
@@ -0,0 +1,31 @@
+package com.chen.algorithm.study.test50;
+
+/**
+ * @author : chen weijie
+ * @Date: 2020-05-22 02:52
+ */
+public class Solution3 {
+
+
+ public double myPow(double x, int n) {
+
+
+ if (n < 0) {
+ x = 1 / x;
+ n = -n;
+ }
+ return quick(x, n);
+ }
+
+
+ public double quick(double x, int n) {
+
+ if (n == 0) {
+ return 1d;
+ }
+ double y = quick(x, n / 2);
+ return n % 2 == 0 ? y * y : y * y * x;
+ }
+
+
+}
diff --git a/src/main/java/com/chen/algorithm/study/test51/Solution.java b/src/main/java/com/chen/algorithm/study/test51/Solution.java
new file mode 100644
index 0000000..a16ca20
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/study/test51/Solution.java
@@ -0,0 +1,92 @@
+package com.chen.algorithm.study.test51;
+
+import com.alibaba.fastjson.JSONObject;
+import org.junit.Test;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Stack;
+
+/**
+ * https://leetcode-cn.com/problems/n-queens/solution/gen-ju-di-46-ti-quan-pai-lie-de-hui-su-suan-fa-si-/
+ *
+ * @author : chen weijie
+ * @Date: 2020-05-17 02:44
+ */
+public class Solution {
+
+
+ private boolean[] col;
+ private boolean[] master;
+ private boolean[] slave;
+ private int n;
+ private List> res;
+
+
+ public List> solveNQueues(int n) {
+ this.n = n;
+ res = new ArrayList<>();
+ if (n == 0) {
+ return res;
+ }
+ col = new boolean[n];
+ master = new boolean[2 * n - 1];
+ slave = new boolean[2 * n - 1];
+ Stack stack = new Stack<>();
+ helper(0, stack);
+ return res;
+ }
+
+
+ public void helper(int row, Stack stack) {
+
+ if (row == n) {
+ List board = convert2board(stack, n);
+ res.add(board);
+ return;
+ }
+
+ // 针对每一列,尝试是否可以放置
+ for (int i = 0; i < n; i++) {
+ if (!col[i] && !master[row + i] && !slave[row - i + n - 1]) {
+ stack.push(i);
+ col[i] = true;
+ master[row + i] = true;
+ slave[row - i + n - 1] = true;
+ helper(row + 1, stack);
+ slave[row - i + n - 1] = false;
+ master[row + i] = false;
+ col[i] = false;
+ stack.pop();
+ }
+ }
+ }
+
+ public List convert2board(Stack stack, int n) {
+
+ List board = new ArrayList<>();
+ for (Integer num : stack) {
+ StringBuilder sb = new StringBuilder();
+
+ for (int i = 0; i < n; i++) {
+ sb.append("*");
+ }
+ sb.replace(num, num + 1, "Q");
+ board.add(sb.toString());
+ }
+ return board;
+ }
+
+
+ @Test
+ public void testCase() {
+ List> res = solveNQueues(4);
+
+ for (List re : res) {
+ System.out.println("====" + JSONObject.toJSONString(re));
+ }
+
+ }
+
+
+}
diff --git a/src/main/java/com/chen/algorithm/study/test518/Solution.java b/src/main/java/com/chen/algorithm/study/test518/Solution.java
new file mode 100644
index 0000000..464c281
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/study/test518/Solution.java
@@ -0,0 +1,28 @@
+package com.chen.algorithm.study.test518;
+
+/**
+ * https://leetcode-cn.com/problems/coin-change-2/solution/ling-qian-dui-huan-iihe-pa-lou-ti-wen-ti-dao-di-yo/
+ *
+ * @author : chen weijie
+ * @Date: 2020-09-22 01:10
+ */
+public class Solution {
+
+
+ public int change(int amount, int[] coins) {
+ int[] dp = new int[amount + 1];
+ dp[0] = 1;
+
+ for (int coin : coins) { //枚举硬币
+ for (int i = 1; i <= amount; i++) { //枚举金额
+ if (i < coin) {
+ continue; // coin不能大于amount
+ }
+ dp[i] = dp[i - coin] + dp[i];
+ }
+ }
+ return dp[amount];
+
+
+ }
+}
diff --git a/src/main/java/com/chen/algorithm/study/test53/Solution.java b/src/main/java/com/chen/algorithm/study/test53/Solution.java
new file mode 100644
index 0000000..8117344
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/study/test53/Solution.java
@@ -0,0 +1,49 @@
+package com.chen.algorithm.study.test53;
+
+import org.junit.Test;
+
+/**
+ * @author : chen weijie
+ * @Date: 2019-10-21 22:50
+ */
+public class Solution {
+
+ public int maxSubArray(int[] nums) {
+
+ int max = nums[0]; // 保存最大的结果
+ int sum = 0; // 保存当前的子序和
+
+ for (int num : nums) {
+ if (sum > 0) { // sum是正数,意味着后面有机会再创新高,可以继续加
+ sum += num;
+ } else { // sum是负的,还不如直接从当前位重新开始算,也比(负数+当前值)要大吧
+ sum = num;
+ }
+ max = Math.max(max, sum); // 每一步都更新最大值
+ }
+ return max;
+ }
+
+
+ public int maxSubArray2(int[] nums) {
+
+ int[] dp = new int[nums.length];
+ dp[0] = nums[0];
+ int max = dp[0];
+ for (int i = 1; i < nums.length; i++) {
+ dp[i] = Math.max(dp[i - 1] + nums[i], nums[i]);
+ max = Math.max(dp[i], max);
+ }
+ return max;
+ }
+
+
+ @Test
+ public void testCase() {
+
+ int nums[] = {-2, 1, -3, 4, -1, 2, 1, -5, 4};
+ System.out.println(maxSubArray2(nums));
+ }
+
+
+}
diff --git a/src/main/java/com/chen/algorithm/study/test53/Solution1Test.java b/src/main/java/com/chen/algorithm/study/test53/Solution1Test.java
new file mode 100644
index 0000000..bd27c68
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/study/test53/Solution1Test.java
@@ -0,0 +1,36 @@
+package com.chen.algorithm.study.test53;
+
+import org.junit.Test;
+
+/**
+ * @author : chen weijie
+ * @Date: 2019-10-21 23:44
+ */
+public class Solution1Test {
+
+
+ public int maxSubArray(int[] nums) {
+
+ int max = 0, sum = 0;
+
+ for (int num : nums) {
+ sum = Math.max(0, sum);
+ sum = sum + num;
+ max = Math.max(sum, max);
+ }
+ return max;
+ }
+
+
+ @Test
+ public void testCase() {
+
+
+ int nums[] = {-2, 1, -3, 4, -1, 2, 1, -5, 4};
+ System.out.println(maxSubArray(nums));
+
+
+ }
+
+
+}
diff --git a/src/main/java/com/chen/algorithm/study/test538/Solution.java b/src/main/java/com/chen/algorithm/study/test538/Solution.java
new file mode 100644
index 0000000..f931990
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/study/test538/Solution.java
@@ -0,0 +1,36 @@
+package com.chen.algorithm.study.test538;
+
+/**
+ * https://leetcode-cn.com/problems/convert-bst-to-greater-tree/solution/ba-er-cha-sou-suo-shu-zhuan-huan-wei-lei-jia-shu-3/
+ * 难
+ * @author : chen weijie
+ * @Date: 2019-11-04 23:27
+ */
+public class Solution {
+
+
+ class TreeNode {
+ int val;
+ TreeNode left;
+ TreeNode right;
+
+ TreeNode(int x) {
+ val = x;
+ }
+ }
+
+ int sum = 0;
+
+ public TreeNode convertBST(TreeNode root) {
+
+ if (root != null) {
+ convertBST(root.right);
+ sum += root.val;
+ root.val = sum;
+ convertBST(root.left);
+ }
+ return root;
+ }
+
+
+}
diff --git a/src/main/java/com/chen/algorithm/study/test543/Solution.java b/src/main/java/com/chen/algorithm/study/test543/Solution.java
new file mode 100644
index 0000000..83f369c
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/study/test543/Solution.java
@@ -0,0 +1,51 @@
+package com.chen.algorithm.study.test543;
+
+/**
+ *
+ * https://leetcode-cn.com/problems/diameter-of-binary-tree/solution/javade-di-gui-jie-fa-by-lyl0724-2/
+ *
+ * @author : chen weijie
+ * @Date: 2019-11-04 23:58
+ */
+public class Solution {
+
+ class TreeNode {
+ int val;
+ TreeNode left;
+ TreeNode right;
+
+ TreeNode(int x) {
+ val = x;
+ }
+ }
+
+
+// 一个节点的最大直径 = 它左树的高度 + 它右树的高度
+
+ private int max;
+
+
+ public int diameterOfBinaryTree(TreeNode root) {
+ depth(root);
+ return max;
+ }
+
+
+ private int depth(TreeNode root) {
+
+ if (root == null) {
+ return 0;
+ }
+
+ int leftDepth = depth(root.left);
+ int rightDepth = depth(root.right);
+
+ //max记录当前的最大直径
+ max = Math.max(leftDepth + rightDepth, max);
+ //由于我计算的直径是左树高度+右树高度,所以这里返回当前树的高度,以供使用
+ return Math.max(leftDepth, rightDepth) + 1;
+ }
+
+
+
+}
diff --git a/src/main/java/com/chen/algorithm/study/test55/Solution.java b/src/main/java/com/chen/algorithm/study/test55/Solution.java
new file mode 100644
index 0000000..d451653
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/study/test55/Solution.java
@@ -0,0 +1,49 @@
+package com.chen.algorithm.study.test55;
+
+import org.junit.Test;
+
+/**
+ * https://leetcode-cn.com/problems/jump-game/solution/dong-tai-gui-hua-yu-tan-xin-suan-fa-jie-jue-ci-wen/
+ *
+ *
+ * 我们记录一个的坐标代表当前可达的最后节点,这个坐标初始等于nums.length-1,
+ * 然后我们每判断完是否可达,都向前移动这个坐标,直到遍历结束。
+ *
+ * 如果这个坐标等于0,那么认为可达,否则不可达。
+ *
+ * @author : chen weijie
+ * @Date: 2019-11-13 00:26
+ */
+public class Solution {
+
+ public boolean canJump(int[] nums) {
+
+
+ if (nums == null) {
+ return false;
+ }
+
+ int lastPosition = nums.length - 1;
+
+ for (int i = nums.length - 1; i >= 0; i--) {
+ // 逐步向前递推
+ if (nums[i] + i >= lastPosition) {
+ lastPosition = i;
+ }
+ }
+
+ return lastPosition == 0;
+ }
+
+
+ @Test
+ public void testCase() {
+
+ int[] n = {3, 2, 1, 1, 4};
+
+ System.out.println(canJump(n));
+
+ }
+
+
+}
diff --git a/src/main/java/com/chen/algorithm/study/test56/Solution.java b/src/main/java/com/chen/algorithm/study/test56/Solution.java
new file mode 100644
index 0000000..1dd707b
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/study/test56/Solution.java
@@ -0,0 +1,69 @@
+package com.chen.algorithm.study.test56;
+
+import com.alibaba.fastjson.JSONObject;
+import org.junit.Test;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * https://leetcode-cn.com/problems/merge-intervals/solution/pai-xu-by-powcai/
+ *
+ * @author : chen weijie
+ * @Date: 2019-11-14 00:22
+ * @Description: zhunn 合并区间
+ */
+public class Solution {
+
+
+ /**
+ * 先按首位置进行排序;
+ *
+ * 接下来,如何判断两个区间是否重叠呢?比如 a = [1,4],b = [2,3]
+ * 当 a[1] >= b[0] 说明两个区间有重叠.
+ * 但是如何把这个区间找出来呢?
+ * 左边位置一定是确定,就是 a[0],而右边位置是 max(a[1], b[1])
+ * 所以,我们就能找出整个区间为:[1,4]
+ *
+ * @param intervals
+ * @return
+ */
+
+ public int[][] merge(int[][] intervals) {
+
+ List inner = Arrays.asList(intervals);
+ List newInner = new ArrayList<>(inner);
+ newInner.sort((o1,o2)-> o1[0]-o2[0]);
+
+ List res = new ArrayList<>();
+
+ for (int i = 0; i < newInner.size(); ) {
+ int t = newInner.get(i)[1];
+ int j = i + 1;
+ while (j < newInner.size() && newInner.get(j)[0] <= t) {
+ t = Math.max(t, newInner.get(j)[1]);
+ j++;
+ }
+ res.add(new int[]{newInner.get(i)[0], t});
+ i = j;
+ }
+
+ int[][] array = new int[res.size()][2];
+
+ for (int i = 0; i < res.size(); i++) {
+ array[i][0] = res.get(i)[0];
+ array[i][1] = res.get(i)[1];
+ }
+ return array;
+ }
+
+
+ @Test
+ public void testCase() {
+
+ int[][] n = {{1, 3}, {2, 6}, {15, 18}, {8, 10}};
+ System.out.println(JSONObject.toJSONString(merge(n)));
+ }
+
+}
diff --git a/src/main/java/com/chen/algorithm/study/test56/Solution2.java b/src/main/java/com/chen/algorithm/study/test56/Solution2.java
new file mode 100644
index 0000000..aba3c63
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/study/test56/Solution2.java
@@ -0,0 +1,65 @@
+package com.chen.algorithm.study.test56;
+
+import com.alibaba.fastjson.JSONObject;
+import org.junit.Test;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * https://leetcode-cn.com/problems/merge-intervals/solution/merge-intervals-by-ikaruga/
+ *
+ * 对 vector> 排序,需要按照先比较区间开始,如果相同再比较区间结束,使用默认的排序规则即可
+ * 使用双指针,左边指针指向当前区间的开始
+ * 使用一个变量来记录连续的范围 t
+ * 右指针开始往后寻找,如果后续的区间的开始值比 t 还小,说明重复了,可以归并到一起
+ * 此时更新更大的结束值到 t
+ * 直到区间断开,将 t 作为区间结束,存储到答案里
+ * 然后移动左指针,跳过中间已经合并的区间
+ *
+ * @author : chen weijie
+ * @Date: 2020-09-15 00:04
+ */
+public class Solution2 {
+
+
+ public int[][] merge(int[][] intervals) {
+
+ List inter = Arrays.asList(intervals);
+ List newInter = new ArrayList<>(inter);
+
+ newInter.sort((o1, o2) -> o1[0] - o2[0]);
+
+ List res = new ArrayList<>();
+
+ for (int i = 0; i < newInter.size(); ) {
+ int t = newInter.get(i)[1];
+ int j = i + 1;
+
+ while (j < newInter.size() && newInter.get(j)[0] <= t) {
+ t = Math.max(t, newInter.get(j)[1]);
+ j++;
+ }
+
+ res.add(new int[]{newInter.get(i)[0], t});
+ i = j;
+ }
+
+ int[][] ans = new int[res.size()][2];
+ for (int i = 0; i < res.size(); i++) {
+ ans[i][0] = res.get(i)[0];
+ ans[i][1] = res.get(i)[1];
+ }
+
+ return ans;
+
+ }
+
+ @Test
+ public void testCase() {
+
+ int[][] n = {{1, 3}, {2, 6}, {15, 18}, {8, 10}};
+ System.out.println(JSONObject.toJSONString(merge(n)));
+ }
+}
diff --git a/src/main/java/com/chen/algorithm/study/test581/Solution.java b/src/main/java/com/chen/algorithm/study/test581/Solution.java
new file mode 100644
index 0000000..32b35e4
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/study/test581/Solution.java
@@ -0,0 +1,48 @@
+package com.chen.algorithm.study.test581;
+
+import org.junit.Test;
+
+import java.util.Arrays;
+
+/**
+ *
+ * https://leetcode-cn.com/problems/shortest-unsorted-continuous-subarray/solution/zui-duan-wu-xu-lian-xu-zi-shu-zu-by-leetcode/
+ *
+ * @author : chen weijie
+ * @Date: 2019-11-07 23:34
+ * @Description: zhunn 最短无序连续子数组
+ */
+public class Solution {
+
+
+ public int findUnsortedSubarray(int[] nums) {
+ if(nums == null || nums.length == 0){
+ return 0;
+ }
+
+ int[] snums = nums.clone();
+ Arrays.sort(snums);
+ int start = snums.length, end = 0;
+ for (int i = 0; i < snums.length; i++) {
+ if (snums[i] != nums[i]) {
+ start = Math.min(start, i);
+ end = Math.max(end, i);
+ }
+ }
+ return (end - start >= 0 ? end - start + 1 : 0);
+ }
+
+
+ @Test
+ public void testCase() {
+
+
+ int[] n = {2, 6, 4, 8, 10, 9, 15};
+
+ System.out.println(findUnsortedSubarray(n));
+
+
+ }
+
+
+}
diff --git a/src/main/java/com/chen/algorithm/study/test581/Solution1.java b/src/main/java/com/chen/algorithm/study/test581/Solution1.java
new file mode 100644
index 0000000..5189075
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/study/test581/Solution1.java
@@ -0,0 +1,43 @@
+package com.chen.algorithm.study.test581;
+
+import org.junit.Test;
+
+/**
+ * https://leetcode-cn.com/problems/shortest-unsorted-continuous-subarray/solution/zui-duan-wu-xu-lian-xu-zi-shu-zu-by-leetcode/
+ *
+ * @author : chen weijie
+ * @Date: 2019-11-07 23:34
+ */
+public class Solution1 {
+
+
+ public int findUnsortedSubarray(int[] nums) {
+
+ int l = nums.length, r = 0;
+
+ for (int i = 0; i < nums.length - 1; i++) {
+ for (int j = i + 1; j < nums.length; j++) {
+ if (nums[j] < nums[i]) {
+ r = Math.max(r, j);
+ l = Math.min(l, i);
+ }
+ }
+ }
+
+ return r - l < 0 ? 0 : r - l + 1;
+ }
+
+
+ @Test
+ public void testCase() {
+
+
+ int[] n = {2, 6, 4, 8, 10, 9, 15};
+
+ System.out.println(findUnsortedSubarray(n));
+
+
+ }
+
+
+}
diff --git a/src/main/java/com/chen/algorithm/study/test617/Solution.java b/src/main/java/com/chen/algorithm/study/test617/Solution.java
new file mode 100644
index 0000000..a7d76e2
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/study/test617/Solution.java
@@ -0,0 +1,37 @@
+package com.chen.algorithm.study.test617;
+
+/**
+ * @author : chen weijie
+ * @Date: 2019-11-08 00:22
+ */
+public class Solution {
+
+
+ public class TreeNode {
+ int val;
+ TreeNode left;
+ TreeNode right;
+
+ TreeNode(int x) {
+ val = x;
+ }
+ }
+
+
+ public TreeNode mergeTrees(TreeNode t1, TreeNode t2) {
+
+ if (t1 == null) {
+ return t2;
+ }
+ if (t2 == null) {
+ return t1;
+ }
+
+ t1.val += t2.val;
+ t1.left = mergeTrees(t1.left, t2.left);
+ t1.right = mergeTrees(t1.right, t2.right);
+ return t1;
+ }
+
+
+}
diff --git a/src/main/java/com/chen/algorithm/study/test62/Solution.java b/src/main/java/com/chen/algorithm/study/test62/Solution.java
new file mode 100644
index 0000000..48dd361
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/study/test62/Solution.java
@@ -0,0 +1,29 @@
+package com.chen.algorithm.study.test62;
+
+/**
+ * @author : chen weijie
+ * @Date: 2019-11-14 01:01
+ */
+public class Solution {
+
+
+ public int uniquePaths(int m, int n) {
+
+ int[][] dp = new int[m][n];
+ for (int i = 0; i < m; i++) {
+ dp[i][0] = 1;
+ }
+
+ for (int i = 0; i < n; i++) {
+ dp[0][i] = 1;
+ }
+ for (int i = 1; i < m; i++) {
+ for (int j = 1; j < n; j++) {
+ dp[i][j] = dp[i - 1][j] + dp[i][j - 1];
+ }
+ }
+ return dp[m - 1][n - 1];
+ }
+
+
+}
diff --git a/src/main/java/com/chen/algorithm/study/test64/Solution.java b/src/main/java/com/chen/algorithm/study/test64/Solution.java
new file mode 100644
index 0000000..b4e9584
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/study/test64/Solution.java
@@ -0,0 +1,36 @@
+package com.chen.algorithm.study.test64;
+
+/**
+ * 动态规划
+ *
+ * @author : chen weijie
+ * @Date: 2019-11-19 00:25
+ */
+public class Solution {
+
+
+ public int minPathSum(int[][] grid) {
+
+
+ int[][] dp = new int[grid.length][grid[0].length];
+ for (int i = grid.length - 1; i >= 0; i--) {
+ for (int j = grid[0].length - 1; j >= 0; j--) {
+ if (i == grid.length - 1 && j != grid[0].length - 1) {
+ dp[i][j] = grid[i][j] + dp[i][j + 1];
+
+ } else if (j == grid[0].length - 1 && i != grid.length - 1) {
+ dp[i][j] = grid[i][j] + dp[i + 1][j];
+
+ } else if (j != grid[0].length - 1 && i != grid.length - 1) {
+
+ dp[i][j] = grid[i][j] + Math.min(dp[i + 1][j], dp[i][j + 1]);
+ } else {
+ dp[i][j] = grid[i][j];
+ }
+ }
+ }
+ return dp[0][0];
+ }
+
+
+}
diff --git a/src/main/java/com/chen/algorithm/study/test64/Solution1.java b/src/main/java/com/chen/algorithm/study/test64/Solution1.java
new file mode 100644
index 0000000..8df59de
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/study/test64/Solution1.java
@@ -0,0 +1,48 @@
+package com.chen.algorithm.study.test64;
+
+import org.junit.Test;
+
+/**
+ * https://leetcode-cn.com/problems/minimum-path-sum/solution/zui-xiao-lu-jing-he-dong-tai-gui-hua-gui-fan-liu-c/
+ *
+ * @author : chen weijie
+ * @Date: 2020-05-13 00:02
+ */
+public class Solution1 {
+
+ public int minPathSum(int[][] grid) {
+
+ if (grid.length == 0) {
+ return 0;
+ }
+
+ int row = grid.length;
+ int clomn = grid[0].length;
+
+// int[][] grid = new int[row][clomn];
+ for (int i = 0; i < row; i++) {
+ for (int j = 0; j < clomn; j++) {
+ if (i == 0 && j == 0) {
+ continue;
+ } else if (i == 0) {
+ grid[i][j] = grid[i][j] + grid[i][j - 1];
+ } else if (j == 0) {
+ grid[i][j] = grid[i][j] + grid[i - 1][j];
+ } else {
+ grid[i][j] = grid[i][j] + Math.min(grid[i - 1][j], grid[i][j - 1]);
+ }
+ }
+ }
+ return grid[row - 1][clomn - 1];
+ }
+
+ @Test
+ public void testCase() {
+
+ int[][] nums = {{4, 5, 6}, {5, 6, 7}, {52, 4, 5}};
+
+
+ }
+
+
+}
diff --git a/src/main/java/com/chen/algorithm/study/test674/Solution.java b/src/main/java/com/chen/algorithm/study/test674/Solution.java
new file mode 100644
index 0000000..91889f1
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/study/test674/Solution.java
@@ -0,0 +1,29 @@
+package com.chen.algorithm.study.test674;
+
+/**
+ * @author : chen weijie
+ * @Date: 2020-05-24 00:15
+ */
+public class Solution {
+
+ public int findLengthOfLCIS(int[] nums) {
+
+ if (nums == null || nums.length == 0) {
+ return 0;
+ }
+
+ int[] dp = new int[nums.length];
+ dp[0] = 1;
+ int max = 1;
+ for (int i = 1; i < nums.length; i++) {
+ if (nums[i] > nums[i - 1]) {
+ dp[i] = dp[i - 1] + 1;
+ } else {
+ dp[i] = 1;
+ }
+ max = Math.max(max, dp[i]);
+ }
+ return max;
+ }
+
+}
diff --git a/src/main/java/com/chen/algorithm/study/test69/Solution.java b/src/main/java/com/chen/algorithm/study/test69/Solution.java
new file mode 100644
index 0000000..e31d3d7
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/study/test69/Solution.java
@@ -0,0 +1,41 @@
+package com.chen.algorithm.study.test69;
+
+import org.junit.Test;
+
+/**
+ * @author : chen weijie
+ * @Date: 2020-05-03 09:39
+ * @Description: zhunn x的平方根,舍弃小数
+ */
+public class Solution {
+
+
+ public int mySqrt(int x) {
+
+ if (x < 2) {
+ return x;
+ }
+
+ int left = 1, right = x / 2, mid;
+ long result;
+
+ while (right >= left) {
+ mid = (right - left) / 2 + left;
+ result = (long) mid * mid;
+ if (result > x) {
+ right = mid - 1;
+ } else if (result < x) {
+ left = mid + 1;
+ } else {
+ return mid;
+ }
+ }
+ return right;
+ }
+
+ @Test
+ public void test() {
+ System.out.println(mySqrt(2147395599));
+ }
+
+}
diff --git a/src/main/java/com/chen/algorithm/study/test7/Solution2.java b/src/main/java/com/chen/algorithm/study/test7/Solution2.java
index 470d372..082e40b 100644
--- a/src/main/java/com/chen/algorithm/study/test7/Solution2.java
+++ b/src/main/java/com/chen/algorithm/study/test7/Solution2.java
@@ -28,7 +28,7 @@ public int reverse(int x) {
@Test
public void testCase() {
- System.out.println(reverse(9083));
+ System.out.println(reverse(120));
}
diff --git a/src/main/java/com/chen/algorithm/study/test7/Solution3.java b/src/main/java/com/chen/algorithm/study/test7/Solution3.java
new file mode 100644
index 0000000..cbbd4cf
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/study/test7/Solution3.java
@@ -0,0 +1,42 @@
+package com.chen.algorithm.study.test7;
+
+import org.junit.Test;
+
+/**
+ * @author : chen weijie
+ * @Date: 2019-09-04 01:51
+ */
+public class Solution3 {
+
+ public int reverse(int x) {
+
+
+ int rev = 0;
+ while (x != 0) {
+
+ int pop = x % 10;
+// if(rev>Integer.MAX_VALUE/10||(rev==Integer.MAX_VALUE/10&&pop>7)){
+// return 0;
+// }
+//
+// if(rev Integer.MAX_VALUE) {
+ return 0;
+ }
+ return res;
+ }
+
+ public static void main(String[] args) {
+ System.out.println(reverse1(123));
+ }
+}
diff --git a/src/main/java/com/chen/algorithm/study/test70/Solution.java b/src/main/java/com/chen/algorithm/study/test70/Solution.java
new file mode 100644
index 0000000..e0d2166
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/study/test70/Solution.java
@@ -0,0 +1,58 @@
+package com.chen.algorithm.study.test70;
+
+import org.junit.Test;
+
+/**
+ * 不难发现,这个问题可以被分解为一些包含最优子结构的子问题,即它的最优解可以从其子问题的最优解来有效地构建,我们可以使用动态规划来解决这一问题。
+ *
+ * 第 i 阶可以由以下两种方法得到:
+ *
+ * 在第(i−1) 阶后向上爬一阶。
+ *
+ * 在第(i−2) 阶后向上爬 2 阶。
+ *
+ * 所以到达第 i 阶的方法总数就是到第(i−1) 阶和第 (i−2) 阶的方法数之和。
+ *
+ * 令 dp[i] 表示能到达第 i 阶的方法总数:
+ *
+ * dp[i]=dp[i-1]+dp[i-2]
+ *
+ *
+ * 在上述方法中,我们使用 dp 数组,其中 dp[i]=dp[i-1]+dp[i-2]。可以很容易通过分析得出 dp[i] 其实就是第 i 个斐波那契数。
+ *
+ * Fib(n)=Fib(n-1)+Fib(n-2)
+ *
+ * 现在我们必须找出以 1 和 2 作为第一项和第二项的斐波那契数列中的第 n 个数,也就是说 Fib(1)=1Fib(1)=1 且 Fib(2)=2Fib(2)=2
+ *
+ * @author : chen weijie
+ * @Date: 2019-10-22 00:07
+ */
+public class Solution {
+
+
+ public int climbStairs(int n) {
+
+ if (n == 1) {
+ return 1;
+ }
+ int first = 1;
+ int second = 2;
+ int third = 0;
+
+ for (int i = 3; i <= n; i++) {
+ third = first + second;
+ first = second;
+ second = third;
+ }
+
+ return third;
+ }
+
+
+ @Test
+ public void testCase() {
+ System.out.println(climbStairs(10));
+ }
+
+
+}
diff --git a/src/main/java/com/chen/algorithm/study/test70/Solution1.java b/src/main/java/com/chen/algorithm/study/test70/Solution1.java
new file mode 100644
index 0000000..c6222c6
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/study/test70/Solution1.java
@@ -0,0 +1,57 @@
+package com.chen.algorithm.study.test70;
+
+import org.junit.Test;
+
+/**
+ * 不难发现,这个问题可以被分解为一些包含最优子结构的子问题,即它的最优解可以从其子问题的最优解来有效地构建,我们可以使用动态规划来解决这一问题。
+ *
+ * 第 i 阶可以由以下两种方法得到:
+ *
+ * 在第(i−1) 阶后向上爬一阶。
+ *
+ * 在第(i−2) 阶后向上爬 2 阶。
+ *
+ * 所以到达第 i 阶的方法总数就是到第(i−1) 阶和第 (i−2) 阶的方法数之和。
+ *
+ * 令 dp[i] 表示能到达第 i 阶的方法总数:
+ *
+ * dp[i]=dp[i-1]+dp[i-2]
+ *
+ *
+ * 在上述方法中,我们使用 dp 数组,其中 dp[i]=dp[i-1]+dp[i-2]。可以很容易通过分析得出 dp[i] 其实就是第 i 个斐波那契数。
+ *
+ * Fib(n)=Fib(n-1)+Fib(n-2)
+ *
+ * 现在我们必须找出以 1 和 2 作为第一项和第二项的斐波那契数列中的第 n 个数,也就是说 Fib(1)=1Fib(1)=1 且 Fib(2)=2Fib(2)=2
+ *
+ * @author : chen weijie
+ * @Date: 2019-10-22 00:07
+ */
+public class Solution1 {
+
+
+ public int climbStairs(int n) {
+
+ if (n == 1 || n == 2) {
+ return n;
+ }
+
+ int[] dp = new int[n + 1];
+ dp[1] = 1;
+ dp[2] = 2;
+
+ for (int i = 3; i <= n; i++) {
+ dp[i] = dp[i - 1] + dp[i - 2];
+ }
+
+ return dp[n];
+ }
+
+
+ @Test
+ public void testCase() {
+ System.out.println(climbStairs(10));
+ }
+
+
+}
diff --git a/src/main/java/com/chen/algorithm/study/test703/KthLargest.java b/src/main/java/com/chen/algorithm/study/test703/KthLargest.java
new file mode 100644
index 0000000..93c5116
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/study/test703/KthLargest.java
@@ -0,0 +1,35 @@
+package com.chen.algorithm.study.test703;
+
+import java.util.PriorityQueue;
+
+/**
+ * @author : chen weijie
+ * @Date: 2020-05-04 16:37
+ */
+public class KthLargest {
+
+
+ public PriorityQueue queue = null;
+ private Integer limit = null;
+
+
+ public KthLargest(int k, int[] nums) {
+ limit = k;
+ queue = new PriorityQueue<>(k);
+ for (int num : nums) {
+ add(num);
+ }
+ }
+
+ public int add(int val) {
+ if (queue.size() < limit) {
+ queue.add(val);
+ } else if (val > queue.peek()) {
+ queue.poll();
+ queue.add(val);
+ }
+ return queue.peek();
+ }
+
+
+}
diff --git a/src/main/java/com/chen/algorithm/study/test703/ObjectPriorityQueue.java b/src/main/java/com/chen/algorithm/study/test703/ObjectPriorityQueue.java
new file mode 100644
index 0000000..da4640e
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/study/test703/ObjectPriorityQueue.java
@@ -0,0 +1,38 @@
+package com.chen.algorithm.study.test703;
+
+import java.util.PriorityQueue;
+
+/**
+ * @author : chen weijie
+ * @Date: 2020-07-27 17:37
+ */
+public class ObjectPriorityQueue {
+
+
+ private PriorityQueue queue = null;
+
+ private Integer limit = null;
+
+
+ public ObjectPriorityQueue(int size, Integer[] nums) {
+ this.limit = size;
+ queue = new PriorityQueue<>(10);
+ for (int num : nums) {
+ add(num);
+ }
+ }
+
+ public int add(int num) {
+
+ if (queue.size() < limit) {
+ queue.offer(num);
+ } else if (queue.peek() > num) {
+ queue.poll();
+ queue.offer(num);
+ }
+
+ return queue.peek();
+ }
+
+
+}
diff --git a/src/main/java/com/chen/algorithm/study/test704/Solution.java b/src/main/java/com/chen/algorithm/study/test704/Solution.java
new file mode 100644
index 0000000..8dda25c
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/study/test704/Solution.java
@@ -0,0 +1,197 @@
+package com.chen.algorithm.study.test704;
+
+/**
+ * @Auther: zhunn
+ * @Date: 2020/10/9 15:31
+ * @Description: 二分查找及其变种 https://blog.csdn.net/Lngxling/article/details/78217619
+ */
+public class Solution {
+
+ /**
+ * 适用于升序数组,可做相应调整适用降序数组
+ */
+ public static int bsearch(int[] array, int target) {
+ if (array == null || array.length == 0
+ /*|| target < array[0] || target > array[array.length - 1]*/) {
+ return -1;
+ }
+
+ int left = 0;
+ int right = array.length - 1;
+ //这里必须是 >=,切记勿遗漏 =
+ while (right >= left) {
+ // 当start=Integer.MAX_VALUE时,给它加个1都会溢出。安全的写法是:mid = start + (end-start)/2,但是会造成死循环,弃用
+ //int mid = min + (max - min) >> 1;
+ int mid = (left + right) >> 1;
+ if (target == array[mid]) {
+ return mid;
+ }
+ if (target < array[mid]) {
+ right = mid - 1;
+ }
+ if (target > array[mid]) {
+ left = mid + 1;
+ }
+ }
+ return -1;
+ }
+
+ /**
+ * 查找第一个与target相等的元素
+ * 当key=array[mid]时, 往左边一个一个逼近,right = mid -1; 返回left
+ */
+ public static int bsearch1(int[] array, int target) {
+ if (array == null || array.length == 0
+ /*|| target < array[0] || target > array[array.length - 1]*/) {
+ return -1;
+ }
+ int left = 0;
+ int right = array.length - 1;
+ while (right >= left) {
+ int mid = (left + right) >> 1;
+ if (array[mid] >= target) {
+ right = mid - 1;
+ } else {
+ left = mid + 1;
+ }
+ }
+
+ if (left < array.length && array[left] == target) {
+ return left;
+ }
+ return -1;
+
+ }
+
+ /**
+ * 查找最后一个与target相等的元素
+ * 当key=array[mid]时, 往右边一个一个逼近,left = mid + 1; 返回right
+ *
+ * @return
+ */
+ public static int bsearch2(int[] array, int target) {
+ if (array == null || array.length == 0 /*|| target < array[0] || target > array[array.length - 1]*/) {
+ return -1;
+ }
+ int left = 0;
+ int right = array.length - 1;
+ while (right >= left) {
+ int mid = (left + right) >> 1;
+ if (array[mid] <= target) {
+ left = mid + 1;
+ } else {
+ right = mid - 1;
+ }
+ }
+
+ if (right >= 0 && array[right] == target) {
+ return right;
+ }
+ return -1;
+ }
+
+ // 二分查找变种说明
+ //public void test(int[] array, int target){
+ //
+ // int left = 0;
+ // int right = array.length - 1;
+ // // 这里必须是 <=
+ // while (left <= right) {
+ // int mid = (left + right) / 2;
+ // if (array[mid] ? key) {
+ // //... right = mid - 1;
+ // }
+ // else {
+ // // ... left = mid + 1;
+ // }
+ // }
+ // return xxx;
+ //}
+
+
+ /**
+ * 查找第一个等于或者大于key的元素
+ */
+ public static int bsearch3(int[] array, int target) {
+ if (array == null || array.length == 0) {
+ return -1;
+ }
+ int left = 0;
+ int right = array.length - 1;
+ while (right >= left) {
+ int mid = (left + right) >> 1;
+ if (array[mid] >= target) {
+ right = mid - 1;
+ } else {
+ left = mid + 1;
+ }
+ }
+ return left;
+ }
+
+ /**
+ * 查找第一个大于key的元素
+ */
+ public static int bsearch4(int[] array, int target) {
+ if (array == null || array.length == 0) {
+ return -1;
+ }
+ int left = 0;
+ int right = array.length - 1;
+ while (right >= left) {
+ int mid = (left + right) >> 1;
+ if (array[mid] > target) {
+ right = mid - 1;
+ } else {
+ left = mid + 1;
+ }
+ }
+ return left;
+ }
+
+ /**
+ * 查找最后一个等于或者小于key的元素
+ */
+ public static int bsearch5(int[] array, int target) {
+ if (array == null || array.length == 0) {
+ return -1;
+ }
+ int left = 0;
+ int right = array.length - 1;
+ while (right >= left) {
+ int mid = (left + right) >> 1;
+ if (array[mid] <= target) {
+ left = mid + 1;
+ } else {
+ right = mid - 1;
+ }
+ }
+ return right;
+ }
+
+ /**
+ * 查找最后一个小于key的元素
+ */
+ public static int bsearch6(int[] array, int target) {
+ if (array == null || array.length == 0) {
+ return -1;
+ }
+ int left = 0;
+ int right = array.length - 1;
+ while (right >= left) {
+ int mid = (left + right) >> 1;
+ if (array[mid] < target) {
+ left = mid + 1;
+ } else {
+ right = mid - 1;
+ }
+ }
+ return right;
+ }
+
+ public static void main(String[] args) {
+ int[] array = {1, 1, 3, 6, 6, 6, 7, 9, 17, 17};
+ int index = bsearch6(array, 0);
+ System.out.println(index);
+ }
+}
diff --git a/src/main/java/com/chen/algorithm/study/test714/Solution.java b/src/main/java/com/chen/algorithm/study/test714/Solution.java
new file mode 100644
index 0000000..89018cc
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/study/test714/Solution.java
@@ -0,0 +1,32 @@
+package com.chen.algorithm.study.test714;
+
+/**
+ * https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock-with-transaction-fee/solution/dong-tai-gui-hua-by-liweiwei1419-6/
+ *
+ * @author : chen weijie
+ * @Date: 2020-09-06 02:17
+ */
+public class Solution {
+
+
+ public int maxProfit(int[] prices, int fee) {
+ int len = prices.length;
+ if (len < 2) {
+ return 0;
+ }
+
+ // dp[i][j] 表示 [0, i] 区间内,到第 i 天(从 0 开始)状态为 j 时的最大收益
+ // j = 0 表示不持股,j = 1 表示持股
+ // 并且规定在买入股票的时候,扣除手续费
+ int[][] dp = new int[len][2];
+
+ dp[0][0] = 0;
+ dp[0][1] = -prices[0] - fee;
+
+ for (int i = 1; i < len; i++) {
+ dp[i][0] = Math.max(dp[i - 1][0], dp[i - 1][1] + prices[i]);
+ dp[i][1] = Math.max(dp[i - 1][1], dp[i - 1][0] - prices[i] - fee);
+ }
+ return dp[len - 1][0];
+ }
+}
diff --git a/src/main/java/com/chen/algorithm/study/test72/Solution.java b/src/main/java/com/chen/algorithm/study/test72/Solution.java
new file mode 100644
index 0000000..6a3595f
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/study/test72/Solution.java
@@ -0,0 +1,56 @@
+package com.chen.algorithm.study.test72;
+
+import org.junit.Test;
+
+/**
+ * https://leetcode-cn.com/problems/edit-distance/solution/zi-di-xiang-shang-he-zi-ding-xiang-xia-by-powcai-3/
+ *
+ * @author : chen weijie
+ * @Date: 2020-05-17 13:32
+ */
+public class Solution {
+
+
+ public int minDistance(String word1, String word2) {
+
+ int m = word1.length();
+ int n = word2.length();
+
+ if (m * n == 0) {
+ return m + n;
+ }
+
+ // 多开一行一列是为了保存边界条件,即字符长度为 0 的情况,这一点在字符串的动态规划问题中比较常见
+ int[][] dp = new int[m + 1][n + 1];
+
+ // 初始化:当 word 2 长度为 0 时,将 word1 的全部删除
+ for (int i = 0; i < m + 1; i++) {
+ dp[i][0] = i;
+ }
+
+ // 当 word1 长度为 0 时,就插入所有 word2 的字符
+ for (int j = 0; j < n + 1; j++) {
+ dp[0][j] = j;
+ }
+
+ for (int i = 1; i < m + 1; i++) {
+ for (int j = 1; j < n + 1; j++) {
+ if (word1.charAt(i - 1) == word2.charAt(j - 1)) {
+ dp[i][j] = dp[i - 1][j - 1];
+ } else {
+ dp[i][j] = Math.min(Math.min(dp[i - 1][j - 1], dp[i][j - 1]), dp[i - 1][j]) + 1;
+ }
+ }
+ }
+ return dp[m][n];
+ }
+
+
+ @Test
+ public void testCase() {
+
+ System.out.println(minDistance("horse", "ros"));
+ }
+
+
+}
diff --git a/src/main/java/com/chen/algorithm/study/test72/Solution1.java b/src/main/java/com/chen/algorithm/study/test72/Solution1.java
new file mode 100644
index 0000000..1afe93b
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/study/test72/Solution1.java
@@ -0,0 +1,54 @@
+package com.chen.algorithm.study.test72;
+
+import org.junit.Test;
+
+/**
+ * https://leetcode-cn.com/problems/edit-distance/solution/zi-di-xiang-shang-he-zi-ding-xiang-xia-by-powcai-3/
+ *
+ * @author : chen weijie
+ * @Date: 2020-05-17 13:32
+ */
+public class Solution1 {
+
+
+ public int minDistance(String word1, String word2) {
+
+ int m = word1.length();
+ int n = word2.length();
+
+ if (m * n == 0) {
+ return m + n;
+ }
+
+ int[][] dp = new int[m + 1][n + 1];
+
+ for (int i = 0; i < m + 1; i++) {
+ dp[i][0] = i;
+ }
+
+ for (int i = 0; i < n + 1; i++) {
+ dp[0][i] = i;
+ }
+
+ for (int i = 1; i < m + 1; i++) {
+ for (int j = 1; j < n + 1; j++) {
+ if (word1.charAt(i - 1) == word2.charAt(j - 1)) {
+ dp[i][j] = dp[i - 1][j - 1];
+ } else {
+ dp[i][j] = Math.min(Math.min(dp[i][j - 1], dp[i - 1][j]), dp[i - 1][j - 1]) + 1;
+ }
+ }
+ }
+
+ return dp[m][n];
+ }
+
+
+ @Test
+ public void testCase() {
+
+ System.out.println(minDistance("horse", "ros"));
+ }
+
+
+}
diff --git a/src/main/java/com/chen/algorithm/study/test72/Solution2.java b/src/main/java/com/chen/algorithm/study/test72/Solution2.java
new file mode 100644
index 0000000..47dc9f0
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/study/test72/Solution2.java
@@ -0,0 +1,124 @@
+package com.chen.algorithm.study.test72;
+
+/**
+ * @Auther: zhunn
+ * @Date: 2020/10/9 13:54
+ * @Description: 编辑距离算法
+ * 距离值:变更次数--- 先计算两个字符串的差异, str1 str2, str1要做多少次(每次一个char字符)增加 删除 替换 操作 才能与str2一致
+ * 相似度:用最长的字符串的len 减去 变更次数 ,然后除以最长的字符串长度. similarity = (maxLen - changeTimes)/maxLen
+ * ORACLE函数: UTL_MATCH.EDIT_DISTANCE
+ * select UTL_MATCH.EDIT_DISTANCE('Java你好','你好') from dual;
+ */
+public class Solution2 {
+
+
+ /**
+ * 编辑距离算法
+ *
+ * @param sourceStr 原字符串
+ * @param targetStr 目标字符串
+ * @return 返回最小距离: 原字符串需要变更多少次才能与目标字符串一致(变更动作:增加/删除/替换,每次都是以字节为单位)
+ */
+ public static int minDistance(String sourceStr, String targetStr) {
+ int sourceLen = sourceStr.length();
+ int targetLen = targetStr.length();
+
+ if (sourceLen == 0) {
+ return targetLen;
+ }
+ if (targetLen == 0) {
+ return sourceLen;
+ }
+
+ //定义矩阵(二维数组)
+ int[][] arr = new int[sourceLen + 1][targetLen + 1];
+
+ for (int i = 0; i < sourceLen + 1; i++) {
+ arr[i][0] = i;
+ }
+ for (int j = 0; j < targetLen + 1; j++) {
+ arr[0][j] = j;
+ }
+
+ //矩阵打印
+ System.out.println("初始化矩阵打印开始");
+ for (int i = 0; i < sourceLen + 1; i++) {
+
+ for (int j = 0; j < targetLen + 1; j++) {
+ System.out.print(arr[i][j] + "\t");
+ }
+ System.out.println();
+ }
+ System.out.println("初始化矩阵打印结束");
+
+ for (int i = 1; i < sourceLen + 1; i++) {
+ for (int j = 1; j < targetLen + 1; j++) {
+
+ if (sourceStr.charAt(i - 1) == targetStr.charAt(j - 1)) {
+ /*
+ * 如果source[i] 等于target[j],则:d[i, j] = d[i-1, j-1] + 0 (递推式 1)
+ */
+ arr[i][j] = arr[i - 1][j - 1];
+ } else {
+ /* 如果source[i] 不等于target[j],则根据插入、删除和替换三个策略,分别计算出使用三种策略得到的编辑距离,然后取最小的一个:
+ d[i, j] = min(d[i, j - 1] + 1, d[i - 1, j] + 1, d[i - 1, j - 1] + 1 ) (递推式 2)
+ >> d[i, j - 1] + 1 表示对source[i]执行插入操作后计算最小编辑距离
+ >> d[i - 1, j] + 1 表示对source[i]执行删除操作后计算最小编辑距离
+ >> d[i - 1, j - 1] + 1表示对source[i]替换成target[i]操作后计算最小编辑距离
+ */
+ arr[i][j] = (Math.min(Math.min(arr[i - 1][j], arr[i][j - 1]), arr[i - 1][j - 1])) + 1;
+ }
+ }
+ }
+
+ System.out.println("----------矩阵打印---------------");
+ //矩阵打印
+ for (int i = 0; i < sourceLen + 1; i++) {
+
+ for (int j = 0; j < targetLen + 1; j++) {
+ System.out.print(arr[i][j] + "\t");
+ }
+ System.out.println();
+ }
+ System.out.println("----------矩阵打印---------------");
+
+ return arr[sourceLen][targetLen];
+ }
+
+ /**
+ * 计算字符串相似度
+ * similarity = (maxlen - distance) / maxlen
+ * ps: 数据定义为double类型,如果为int类型 相除后结果为0(只保留整数位)
+ *
+ * @param str1
+ * @param str2
+ * @return
+ */
+ public static double getsimilarity(String str1, String str2) {
+ double distance = minDistance(str1, str2);
+ double maxlen = Math.max(str1.length(), str2.length());
+ double res = (maxlen - distance) / maxlen;
+
+ //System.out.println("distance="+distance);
+ //System.out.println("maxlen:"+maxlen);
+ //System.out.println("(maxlen - distance):"+(maxlen - distance));
+ return res;
+ }
+
+ public static String evaluate(String str1, String str2) {
+ double result = getsimilarity(str1, str2);
+ return String.valueOf(result);
+ }
+
+ public static void main(String[] args) {
+ String str1 = "2/F20NGNT";
+ String str2 = "1/F205ONGNT";
+ int result = minDistance(str1, str2);
+ //String res = evaluate(str1, str2);
+ System.out.println("最小编辑距离minDistance:" + result);
+ //System.out.println(str1 + "与" + str2 + "相似度为:" + res);
+
+
+ }
+
+}
diff --git a/src/main/java/com/chen/algorithm/study/test75/Solution.java b/src/main/java/com/chen/algorithm/study/test75/Solution.java
new file mode 100644
index 0000000..d2684a2
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/study/test75/Solution.java
@@ -0,0 +1,44 @@
+package com.chen.algorithm.study.test75;
+
+import com.alibaba.fastjson.JSONObject;
+import org.junit.Test;
+
+/**
+ * @author : chen weijie
+ * @Date: 2019-11-20 00:51
+ */
+public class Solution {
+
+
+ public void sortColors(int[] nums) {
+
+ if (nums == null || nums.length == 0) {
+ return;
+ }
+
+
+ for (int i = 0; i < nums.length - 1; i++) {
+ for (int j = i; j <= nums.length - 1; j++) {
+ int temp;
+ if (nums[i] > nums[j]) {
+ temp = nums[i];
+ nums[i] = nums[j];
+ nums[j] = temp;
+ }
+ }
+ }
+ }
+
+
+ @Test
+ public void testCase() {
+
+ int[] nums = {2, 0, 2, 1, 1, 0};
+ sortColors(nums);
+ System.out.println(JSONObject.toJSONString(nums));
+
+
+ }
+
+
+}
diff --git a/src/main/java/com/chen/algorithm/study/test75/Solution1.java b/src/main/java/com/chen/algorithm/study/test75/Solution1.java
new file mode 100644
index 0000000..705ed3c
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/study/test75/Solution1.java
@@ -0,0 +1,44 @@
+package com.chen.algorithm.study.test75;
+
+import com.alibaba.fastjson.JSONObject;
+import org.junit.Test;
+
+/**
+ * @author : chen weijie
+ * @Date: 2019-11-20 01:00
+ */
+public class Solution1 {
+
+ public void sortColors(int[] nums) {
+
+ if (nums == null || nums.length == 0) {
+ return;
+ }
+
+
+ int temp;
+ for (int i = 1; i <= nums.length - 1; i++) {
+
+ int leftIndex = i - 1;
+ temp = nums[i];
+
+ while (leftIndex >= 0 && temp < nums[leftIndex]) {
+ nums[leftIndex + 1] = nums[leftIndex];
+ leftIndex--;
+ }
+ nums[leftIndex + 1] = temp;
+ }
+ }
+
+ @Test
+ public void testCase() {
+
+ int[] nums = {2, 0, 2, 1, 1, 0};
+ sortColors(nums);
+ System.out.println(JSONObject.toJSONString(nums));
+
+
+ }
+
+
+}
diff --git a/src/main/java/com/chen/algorithm/study/test75/Solution2.java b/src/main/java/com/chen/algorithm/study/test75/Solution2.java
new file mode 100644
index 0000000..6be1d0e
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/study/test75/Solution2.java
@@ -0,0 +1,54 @@
+package com.chen.algorithm.study.test75;
+
+import com.alibaba.fastjson.JSONObject;
+import org.junit.Test;
+
+/**
+ * https://leetcode-cn.com/problems/sort-colors/solution/yan-se-fen-lei-by-leetcode/
+ *
+ * @author : chen weijie
+ * @Date: 2019-11-20 00:51
+ */
+public class Solution2 {
+
+
+ public void sortColors(int[] nums) {
+
+ if (nums == null || nums.length == 0) {
+ return;
+ }
+
+ int p0 = 0, curr = 0;
+
+ int p2 = nums.length - 1;
+
+ int temp;
+
+ while (curr <= p2) {
+ if (nums[curr] == 0) {
+ temp = nums[p0];
+ nums[p0++] = nums[curr];
+ nums[curr++] = temp;
+ } else if (nums[curr] == 2) {
+ temp = nums[curr];
+ nums[curr] = nums[p2];
+ nums[p2--] = temp;
+ } else {
+ curr++;
+ }
+ }
+ }
+
+
+ @Test
+ public void testCase() {
+
+ int[] nums = {2, 0, 2, 1, 1, 0};
+ sortColors(nums);
+ System.out.println(JSONObject.toJSONString(nums));
+
+
+ }
+
+
+}
diff --git a/src/main/java/com/chen/algorithm/study/test78/Solution.java b/src/main/java/com/chen/algorithm/study/test78/Solution.java
new file mode 100644
index 0000000..a8555ee
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/study/test78/Solution.java
@@ -0,0 +1,47 @@
+package com.chen.algorithm.study.test78;
+
+import org.junit.Test;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.PriorityQueue;
+
+/**
+ * https://leetcode-cn.com/problems/subsets/solution/hui-su-suan-fa-by-powcai-5/
+ *
+ * @author : chen weijie
+ * @Date: 2019-11-21 00:07
+ */
+public class Solution {
+
+ public List> subsets(int[] nums) {
+
+ List> res = new ArrayList<>();
+ backtrack(0, nums, res, new ArrayList<>());
+ return res;
+ }
+
+
+ private void backtrack(int i, int[] nums, List> res, ArrayList tmp) {
+
+ res.add(new ArrayList<>(tmp));
+ for (int j = i; j < nums.length; j++) {
+ tmp.add(nums[j]);
+ backtrack(j + 1, nums, res, tmp);
+ tmp.remove(tmp.size() - 1);
+ }
+ }
+
+
+ @Test
+ public void testCase() {
+
+ int[] n = {1, 2, 3};
+
+ System.out.println(subsets(n));
+
+
+ }
+
+
+}
diff --git a/src/main/java/com/chen/algorithm/study/test79/Solution.java b/src/main/java/com/chen/algorithm/study/test79/Solution.java
new file mode 100644
index 0000000..c051ce3
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/study/test79/Solution.java
@@ -0,0 +1,73 @@
+package com.chen.algorithm.study.test79;
+
+import org.junit.Test;
+
+/**
+ * @author : chen weijie
+ * @Date: 2019-11-24 18:11
+ */
+public class Solution {
+
+
+ private boolean[][] visited;
+
+ public boolean exist(char[][] board, String word) {
+
+ int m = board.length;
+ int n = board[0].length;
+
+ if (m * n == 0) {
+ return false;
+ }
+
+ visited = new boolean[m][n];
+
+ for (int i = 0; i < m; i++) {
+ for (int j = 0; j < n; j++) {
+ if (dfs(i, j, board, word, 0)) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+
+ private boolean dfs(int x, int y, char[][] board, String word, Integer index) {
+
+ if (x < 0 || y < 0 || x >= board.length || y >= board[0].length || board[x][y] != word.charAt(index) || visited[x][y]) {
+ return false;
+ }
+
+ if (index == word.length() - 1) {
+ return true;
+ }
+
+ visited[x][y] = true;
+ if (dfs(x - 1, y, board, word, index + 1) || dfs(x + 1, y, board, word, index + 1)
+ || dfs(x, y - 1, board, word, index + 1) || dfs(x + 1, y, board, word, index + 1)) {
+ return true;
+ }
+ visited[x][y] = false;
+ return false;
+ }
+
+
+ @Test
+ public void testCase() {
+
+ char[][] nums = {
+ {'A', 'B', 'C', 'E'},
+ {'S', 'F', 'C', 'S'},
+ {'A', 'D', 'E', 'E'}
+ };
+
+ String word = "SEE";
+
+ System.out.println(exist(nums, word));
+
+
+ }
+
+
+}
diff --git a/src/main/java/com/chen/algorithm/study/test79/Solution1.java b/src/main/java/com/chen/algorithm/study/test79/Solution1.java
new file mode 100644
index 0000000..3030886
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/study/test79/Solution1.java
@@ -0,0 +1,65 @@
+package com.chen.algorithm.study.test79;
+
+import org.junit.Test;
+
+/**
+ * https://leetcode-cn.com/problems/word-search/solution/zai-er-wei-ping-mian-shang-shi-yong-hui-su-fa-pyth/
+ *
+ * @author : chen weijie
+ * @Date: 2020-09-15 01:47
+ */
+public class Solution1 {
+
+ private boolean[][] visited;
+
+ public boolean exist(char[][] board, String word) {
+ int m = board.length;
+ int n = board[0].length;
+ visited = new boolean[m][n];
+ for (int i = 0; i < m; i++) {
+ for (int j = 0; j < n; j++) {
+ // 递归终止条件就判断了 word.charAt(0) == board[i][j]
+ // if (word.charAt(0) == board[i][j]) {
+ if (dfs(0, board, word, i, j)) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ public boolean dfs(int index, char[][] board, String word, int x, int y) {
+ if (x < 0 || y < 0 || x >= board.length || y >= board[0].length
+ || word.charAt(index) != board[x][y] || visited[x][y]) {
+ return false;
+ }
+
+ if (index == word.length() - 1) {
+ return true;
+ }
+ visited[x][y] = true;
+ if (dfs(index + 1, board, word, x + 1, y) || dfs(index + 1, board, word, x - 1, y) ||
+ dfs(index + 1, board, word, x, y + 1) || dfs(index + 1, board, word, x, y - 1)) {
+ return true;
+ }
+ visited[x][y] = false;
+ return false;
+ }
+
+
+ @Test
+ public void testCase() {
+
+ char[][] nums = {
+ {'A', 'B', 'C', 'E'},
+ {'S', 'F', 'C', 'S'},
+ {'A', 'D', 'E', 'E'}
+ };
+
+ String word = "SEE";
+
+ System.out.println(exist(nums, word));
+
+ }
+
+}
diff --git a/src/main/java/com/chen/algorithm/study/test83/Solution.java b/src/main/java/com/chen/algorithm/study/test83/Solution.java
index 5da3c45..5ce2598 100644
--- a/src/main/java/com/chen/algorithm/study/test83/Solution.java
+++ b/src/main/java/com/chen/algorithm/study/test83/Solution.java
@@ -15,13 +15,14 @@ public ListNode deleteDuplicates(ListNode head) {
}
ListNode temp = head;
- while (temp.next != null) {
- if (temp.next.val == temp.val) {
- temp.next = temp.next.next;
+ while (head.next != null) {
+ if (head.val == head.next.val) {
+ head.next = head.next.next;
+ } else {
+ head = head.next;
}
- temp = temp.next;
}
- return head;
+ return temp;
}
diff --git a/src/main/java/com/chen/algorithm/study/test83/Solution2.java b/src/main/java/com/chen/algorithm/study/test83/Solution2.java
index 3cfdeef..140a0f5 100644
--- a/src/main/java/com/chen/algorithm/study/test83/Solution2.java
+++ b/src/main/java/com/chen/algorithm/study/test83/Solution2.java
@@ -3,6 +3,7 @@
/**
* @author : chen weijie
* @Date: 2019-09-08 02:19
+ * @Description: zhunn 删除排序链表中的重复元素
*/
public class Solution2 {
diff --git a/src/main/java/com/chen/algorithm/study/test88/Solution.java b/src/main/java/com/chen/algorithm/study/test88/Solution.java
new file mode 100644
index 0000000..c2ace9a
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/study/test88/Solution.java
@@ -0,0 +1,40 @@
+package com.chen.algorithm.study.test88;
+
+import org.junit.Test;
+
+import java.util.Arrays;
+
+/**
+ * https://leetcode-cn.com/problems/merge-sorted-array/solution/leetcode88-he-bing-liang-ge-you-xu-shu-zu-by-ma-xi/
+ *
+ * @author : chen weijie
+ * @Date: 2020-07-20 11:33
+ * @Description: 合并两个有序数组
+ */
+public class Solution {
+
+ public void merge(int[] nums1, int m, int[] nums2, int n) {
+
+ int p1 = m - 1, p2 = n - 1, p3 = m + n - 1;
+ while (p2 >= 0) {
+ if (p1 >= 0 && nums1[p1] > nums2[p2]) {
+ nums1[p3--] = nums1[p1--];
+ } else {
+ nums1[p3--] = nums2[p2--];
+ }
+ }
+ }
+
+
+ @Test
+ public void testCase() {
+ //int[] m = {1, 2, 3, 4, 0, 0, 0, 0, 0, 0, 0};
+ //int[] n = {0, 2, 5, 6, 8, 9, 25};
+ //merge(m, 4, n, n.length);
+ int[] m = {1,2,3,0,0,0};
+ int[] n = {2,5,6};
+ merge(m, 3, n, n.length);
+ System.out.println(Arrays.toString(m));
+ }
+
+}
diff --git a/src/main/java/com/chen/algorithm/study/test88/Solution2.java b/src/main/java/com/chen/algorithm/study/test88/Solution2.java
new file mode 100644
index 0000000..400ed70
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/study/test88/Solution2.java
@@ -0,0 +1,22 @@
+package com.chen.algorithm.study.test88;
+
+/**
+ * @author : chen weijie
+ * @Date: 2020-08-19 18:04
+ */
+public class Solution2 {
+
+ public void merge(int[] nums1, int m, int[] nums2, int n) {
+
+ int pa = m - 1, pb = n - 1, pc = m + n - 1;
+ while (pb >= 0) {
+ if (pa >= 0 && nums1[pa] < nums2[pb]) {
+ nums1[pc--] = nums2[pb--];
+ } else {
+ nums1[pc--] = nums1[pa--];
+ }
+ }
+ }
+
+
+}
diff --git a/src/main/java/com/chen/algorithm/study/test9/Solution3.java b/src/main/java/com/chen/algorithm/study/test9/Solution3.java
new file mode 100644
index 0000000..e44a370
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/study/test9/Solution3.java
@@ -0,0 +1,27 @@
+package com.chen.algorithm.study.test9;
+
+/**
+ * @author : chen weijie
+ * @Date: 2020-05-19 12:16
+ */
+public class Solution3 {
+
+
+ public boolean isPalindrome(int x) {
+
+ if (x < 0) {
+ return false;
+ }
+
+ int m = x;
+ int rev = 0;
+ while (x != 0) {
+ int pop = x % 10;
+ x = x / 10;
+ rev = rev * 10 + pop;
+ }
+
+ return rev == m;
+ }
+
+}
diff --git a/src/main/java/com/chen/algorithm/study/test9/Solution4.java b/src/main/java/com/chen/algorithm/study/test9/Solution4.java
new file mode 100644
index 0000000..8e5453c
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/study/test9/Solution4.java
@@ -0,0 +1,34 @@
+package com.chen.algorithm.study.test9;
+
+/**
+ * @Auther: zhunn
+ * @Date: 2020/9/16 18:22
+ * @Description: 回文数
+ */
+public class Solution4 {
+
+ public static boolean isPalindrome1(int x) {
+ // 特殊情况:
+ // 当 x < 0 时,x 不是回文数。
+ // 同样地,如果数字的最后一位是 0,为了使该数字为回文,
+ // 则其第一位数字也应该是 0
+ // 只有 0 满足这一属性
+ if (x < 0 || (x != 0 && x % 10 == 0)) return false;
+ int rev = 0;
+ while (x > rev) {
+ rev = rev * 10 + x % 10;
+ x /= 10;
+ }
+ // 当数字长度为奇数时,我们可以通过 revertedNumber/10 去除处于中位的数字。
+ return rev == x || rev / 10 == x;
+ }
+
+ public static void main(String[] args) {
+ System.out.println(isPalindrome1(-121));
+ System.out.println(isPalindrome1(0));
+ System.out.println(isPalindrome1(1000));
+ System.out.println(isPalindrome1(12321));
+ System.out.println(isPalindrome1(1221));
+ System.out.println(isPalindrome1(1231));
+ }
+}
diff --git a/src/main/java/com/chen/algorithm/study/test90/Solution.java b/src/main/java/com/chen/algorithm/study/test90/Solution.java
new file mode 100644
index 0000000..bcfe0b9
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/study/test90/Solution.java
@@ -0,0 +1,10 @@
+package com.chen.algorithm.study.test90;
+
+/**
+ * @author : chen weijie
+ * @Date: 2020-09-27 01:25
+ */
+public class Solution {
+
+
+}
diff --git a/src/main/java/com/chen/algorithm/study/test92/Solution.java b/src/main/java/com/chen/algorithm/study/test92/Solution.java
new file mode 100644
index 0000000..7972c2c
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/study/test92/Solution.java
@@ -0,0 +1,47 @@
+package com.chen.algorithm.study.test92;
+
+
+/**
+ * @author Chen WeiJie
+ * @date 2020-05-27 17:39:32
+ **/
+public class Solution {
+
+
+ public class ListNode {
+ int val;
+ ListNode next;
+
+ ListNode(int x) {
+ val = x;
+ }
+ }
+
+
+ public ListNode reverseBetween(ListNode head, int m, int n) {
+
+ if (head == null) {
+ return null;
+ }
+
+ ListNode pre = new ListNode(1);
+ pre.next = head;
+ ListNode ans = pre;
+
+ for (int i = 0; i < m - 1; i++) {
+ pre = pre.next;
+ }
+
+ ListNode end = pre.next;
+
+ for (int i = m; i < n; i++) {
+
+ ListNode temp = end.next;
+ end.next = temp.next;
+ temp.next = pre.next;
+ pre.next = temp;
+ }
+
+ return ans.next;
+ }
+}
diff --git a/src/main/java/com/chen/algorithm/study/test92/Solution2.java b/src/main/java/com/chen/algorithm/study/test92/Solution2.java
new file mode 100644
index 0000000..1584663
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/study/test92/Solution2.java
@@ -0,0 +1,79 @@
+package com.chen.algorithm.study.test92;
+
+
+import org.junit.Test;
+
+/**
+ * @author Chen WeiJie
+ * @date 2020-05-27 17:39:32
+ * @Description: zhunn 反转链表2
+ **/
+public class Solution2 {
+
+
+ public class ListNode {
+ int val;
+ ListNode next;
+
+ ListNode(int x) {
+ val = x;
+ }
+ }
+
+
+ public ListNode reverseBetween(ListNode head, int m, int n) {
+
+ if (head == null){
+ return null;
+ }
+
+ ListNode dummy = new ListNode(-1);
+ dummy.next = head;
+ ListNode pre = dummy;
+
+ for (int i = 0; i < m-1; i++) {
+ pre = pre.next;
+ head = head.next;
+ }
+
+
+ for (int i = m; i < n ; i++) {
+ ListNode temp = head.next;
+ head.next = temp.next;
+ temp.next = pre.next;
+ pre.next = temp;
+ }
+
+ return dummy.next;
+ }
+
+ @Test
+ public void test() {
+ ListNode l1_1 = new ListNode(7);
+ ListNode l1_2 = new ListNode(9);
+ ListNode l1_3 = new ListNode(2);
+ ListNode l1_4 = new ListNode(10);
+ ListNode l1_5 = new ListNode(1);
+ ListNode l1_6 = new ListNode(8);
+ ListNode l1_7 = new ListNode(6);
+
+ l1_1.next = l1_2;
+ l1_2.next = l1_3;
+ l1_3.next = l1_4;
+ l1_4.next = l1_5;
+ l1_5.next = l1_6;
+ l1_6.next = l1_7;
+
+ ListNode result = reverseBetween(l1_1,3,6);
+
+ System.out.println(result.val);
+ System.out.println(result.next.val);
+ System.out.println(result.next.next.val);
+ System.out.println(result.next.next.next.val);
+ System.out.println(result.next.next.next.next.val);
+ System.out.println(result.next.next.next.next.next.val);
+ System.out.println(result.next.next.next.next.next.next.val);
+ }
+
+
+}
diff --git a/src/main/java/com/chen/algorithm/study/test92/Solution3.java b/src/main/java/com/chen/algorithm/study/test92/Solution3.java
new file mode 100644
index 0000000..de47efd
--- /dev/null
+++ b/src/main/java/com/chen/algorithm/study/test92/Solution3.java
@@ -0,0 +1,120 @@
+package com.chen.algorithm.study.test92;
+
+import org.junit.Test;
+
+/**
+ * @Auther: zhunn
+ * @Date: 2020/10/24 17:23
+ * @Description: 反转链表二:1-双指针,2-删除结点递推
+ */
+public class Solution3 {
+
+ class ListNode {
+ int val;
+ ListNode next;
+
+ ListNode(int x) {
+ val = x;
+ }
+ }
+
+ // 翻转n个节点,返回新链表的头部
+ private ListNode reverseN(ListNode head, int n) {
+ ListNode prev = null;
+ ListNode curr = head;
+ for (int i = 0; i < n; i++) {
+ ListNode oldNext = curr.next;
+ curr.next = prev;
+ prev = curr;
+ curr = oldNext;
+ }
+ return prev;
+ }
+
+ /**
+ * 1-双指针
+ * @param head
+ * @param m
+ * @param n
+ * @return
+ */
+ public ListNode reverseBetween1(ListNode head, int m, int n) {
+ ListNode dummy = new ListNode(42);
+ dummy.next = head;
+ ListNode ptr1 = dummy;
+ ListNode ptr2 = dummy;
+ // 找到左右两段的端点
+ for (int i = 0; i < m - 1; i++) {
+ ptr2 = ptr2.next;
+ }
+ for (int i = 0; i < n + 1; i++) {
+ ptr1 = ptr1.next;
+ }
+ // 找到中段的尾端点
+ ListNode t = ptr2.next;
+ // 翻转中段,得到中段的头端点
+ ListNode h = reverseN(t, n - m + 1);
+ // 中端的头端点和左段端点相连
+ ptr2.next = h;
+ // 中段的尾端点和右段端点相连
+ t.next = ptr1;
+ return dummy.next;
+ }
+
+ /**
+ * 2-删除结点递推
+ * @param head
+ * @param m
+ * @param n
+ * @return
+ */
+ public ListNode reverseBetween2(ListNode head, int m, int n){
+ if(head == null || head.next == null){
+ return head;
+ }
+
+ ListNode dummy = new ListNode(-1);
+ dummy.next = head;
+ ListNode pre = dummy;
+ for(int i =0;i inorderTraversal(TreeNode root) {
+ List