diff --git a/pom.xml b/pom.xml index f848034..ddb917f 100644 --- a/pom.xml +++ b/pom.xml @@ -12,6 +12,8 @@ 5.1.40 4.3.11.RELEASE 1.16.10 + 3.2.8 + 1.2.0 @@ -46,6 +48,17 @@ ${spring.version} + + org.mybatis + mybatis + ${mybatis.version} + + + org.mybatis + mybatis-spring + ${mybatis.spring.version} + + org.springframework spring-aop @@ -149,6 +162,11 @@ fastjson 1.2.16 + + com.google.guava + guava + 28.0-jre + @@ -211,6 +229,40 @@ + + org.apache.maven.plugins + maven-enforcer-plugin + 3.0.0-M3 + + + enforce-versions + + enforce + + + + + + WARN + + org.apache.maven.plugins:maven-verifier-plugin + + Please consider using the maven-invoker-plugin (http://maven.apache.org/plugins/maven-invoker-plugin/)! + + + 2.0.6 + + + 1.5 + + + unix + + + + + + diff --git a/src/main/java/com/chen/Test.java b/src/main/java/com/chen/Test.java new file mode 100644 index 0000000..ce3beb4 --- /dev/null +++ b/src/main/java/com/chen/Test.java @@ -0,0 +1,11 @@ +package com.chen; + +/** + * @author : chen weijie + * @Date: 2020-09-18 20:03 + */ +public class Test { + + + +} diff --git a/src/main/java/com/chen/algorithm/CacheMap.java b/src/main/java/com/chen/algorithm/CacheMap.java new file mode 100644 index 0000000..97f3b11 --- /dev/null +++ b/src/main/java/com/chen/algorithm/CacheMap.java @@ -0,0 +1,35 @@ +package com.chen.algorithm; + +import java.util.LinkedHashMap; +import java.util.Map; + +/** + * @author : chen weijie + * @Date: 2020-08-26 10:29 + */ +public class CacheMap extends LinkedHashMap { + + + private int limit; + + public CacheMap(int limit) { + super(limit, 0.75f, true); + this.limit = limit; + } + + public void putVal(K k, V v) { + super.put(k, v); + } + + public V getVal(K k) { + return super.getOrDefault(k, (V) new Object()); + } + + + @Override + protected boolean removeEldestEntry(Map.Entry entry) { + return super.size() > limit; + } + + +} diff --git a/src/main/java/com/chen/algorithm/RevertTree.java b/src/main/java/com/chen/algorithm/RevertTree.java new file mode 100644 index 0000000..8a4e957 --- /dev/null +++ b/src/main/java/com/chen/algorithm/RevertTree.java @@ -0,0 +1,106 @@ +package com.chen.algorithm; + +import com.alibaba.fastjson.JSONObject; +import org.junit.Test; + +import java.util.LinkedList; + +/** + * @author : chen weijie + * @Date: 2020-08-05 21:25 + */ +public class RevertTree { + + + class TreeNode { + + int val; + TreeNode left; + TreeNode right; + + public TreeNode(int val, TreeNode left, TreeNode right) { + this.right = right; + this.left = left; + 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; + } + } + + public TreeNode revert(TreeNode root) { + + if (root == null) { + return null; + } + + LinkedList 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 result = new ArrayList<>(); + + if (root == null) { + return result; + } + inorderTraversal(root.left); + result.add(root.val); + inorderTraversal(root.right); + + return result; + } + + +} diff --git a/src/main/java/com/chen/algorithm/study/test94/Solution1.java b/src/main/java/com/chen/algorithm/study/test94/Solution1.java new file mode 100644 index 0000000..1ed08da --- /dev/null +++ b/src/main/java/com/chen/algorithm/study/test94/Solution1.java @@ -0,0 +1,59 @@ +package com.chen.algorithm.study.test94; + +import com.alibaba.fastjson.JSONObject; +import org.junit.Test; + +import java.util.ArrayList; +import java.util.List; +import java.util.Stack; + +/** + * @author : chen weijie + * @Date: 2019-11-24 19:06 + */ +public class Solution1 { + + + class TreeNode { + int val; + TreeNode left; + TreeNode right; + TreeNode(int x) { + val = x; + } + } + + + public List inorderTraversal(TreeNode root) { + + List result = new ArrayList<>(); + Stack stack = new Stack<>(); + TreeNode curr = root; + + while (curr != null || !stack.isEmpty()) { + while (curr != null) { + stack.push(curr); + curr = curr.left; + } + curr = stack.pop(); + result.add(curr.val); + curr = curr.right; + } + return result; + } + + + @Test + public void testCase() { + + TreeNode root = new TreeNode(1); + TreeNode root2 = new TreeNode(2); + TreeNode root3 = new TreeNode(3); + root.right = root2; + root2.left = root3; + System.out.println(JSONObject.toJSONString(inorderTraversal(root))); + + } + + +} diff --git a/src/main/java/com/chen/algorithm/study/test94/Solution2.java b/src/main/java/com/chen/algorithm/study/test94/Solution2.java new file mode 100644 index 0000000..f970d24 --- /dev/null +++ b/src/main/java/com/chen/algorithm/study/test94/Solution2.java @@ -0,0 +1,48 @@ +package com.chen.algorithm.study.test94; + +import java.util.ArrayList; +import java.util.List; +import java.util.Stack; + +/** + * https://leetcode-cn.com/problems/binary-tree-inorder-traversal/solution/94er-cha-shu-de-zhong-xu-bian-li-by-wulin-v/ + * + * @author : chen weijie + * @Date: 2020-05-11 23:42 + */ +public class Solution2 { + + class TreeNode { + int val; + TreeNode left; + TreeNode right; + + TreeNode(int x) { + val = x; + } + } + + + public List inorderTraversal(TreeNode root) { + + if (root == null) { + return new ArrayList<>(); + } + + List result = new ArrayList<>(); + Stack stack = new Stack<>(); + TreeNode curr = root; + while (!stack.isEmpty() || curr != null) { + while (curr != null) { + stack.push(curr); + curr = curr.left; + } + curr = stack.pop(); + result.add(curr.val); + curr = curr.right; + } + return result; + } + + +} diff --git a/src/main/java/com/chen/algorithm/study/test94/Solution3.java b/src/main/java/com/chen/algorithm/study/test94/Solution3.java new file mode 100644 index 0000000..ed00ff6 --- /dev/null +++ b/src/main/java/com/chen/algorithm/study/test94/Solution3.java @@ -0,0 +1,63 @@ +package com.chen.algorithm.study.test94; + +import com.alibaba.fastjson.JSONObject; +import org.junit.Test; + +import java.util.ArrayList; +import java.util.List; +import java.util.Stack; + +/** + * @author : chen weijie + * @Date: 2019-11-24 19:06 + */ +public class Solution3 { + + + class TreeNode { + int val; + TreeNode left; + TreeNode right; + + TreeNode(int x) { + val = x; + } + } + + + public List inorderTraversal(TreeNode root) { + List result = new ArrayList<>(); + + if (root == null){ + return result; + } + + Stack stack = new Stack<>(); + TreeNode curr = root; + + while ( !stack.isEmpty() || curr !=null){ + while (curr != null){ + stack.push(curr); + curr = curr.left; + } + curr = stack.pop(); + result.add(curr.val); + curr = curr.right; + } + return result; + } + + @Test + public void testCase() { + + TreeNode root = new TreeNode(1); + TreeNode root2 = new TreeNode(2); + TreeNode root3 = new TreeNode(3); + root.right = root2; + root2.left = root3; + System.out.println(JSONObject.toJSONString(inorderTraversal(root))); + + } + + +} diff --git a/src/main/java/com/chen/algorithm/study/test96/Solution.java b/src/main/java/com/chen/algorithm/study/test96/Solution.java new file mode 100644 index 0000000..4531f27 --- /dev/null +++ b/src/main/java/com/chen/algorithm/study/test96/Solution.java @@ -0,0 +1,25 @@ +package com.chen.algorithm.study.test96; + +/** + * + * 暂时跳过。。。 + * @author : chen weijie + * @Date: 2019-12-03 00:44 + */ +public class Solution { + + + public int numTrees(int n) { + int[] dp = new int[n+1]; + dp[0] = 1; + dp[1] = 1; + + for(int i = 2; i < n + 1; i++) + for(int j = 1; j < i + 1; j++) + dp[i] += dp[j-1] * dp[i-j]; + + return dp[n]; + } + + +} diff --git a/src/main/java/com/chen/algorithm/study/test98/Solution.java b/src/main/java/com/chen/algorithm/study/test98/Solution.java new file mode 100644 index 0000000..b7b37f1 --- /dev/null +++ b/src/main/java/com/chen/algorithm/study/test98/Solution.java @@ -0,0 +1,48 @@ +package com.chen.algorithm.study.test98; + +/** + * @author : chen weijie + * @Date: 2020-08-30 18:32 + */ +public class Solution { + + + class TreeNode { + int val; + TreeNode left; + TreeNode right; + + TreeNode(int x) { + val = x; + } + } + + + /** + * 要求根节点大于左子树的最大值,小于右子树的最小值 + * + * @param root + * @return + */ + public boolean isValidBST(TreeNode root) { + return isValid(root, null, null); + } + + + public boolean isValid(TreeNode root, Integer max, Integer min) { + + if (root == null) { + return true; + } + if (min != null && root.val <= min) { + return false; + } + if (max != null && root.val >= max) { + return false; + } + + return isValid(root.left, min, root.val) && isValid(root.right, root.val, max); + } + + +} diff --git a/src/main/java/com/chen/algorithm/study/test98/Solution1.java b/src/main/java/com/chen/algorithm/study/test98/Solution1.java new file mode 100644 index 0000000..f7617a7 --- /dev/null +++ b/src/main/java/com/chen/algorithm/study/test98/Solution1.java @@ -0,0 +1,61 @@ +package com.chen.algorithm.study.test98; + +import java.util.Stack; + +/** + * @author : chen weijie + * @Date: 2020-08-30 20:54 + */ +public class Solution1 { + + + class TreeNode { + int val; + TreeNode left; + TreeNode right; + + TreeNode(int x) { + val = x; + } + } + + + /** + * 要求根节点大于左子树的最大值,小于右子树的最小值 + * + * @param root + * @return + */ + public boolean isValidBST(TreeNode root) { + + if (root == null) { + return true; + } + + Stack stack = new Stack<>(); + TreeNode curr = root; + +// int preVal = Integer.MIN_VALUE; + double preVal = -Double.MAX_VALUE; + while (!stack.isEmpty() || curr != null) { + while (curr != null) { + stack.push(curr); + curr = curr.left; + } + + curr = stack.pop(); + int currVal = curr.val; + if (preVal >= currVal) { + return false; + } + preVal = currVal; + curr = curr.right; + } + return true; + } + + + + + +} diff --git a/src/main/java/com/chen/algorithm/sum/ArraySum.java b/src/main/java/com/chen/algorithm/sum/ArraySum.java index 9ee76e0..36ce4e4 100644 --- a/src/main/java/com/chen/algorithm/sum/ArraySum.java +++ b/src/main/java/com/chen/algorithm/sum/ArraySum.java @@ -1,7 +1,12 @@ package com.chen.algorithm.sum; +import com.alibaba.fastjson.JSONObject; import org.junit.Test; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + /** * User: chenweijie * Date: 10/18/17 @@ -14,29 +19,33 @@ public class ArraySum { @Test public void test() { - int[] num = {1, 2, 2, 3, 4, 5, 6, 7, 8, 9}; + int[] num = {2, 3, 4, 5, 6, 7, 8, 9}; int sum = 7; - findSum(num, sum); + List> res = findSum(num, sum); + System.out.println(JSONObject.toJSONString(res)); } - public void findSum(int[] num, int sum) { - int left = 0; - int right = 0; + public List> findSum(int[] candidates, int target) { + + List> res = new ArrayList<>(); + Arrays.sort(candidates); - for (int i = 0; i < num.length; i++) { - int curSum = 0; - left = i; - right = i; - while (curSum < sum) { - curSum += num[right++]; + for(int i = 0 ; i list = new ArrayList<>(); + if(currentSum == target){ + for(int j = left; j < right ; j++){ + list.add(candidates[j]); } - System.out.println(); + res.add(list); } } + return res; } diff --git a/src/main/java/com/chen/algorithm/tree/RevertTree.java b/src/main/java/com/chen/algorithm/tree/RevertTree.java new file mode 100644 index 0000000..5db5b04 --- /dev/null +++ b/src/main/java/com/chen/algorithm/tree/RevertTree.java @@ -0,0 +1,93 @@ +package com.chen.algorithm.tree; + +import java.util.LinkedList; +import java.util.List; +import java.util.Queue; +import java.util.Stack; + +/** + * https://zhuanlan.zhihu.com/p/29425290 + * + * @author : chen weijie + * @Date: 2020-07-09 01:51 + */ +public class RevertTree { + + + class Node { + private String value; + private List children; + + public Node(String value, List children) { + this.value = value; + this.children = children; + } + + public Node() { + } + + public String value() { + return this.value; + } + + public void setValue(String value) { + this.value = value; + } + + public void addChild(Node node) { + if (node == null) { + return; + } + this.children.add(node); + } + + public List getChildren() { + return this.children; + } + } + + public void dfs(Node root) { + + if (root == null) { + return; + } + + Stack stack = new Stack<>(); + stack.push(root); + + while (!stack.isEmpty()) { + Node node = stack.pop(); + System.out.println(node.value); + + if (node.children != null && node.children.size() != 0) { + List children = node.children; + for (int i = children.size() - 1; i >= 0; i--) { + stack.push(children.get(i)); + } + } + } + } + + public void bfs(Node root) { + + if (root == null) { + return; + } + + Queue queue = new LinkedList<>(); + queue.add(root); + + while (!queue.isEmpty()) { + Node node = queue.poll(); + System.out.println(node.value); + + List children = node.children; + + for (Node child : children) { + queue.add(child); + } + } + } + + +} diff --git a/src/main/java/com/chen/algorithm/SplitList.java b/src/main/java/com/chen/api/util/SplitList.java similarity index 98% rename from src/main/java/com/chen/algorithm/SplitList.java rename to src/main/java/com/chen/api/util/SplitList.java index d6e9762..3c0ff57 100644 --- a/src/main/java/com/chen/algorithm/SplitList.java +++ b/src/main/java/com/chen/api/util/SplitList.java @@ -1,4 +1,4 @@ -package com.chen.algorithm; +package com.chen.api.util; import java.util.ArrayList; import java.util.List; diff --git a/src/main/java/com/chen/api/util/bloomFilter/GuavaFilter.java b/src/main/java/com/chen/api/util/bloomFilter/GuavaFilter.java new file mode 100644 index 0000000..5bd45c7 --- /dev/null +++ b/src/main/java/com/chen/api/util/bloomFilter/GuavaFilter.java @@ -0,0 +1,36 @@ +package com.chen.api.util.bloomFilter; + +import com.google.common.hash.BloomFilter; +import com.google.common.hash.Funnels; + +/** + * @author : chen weijie + * @Date: 2020-04-15 01:30 + */ +public class GuavaFilter { + + + /** + * 我们创建了一个最多存放 最多 1500个整数的布隆过滤器,并且我们可以容忍误判的概率为百分之(0.01) + * + * @param args + */ + public static void main(String[] args) { + + // 创建布隆过滤器对象 + BloomFilter filter = BloomFilter.create( + Funnels.integerFunnel(), + 1500, + 0.01); + // 判断指定元素是否存在 + System.out.println(filter.mightContain(1)); + System.out.println(filter.mightContain(2)); + // 将元素添加进布隆过滤器 + filter.put(1); + filter.put(2); + System.out.println(filter.mightContain(1)); + System.out.println(filter.mightContain(2)); + + + } +} diff --git a/src/main/java/com/chen/api/util/bloomFilter/MyBloomFilter.java b/src/main/java/com/chen/api/util/bloomFilter/MyBloomFilter.java new file mode 100644 index 0000000..4dcda0d --- /dev/null +++ b/src/main/java/com/chen/api/util/bloomFilter/MyBloomFilter.java @@ -0,0 +1,104 @@ +package com.chen.api.util.bloomFilter; + +import java.util.BitSet; + +/** + * 一个合适大小的位数组保存数据 + * 几个不同的哈希函数 + * 添加元素到位数组(布隆过滤器)的方法实现 + * 判断给定元素是否存在于位数组(布隆过滤器)的方法实现 + *

+ * 布隆过滤器 + * + * @author : chen weijie + * @Date: 2020-04-15 01:20 + */ +public class MyBloomFilter { + + /** + * 位数组的大小 + */ + private static final int DEFAULT_SIZE = 2 << 24; + /** + * 通过这个数组可以创建 6 个不同的哈希函数 + */ + private static final int[] SEEDS = new int[]{3, 13, 46, 71, 91, 134}; + + /** + * 位数组。数组中的元素只能是 0 或者 1 + */ + private BitSet bits = new BitSet(DEFAULT_SIZE); + + /** + * 存放包含 hash 函数的类的数组 + */ + private SimpleHash[] func = new SimpleHash[SEEDS.length]; + + /** + * 初始化多个包含 hash 函数的类的数组,每个类中的 hash 函数都不一样 + */ + public MyBloomFilter() { + // 初始化多个不同的 Hash 函数 + for (int i = 0; i < SEEDS.length; i++) { + func[i] = new SimpleHash(DEFAULT_SIZE, SEEDS[i]); + } + } + + /** + * 添加元素到位数组 + */ + public void add(Object value) { + for (SimpleHash f : func) { + bits.set(f.hash(value), true); + } + } + + /** + * 判断指定元素是否存在于位数组 + */ + public boolean contains(Object value) { + boolean ret = true; + for (SimpleHash f : func) { + ret = ret && bits.get(f.hash(value)); + } + return ret; + } + + /** + * 静态内部类。用于 hash 操作! + */ + public static class SimpleHash { + + private int cap; + private int seed; + + public SimpleHash(int cap, int seed) { + this.cap = cap; + this.seed = seed; + } + + /** + * 计算 hash 值 + */ + public int hash(Object value) { + int h; + return (value == null) ? 0 : Math.abs(seed * (cap - 1) & ((h = value.hashCode()) ^ (h >>> 16))); + } + + } + + public static void main(String[] args) { + + String value1 = "https://javaguide.cn/"; + String value2 = "https://github.com/Snailclimb"; + MyBloomFilter filter = new MyBloomFilter(); + System.out.println(filter.contains(value1)); + System.out.println(filter.contains(value2)); + filter.add(value1); + filter.add(value2); + System.out.println(filter.contains(value1)); + System.out.println(filter.contains(value2)); + + } + +} diff --git a/src/main/java/com/chen/api/util/clone/Address.java b/src/main/java/com/chen/api/util/clone/Address.java new file mode 100644 index 0000000..96c0f47 --- /dev/null +++ b/src/main/java/com/chen/api/util/clone/Address.java @@ -0,0 +1,30 @@ +package com.chen.api.util.clone; + +/** + * @author : chen weijie + * @Date: 2020-07-23 16:06 + */ +public class Address implements Cloneable { + + private String add; + + public String getAdd() { + return add; + } + + public void setAdd(String add) { + this.add = add; + } + + @Override + public Object clone() { + Address address = null; + try { + address = (Address) super.clone(); + } catch (CloneNotSupportedException e) { + e.printStackTrace(); + } + return address; + } + +} diff --git a/src/main/java/com/chen/api/util/clone/DeepClone.java b/src/main/java/com/chen/api/util/clone/DeepClone.java new file mode 100644 index 0000000..7336a18 --- /dev/null +++ b/src/main/java/com/chen/api/util/clone/DeepClone.java @@ -0,0 +1,27 @@ +package com.chen.api.util.clone; + +/** + * @author : chen weijie + * @Date: 2020-07-23 16:06 + */ +public class DeepClone { + + public static void main(String[] args) { + + Address addr = new Address(); + addr.setAdd("杭州市"); + Student stu1 = new Student(); + stu1.setNumber(123); + stu1.setAddr(addr); + + Student stu2 = (Student) stu1.clone(); + + System.out.println("学生1:" + stu1.getNumber() + ",地址:" + stu1.getAddr().getAdd()); + System.out.println("学生2:" + stu2.getNumber() + ",地址:" + stu2.getAddr().getAdd()); + + addr.setAdd("上海市"); + + System.out.println("学生1:" + stu1.getNumber() + ",地址:" + stu1.getAddr().getAdd()); + System.out.println("学生2:" + stu2.getNumber() + ",地址:" + stu2.getAddr().getAdd()); + } +} diff --git a/src/main/java/com/chen/api/util/clone/ShallowClone.java b/src/main/java/com/chen/api/util/clone/ShallowClone.java new file mode 100644 index 0000000..3bb995b --- /dev/null +++ b/src/main/java/com/chen/api/util/clone/ShallowClone.java @@ -0,0 +1,27 @@ +package com.chen.api.util.clone; + +/** + * https://www.cnblogs.com/qian123/p/5710533.html + * + * @author : chen weijie + * @Date: 2020-07-23 16:02 + */ +public class ShallowClone { + + + public static void main(String args[]) { + Student stu1 = new Student(); + stu1.setNumber(12345); + Student stu2 = (Student)stu1.clone(); + + System.out.println("学生1:" + stu1.getNumber()); + System.out.println("学生2:" + stu2.getNumber()); + + stu2.setNumber(54321); + + System.out.println("学生1:" + stu1.getNumber()); + System.out.println("学生2:" + stu2.getNumber()); + } + + +} diff --git a/src/main/java/com/chen/api/util/clone/Student.java b/src/main/java/com/chen/api/util/clone/Student.java new file mode 100644 index 0000000..2a1a30d --- /dev/null +++ b/src/main/java/com/chen/api/util/clone/Student.java @@ -0,0 +1,51 @@ +package com.chen.api.util.clone; + +/** + * + * 1. 被复制的类需要实现Clonenable接口(不实现的话在调用clone方法会抛出CloneNotSupportedException异常), 该接口为标记接口(不含任何方法) + * + * 2. 覆盖clone()方法,访问修饰符设为public。方法中调用super.clone()方法得到需要的复制对象。(native为本地方法) + * + * + * # 通过深复制, + * 序列化就是将对象写到流的过程,写到流中的对象是原有对象的一个拷贝,而原对象仍然存在于内存中。通过序列化实现的拷贝不仅可以复制对象本身, + * 而且可以复制其引用的成员对象,因此通过序列化将对象写到一个流中,再从流里将其读出来,可以实现深克隆。需要注意的是能够实现序列化的对象其类必须实现Serializable接口, + * 否则无法实现序列化操作。 + * + * @author : chen weijie + * @Date: 2020-07-23 16:02 + */ +public class Student implements Cloneable { + + private int number; + + private Address addr; + + public int getNumber() { + return number; + } + + public void setNumber(int number) { + this.number = number; + } + + public Address getAddr() { + return addr; + } + + public void setAddr(Address addr) { + this.addr = addr; + } + + @Override + public Object clone() { + Student stu = null; + try{ + stu = (Student)super.clone(); //浅复制 + }catch(CloneNotSupportedException e) { + e.printStackTrace(); + } +// stu.addr = (Address) addr.clone(); //深度复制 + return stu; + } +} diff --git a/src/main/java/com/chen/api/util/generic/GenericClass/Generic.java b/src/main/java/com/chen/api/util/generic/GenericClass/Generic.java new file mode 100644 index 0000000..91609a4 --- /dev/null +++ b/src/main/java/com/chen/api/util/generic/GenericClass/Generic.java @@ -0,0 +1,31 @@ +package com.chen.api.util.generic.GenericClass; + +/** + * 泛型类,是在实例化类的时候指明泛型的具体类型; + *

+ * 泛型方法,是在调用方法的时候指明泛型的具体类型。 + * + * @author Chen WeiJie + * @date 2019-12-04 17:12:50 + **/ +public class Generic { + + + private T key; + + + public Generic(T key) { + this.key = key; + } + + + public T getKey() { + return key; + } + + public void setKey(T key) { + this.key = key; + } + + +} diff --git a/src/main/java/com/chen/api/util/generic/GenericClass/GenericTest.java b/src/main/java/com/chen/api/util/generic/GenericClass/GenericTest.java new file mode 100644 index 0000000..edc7059 --- /dev/null +++ b/src/main/java/com/chen/api/util/generic/GenericClass/GenericTest.java @@ -0,0 +1,20 @@ +package com.chen.api.util.generic.GenericClass; + +/** + * @author Chen WeiJie + * @date 2019-12-04 17:15:47 + **/ +public class GenericTest { + + + public static void main(String[] args) { + + //在实例化泛型类时,必须指定T的具体类型 + Generic generic = new Generic<>(123); + Generic genericStr = new Generic<>("221"); + System.out.println("泛型测试 key is " + generic.getKey()); + System.out.println("泛型测试 key is " + genericStr.getKey()); + + } + +} diff --git a/src/main/java/com/chen/api/util/generic/genericMethod/GenericMethod.java b/src/main/java/com/chen/api/util/generic/genericMethod/GenericMethod.java new file mode 100644 index 0000000..8f252c0 --- /dev/null +++ b/src/main/java/com/chen/api/util/generic/genericMethod/GenericMethod.java @@ -0,0 +1,67 @@ +package com.chen.api.util.generic.genericMethod; + +/** + * 泛型方法,是在调用方法的时候指明泛型的具体类型。 + *

+ * public 与 返回值中间非常重要,可以理解为声明此方法为泛型方法。 + * + * @author Chen WeiJie + * @date 2019-12-05 15:37:05 + **/ +public class GenericMethod { + + + /** + * 1)public 与 返回值中间非常重要,可以理解为声明此方法为泛型方法。 + * 2)只有声明了的方法才是泛型方法,泛型类中的使用了泛型的成员方法并不是泛型方法。 + * 3)表明该方法将使用泛型类型T,此时才可以在方法中使用泛型类型T。 + * 4)与泛型类的定义一样,此处T可以随便写为任意标识,常见的如T、E、K、V等形式的参数常用于表示泛型。 + * + * @param tClass + * @param + * @return + * @throws IllegalAccessException + * @throws InstantiationException + */ + public static T getGenericMethod(Class tClass) throws IllegalAccessException, InstantiationException { + + T instance = tClass.newInstance(); + return instance; + } + + + public void getClassType(E e) { + System.out.println(e); + } + + + /** + * 泛型方法与可变参数 + * + * @param args + * @param + */ + public void printMsg(T... args) { + + for (T arg : args) { + System.out.println(arg.toString()); + } + } + + + //泛型类中的’?’是类型实参,而不是类型形参 + + + public static void main(String[] args) { + + GenericMethod genericMethod = new GenericMethod(); + //普通泛型方法 + String name = "zhang san"; + genericMethod.getClassType(name); + + // 可变参数的泛型方法 + genericMethod.printMsg("111", 222, "aaaa", "2323.4", 55.55); + } + + +} diff --git a/src/main/java/com/chen/api/util/aqs/Mutex.java b/src/main/java/com/chen/api/util/lock/aqs/Mutex.java similarity index 98% rename from src/main/java/com/chen/api/util/aqs/Mutex.java rename to src/main/java/com/chen/api/util/lock/aqs/Mutex.java index 628c1c5..0253d23 100644 --- a/src/main/java/com/chen/api/util/aqs/Mutex.java +++ b/src/main/java/com/chen/api/util/lock/aqs/Mutex.java @@ -1,4 +1,4 @@ -package com.chen.api.util.aqs; +package com.chen.api.util.lock.aqs; import java.util.concurrent.TimeUnit; import java.util.concurrent.locks.AbstractQueuedSynchronizer; diff --git a/src/main/java/com/chen/api/util/aqs/TwinsLock.java b/src/main/java/com/chen/api/util/lock/aqs/TwinsLock.java similarity index 96% rename from src/main/java/com/chen/api/util/aqs/TwinsLock.java rename to src/main/java/com/chen/api/util/lock/aqs/TwinsLock.java index ad36fcc..8454ae2 100644 --- a/src/main/java/com/chen/api/util/aqs/TwinsLock.java +++ b/src/main/java/com/chen/api/util/lock/aqs/TwinsLock.java @@ -1,4 +1,4 @@ -package com.chen.api.util.aqs; +package com.chen.api.util.lock.aqs; import java.util.concurrent.TimeUnit; import java.util.concurrent.locks.AbstractQueuedSynchronizer; @@ -25,6 +25,7 @@ private static final class Sync extends AbstractQueuedSynchronizer { setState(count); } + @Override public int tryAcquireShared(int reduceCount) { for (; ; ) { int current = getState(); @@ -36,6 +37,7 @@ public int tryAcquireShared(int reduceCount) { } + @Override public boolean tryReleaseShared(int returnCount) { for (; ; ) { int current = getState(); diff --git a/src/main/java/com/chen/api/util/aqs/TwinsLockTest.java b/src/main/java/com/chen/api/util/lock/aqs/TwinsLockTest.java similarity index 97% rename from src/main/java/com/chen/api/util/aqs/TwinsLockTest.java rename to src/main/java/com/chen/api/util/lock/aqs/TwinsLockTest.java index 478d458..defab62 100644 --- a/src/main/java/com/chen/api/util/aqs/TwinsLockTest.java +++ b/src/main/java/com/chen/api/util/lock/aqs/TwinsLockTest.java @@ -1,4 +1,4 @@ -package com.chen.api.util.aqs; +package com.chen.api.util.lock.aqs; import java.util.concurrent.locks.Lock; diff --git a/src/main/java/com/chen/api/util/lock/SyncThread.java b/src/main/java/com/chen/api/util/lock/deadLock/SyncThread.java similarity index 96% rename from src/main/java/com/chen/api/util/lock/SyncThread.java rename to src/main/java/com/chen/api/util/lock/deadLock/SyncThread.java index ecd64be..f68a018 100644 --- a/src/main/java/com/chen/api/util/lock/SyncThread.java +++ b/src/main/java/com/chen/api/util/lock/deadLock/SyncThread.java @@ -1,4 +1,4 @@ -package com.chen.api.util.lock; +package com.chen.api.util.lock.deadLock; /** * @Author chenweijie diff --git a/src/main/java/com/chen/api/util/lock/ThreadDeadlock.java b/src/main/java/com/chen/api/util/lock/deadLock/ThreadDeadlock.java similarity index 93% rename from src/main/java/com/chen/api/util/lock/ThreadDeadlock.java rename to src/main/java/com/chen/api/util/lock/deadLock/ThreadDeadlock.java index 1d90201..f266d64 100644 --- a/src/main/java/com/chen/api/util/lock/ThreadDeadlock.java +++ b/src/main/java/com/chen/api/util/lock/deadLock/ThreadDeadlock.java @@ -1,4 +1,4 @@ -package com.chen.api.util.lock; +package com.chen.api.util.lock.deadLock; /** * 死锁范例 diff --git a/src/main/java/com/chen/api/util/lock/reentrantLock/FairReentrantLockTest.java b/src/main/java/com/chen/api/util/lock/reentrantLock/FairReentrantLockTest.java new file mode 100644 index 0000000..a129b82 --- /dev/null +++ b/src/main/java/com/chen/api/util/lock/reentrantLock/FairReentrantLockTest.java @@ -0,0 +1,58 @@ +package com.chen.api.util.lock.reentrantLock; + +import java.util.concurrent.TimeUnit; +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReentrantLock; + +/** + * 公平锁 + *

+ * 大部分情况下我们使用非公平锁,因为其性能比公平锁好很多。但是公平锁能够避免线程饥饿,某些情况下也很有用。 + * + * @author : chen weijie + * @Date: 2019-11-11 18:33 + */ +public class FairReentrantLockTest { + + + static Lock lock = new ReentrantLock(true); + + + public static void main(String[] args) { + + for (int i = 0; i < 5; i++) { + new Thread(new ThreadDemo(i)).start(); + } + + } + + + static class ThreadDemo implements Runnable { + + Integer id; + + public ThreadDemo(Integer id) { + this.id = id; + } + + @Override + public void run() { + + try { + TimeUnit.MILLISECONDS.sleep(1000); + } catch (InterruptedException e) { + e.printStackTrace(); + } + + for (int i = 0; i < 2; i++) { + lock.lock(); + System.out.println("获得锁的线程:" + id); + lock.unlock(); + } + + + } + } + + +} diff --git a/src/main/java/com/chen/api/util/lock/reentrantLock/LockInterruptiblyTest.java b/src/main/java/com/chen/api/util/lock/reentrantLock/LockInterruptiblyTest.java new file mode 100644 index 0000000..03fa57d --- /dev/null +++ b/src/main/java/com/chen/api/util/lock/reentrantLock/LockInterruptiblyTest.java @@ -0,0 +1,58 @@ +package com.chen.api.util.lock.reentrantLock; + +import java.util.concurrent.TimeUnit; +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReentrantLock; + +/** + * + * 构造死锁场景:创建两个子线程,子线程在运行时会分别尝试获取两把锁。其中一个线程先获取锁1在获取锁2,另一个线程正好相反。如果没有外界中断,该程序将处于死锁状态永远无法停止。 + * + * @author : chen weijie + * @Date: 2019-11-11 18:41 + */ +public class LockInterruptiblyTest { + + + static Lock lock1 = new ReentrantLock(); + static Lock lock2 = new ReentrantLock(); + + public static void main(String[] args) { + + Thread thread = new Thread(new ThreadDemo(lock1, lock2)); + Thread thread1 = new Thread(new ThreadDemo(lock2, lock1)); + + thread.start(); + thread1.start(); + thread.interrupt(); + } + + + static class ThreadDemo implements Runnable { + + Lock firstLock; + Lock secondLock; + + public ThreadDemo(Lock firstLock, Lock secondLock) { + this.firstLock = firstLock; + this.secondLock = secondLock; + } + + @Override + public void run() { + try { + firstLock.lockInterruptibly(); + TimeUnit.MILLISECONDS.sleep(10); + secondLock.lockInterruptibly(); + } catch (InterruptedException e) { + e.printStackTrace(); + } finally { + firstLock.unlock(); + secondLock.unlock(); + System.out.println(Thread.currentThread().getName() + "正常结束"); + } + } + } + + +} diff --git a/src/main/java/com/chen/api/util/lock/reentrantLock/TryLockTest.java b/src/main/java/com/chen/api/util/lock/reentrantLock/TryLockTest.java new file mode 100644 index 0000000..860be26 --- /dev/null +++ b/src/main/java/com/chen/api/util/lock/reentrantLock/TryLockTest.java @@ -0,0 +1,64 @@ +package com.chen.api.util.lock.reentrantLock; + +import java.util.concurrent.TimeUnit; +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReentrantLock; + +/** + * 等待超时 + * + * @author : chen weijie + * @Date: 2019-11-11 18:49 + */ +public class TryLockTest { + + + static Lock lock1 = new ReentrantLock(); + static Lock lock2 = new ReentrantLock(); + + public static void main(String[] args) { + + Thread thread = new Thread(new ThreadDemo(lock1, lock2)); + Thread thread1 = new Thread(new ThreadDemo(lock2, lock1)); + + thread.start(); + thread1.start(); + thread.interrupt(); + } + + + static class ThreadDemo implements Runnable { + + Lock firstLock; + Lock secondLock; + + public ThreadDemo(Lock firstLock, Lock secondLock) { + this.firstLock = firstLock; + this.secondLock = secondLock; + } + + @Override + public void run() { + try { + while (!firstLock.tryLock()) { + TimeUnit.MILLISECONDS.sleep(100); + System.out.println("firstLock 未获取到"); + } + + while (!secondLock.tryLock()) { + TimeUnit.MILLISECONDS.sleep(100); + System.out.println("secondLock 未获取到"); +// lock1.unlock(); + } + + } catch (InterruptedException e) { + e.printStackTrace(); + } finally { + firstLock.unlock(); + secondLock.unlock(); + System.out.println(Thread.currentThread().getName() + "正常结束"); + } + } + } + +} diff --git a/src/main/java/com/chen/api/util/map/HashMapTest.java b/src/main/java/com/chen/api/util/map/HashMapTest.java new file mode 100644 index 0000000..ce5f005 --- /dev/null +++ b/src/main/java/com/chen/api/util/map/HashMapTest.java @@ -0,0 +1,36 @@ +package com.chen.api.util.map; + +import java.util.HashMap; + +/** + * @author : chen weijie + * @Date: 2020-05-15 17:04 + */ +public class HashMapTest { + + + private static HashMap map = new HashMap<>(2, 0.75f); + + public static void main(String[] args) { + map.put(5, "C"); + + new Thread("Thread1") { + @Override + public void run() { + map.put(7, "B"); + System.out.println(map); + } + }.start(); + + new Thread("Thread2") { + @Override + public void run() { + map.put(3, "A"); + System.out.println(map); + } + + ; + }.start(); + } + +} diff --git a/src/main/java/com/chen/api/util/map/LinkedCacheHashMap.java b/src/main/java/com/chen/api/util/map/LinkedCacheHashMap.java new file mode 100644 index 0000000..70a7d24 --- /dev/null +++ b/src/main/java/com/chen/api/util/map/LinkedCacheHashMap.java @@ -0,0 +1,41 @@ +package com.chen.api.util.map; + +import java.util.LinkedHashMap; +import java.util.Map; + +/** + * @author : chen weijie + * @Date: 2020-06-29 01:06 + */ +public class LinkedCacheHashMap extends LinkedHashMap { + + + private static int defaul_limt = 100; + + private int limt; + + public LinkedCacheHashMap() { + this(defaul_limt); + } + + public LinkedCacheHashMap(Integer size) { + super(size, 0.75f, true); + this.limt = size; + } + + public V getV(K key) { + return get(key); + } + + public void save(K key, V value) { + put(key, value); + } + + + @Override + protected boolean removeEldestEntry(Map.Entry value) { + return super.size() > limt; + } + + +} diff --git a/src/main/java/com/chen/api/util/queue/BlockQueue.java b/src/main/java/com/chen/api/util/queue/BlockQueue.java new file mode 100644 index 0000000..da7d2c6 --- /dev/null +++ b/src/main/java/com/chen/api/util/queue/BlockQueue.java @@ -0,0 +1,60 @@ +package com.chen.api.util.queue; + +import java.util.Comparator; +import java.util.concurrent.*; + +/** + * @author : chen weijie + * @Date: 2020-06-11 16:54 + */ +public class BlockQueue { + + + public static void main(String[] args) throws InterruptedException { + + + BlockingQueue queue = new LinkedBlockingQueue<>(); + + queue.add(1); + queue.offer(10); + queue.put(3); + + Integer d = queue.peek(); + Integer f = queue.element(); + Integer c = queue.remove(); + Integer b = queue.poll(); + Integer a = queue.take(); + + + PriorityBlockingQueue priorityBlockingQueue = new PriorityBlockingQueue<>(); + priorityBlockingQueue.put(new Student(1)); + priorityBlockingQueue.put(new Student(12)); + priorityBlockingQueue.put(new Student(13)); + + + } + + + static class Student implements Comparator { + + private Integer age; + + public Student(Integer age) { + this.age = age; + } + + public Integer getAge() { + return age; + } + + public void setAge(Integer age) { + this.age = age; + } + + @Override + public int compare(Student o1, Student o2) { + return o1.getAge() - o2.getAge(); + } + } + +} diff --git a/src/main/java/com/chen/api/util/reflection/anonotation/Test.java b/src/main/java/com/chen/api/util/reflection/anonotation/Test.java new file mode 100644 index 0000000..4dbbd1c --- /dev/null +++ b/src/main/java/com/chen/api/util/reflection/anonotation/Test.java @@ -0,0 +1,30 @@ +package com.chen.api.util.reflection.anonotation; + +import org.springframework.stereotype.Controller; + +import java.lang.annotation.Annotation; + +/** + * @author : chen weijie + * @Date: 2019-10-23 00:14 + */ +@Controller +public class Test { + + + public static void main(String[] args) { + + Test test = new Test(); + + Class clazz = test.getClass(); + Annotation[] annotations = clazz.getAnnotations(); + + for (Annotation annotation : annotations) { + + System.out.println(annotation); + } + + + } + +} diff --git a/src/main/java/com/chen/api/util/reflection/field/Test.java b/src/main/java/com/chen/api/util/reflection/field/Test.java new file mode 100644 index 0000000..f24f9f4 --- /dev/null +++ b/src/main/java/com/chen/api/util/reflection/field/Test.java @@ -0,0 +1,45 @@ +package com.chen.api.util.reflection.field; + +import java.lang.reflect.Constructor; +import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; + +/** + * @author : chen weijie + * @Date: 2019-10-23 00:07 + */ +public class Test { + + public Test(){ + System.out.println("无参构造器 Run..........."); + } + + + private String testName = "hello"; + + public String getTestName() { + return testName; + } + + + public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, IllegalAccessException, NoSuchMethodException, InvocationTargetException, InstantiationException { + + Class clazz = Test.class; + Class clazz2 = Class.forName("com.chen.api.util.reflection.field.Test"); + Test test = new Test(); + Class clazz3 = test.getClass(); + + Field field = clazz3.getDeclaredField("testName"); + field.setAccessible(true); + field.set(test, "nihao"); + + Constructor constructor1 = clazz3.getConstructor(); + Test test1 = (Test) constructor1.newInstance(); + + System.out.println("testName:" + test1.getTestName()); + + + } + + +} diff --git a/src/main/java/com/chen/api/util/socket/bio/IOClient.java b/src/main/java/com/chen/api/util/socket/bio/IOClient.java new file mode 100644 index 0000000..3dfa6f0 --- /dev/null +++ b/src/main/java/com/chen/api/util/socket/bio/IOClient.java @@ -0,0 +1,33 @@ +package com.chen.api.util.socket.bio; + +import java.io.IOException; +import java.net.Socket; +import java.util.Date; + +/** + * @author : chen weijie + * @Date: 2020-05-29 00:01 + */ +public class IOClient { + + + public static void main(String[] args) { + // TODO 创建多个线程,模拟多个客户端连接服务端 + + for (int i = 0; i < 10; i++) { + new Thread(() -> { + try { + Socket socket = new Socket("localhost",3333); + while (true){ + socket.getOutputStream().write((new Date() + " hello world").getBytes()); + Thread.sleep(2000); + } + } catch (IOException | InterruptedException e) { + e.printStackTrace(); + } + }).start(); + } + + } + +} diff --git a/src/main/java/com/chen/api/util/socket/bio/IOServer.java b/src/main/java/com/chen/api/util/socket/bio/IOServer.java new file mode 100644 index 0000000..efe2ffa --- /dev/null +++ b/src/main/java/com/chen/api/util/socket/bio/IOServer.java @@ -0,0 +1,48 @@ +package com.chen.api.util.socket.bio; + +import java.io.IOException; +import java.io.InputStream; +import java.net.ServerSocket; +import java.net.Socket; + +/** + * @author : chen weijie + * @Date: 2020-05-29 00:05 + */ +public class IOServer { + + + public static void main(String[] args) throws IOException { + // TODO 服务端处理客户端连接请求 + ServerSocket serverSocket = new ServerSocket(3333); + + // 接收到客户端连接请求之后为每个客户端创建一个新的线程进行链路处理 + new Thread(() -> { + while (true) { + try { + // 阻塞方法获取新的连接 + Socket socket = serverSocket.accept(); + + // 每一个新的连接都创建一个线程,负责读取数据 + new Thread(() -> { + try { + int len; + byte[] data = new byte[1024]; + InputStream inputStream = socket.getInputStream(); + // 按字节流方式读取数据 + while ((len = inputStream.read(data)) != -1) { + System.out.println(new String(data, 0, len)); + } + } catch (IOException e) { + } + }).start(); + + } catch (IOException e) { + } + + } + }).start(); + + } + +} diff --git a/src/main/java/com/chen/api/util/socket/nio/NIOServer.java b/src/main/java/com/chen/api/util/socket/nio/NIOServer.java new file mode 100644 index 0000000..53806c3 --- /dev/null +++ b/src/main/java/com/chen/api/util/socket/nio/NIOServer.java @@ -0,0 +1,95 @@ +package com.chen.api.util.socket.nio; + +import java.io.IOException; +import java.net.InetSocketAddress; +import java.nio.ByteBuffer; +import java.nio.channels.SelectionKey; +import java.nio.channels.Selector; +import java.nio.channels.ServerSocketChannel; +import java.nio.channels.SocketChannel; +import java.nio.charset.Charset; +import java.util.Iterator; +import java.util.Set; + +/** + * @author : chen weijie + * @Date: 2020-05-29 00:17 + */ +public class NIOServer { + + public static void main(String[] args) throws IOException { + // 1. serverSelector负责轮询是否有新的连接,服务端监测到新的连接之后,不再创建一个新的线程, + // 而是直接将新连接绑定到clientSelector上,这样就不用 IO 模型中 1w 个 while 循环在死等 + Selector serverSelector = Selector.open(); + // 2. clientSelector负责轮询连接是否有数据可读 + Selector clientSelector = Selector.open(); + + new Thread(() -> { + try { + // 对应IO编程中服务端启动 + ServerSocketChannel listenerChannel = ServerSocketChannel.open(); + listenerChannel.socket().bind(new InetSocketAddress(3333)); + listenerChannel.configureBlocking(false); + listenerChannel.register(serverSelector, SelectionKey.OP_ACCEPT); + + while (true) { + // 监测是否有新的连接,这里的1指的是阻塞的时间为 1ms + if (serverSelector.select(1) > 0) { + Set set = serverSelector.selectedKeys(); + Iterator keyIterator = set.iterator(); + + while (keyIterator.hasNext()) { + SelectionKey key = keyIterator.next(); + + if (key.isAcceptable()) { + try { + // (1) 每来一个新连接,不需要创建一个线程,而是直接注册到clientSelector + SocketChannel clientChannel = ((ServerSocketChannel) key.channel()).accept(); + clientChannel.configureBlocking(false); + clientChannel.register(clientSelector, SelectionKey.OP_READ); + } finally { + keyIterator.remove(); + } + } + + } + } + } + } catch (IOException ignored) { + } + }).start(); + new Thread(() -> { + try { + while (true) { + // (2) 批量轮询是否有哪些连接有数据可读,这里的1指的是阻塞的时间为 1ms + if (clientSelector.select(1) > 0) { + Set set = clientSelector.selectedKeys(); + Iterator keyIterator = set.iterator(); + + while (keyIterator.hasNext()) { + SelectionKey key = keyIterator.next(); + + if (key.isReadable()) { + try { + SocketChannel clientChannel = (SocketChannel) key.channel(); + ByteBuffer byteBuffer = ByteBuffer.allocate(1024); + // (3) 面向 Buffer + clientChannel.read(byteBuffer); + byteBuffer.flip(); + System.out.println(Thread.currentThread()+"==="+ + Charset.defaultCharset().newDecoder().decode(byteBuffer).toString()); + } finally { + keyIterator.remove(); + key.interestOps(SelectionKey.OP_READ); + } + } + + } + } + } + } catch (IOException ignored) { + } + }).start(); + + } +} diff --git a/src/main/java/com/chen/api/util/spi/Main.java b/src/main/java/com/chen/api/util/spi/Main.java new file mode 100644 index 0000000..1ff3dac --- /dev/null +++ b/src/main/java/com/chen/api/util/spi/Main.java @@ -0,0 +1,24 @@ +package com.chen.api.util.spi; + +import java.util.Iterator; +import java.util.ServiceLoader; + +/** + * @author : chen weijie + * @Date: 2020-06-15 11:06 + */ +public class Main { + + public static void main(String[] args) { + + System.out.println("hello world"); + + ServiceLoader serviceLoader = ServiceLoader.load(Search.class); + Iterator searchList = serviceLoader.iterator(); + while (searchList.hasNext()) { + Search curSearch = searchList.next(); + curSearch.search("test"); + } + + } +} diff --git a/src/main/java/com/chen/api/util/spi/Search.java b/src/main/java/com/chen/api/util/spi/Search.java new file mode 100644 index 0000000..ab88b81 --- /dev/null +++ b/src/main/java/com/chen/api/util/spi/Search.java @@ -0,0 +1,12 @@ +package com.chen.api.util.spi; + +import java.util.List; + +/** + * @author : chen weijie + * @Date: 2020-06-15 11:02 + */ +public interface Search { + + List search(String word); +} diff --git a/src/main/java/com/chen/api/util/spi/impl/DatabaseSearch.java b/src/main/java/com/chen/api/util/spi/impl/DatabaseSearch.java new file mode 100644 index 0000000..cd853fd --- /dev/null +++ b/src/main/java/com/chen/api/util/spi/impl/DatabaseSearch.java @@ -0,0 +1,18 @@ +package com.chen.api.util.spi.impl; + +import com.chen.api.util.spi.Search; + +import java.util.List; + +/** + * @author : chen weijie + * @Date: 2020-06-15 11:03 + */ +public class DatabaseSearch implements Search { + + @Override + public List search(String word) { + System.out.println("now use database search. keyword:" + word); + return null; + } +} diff --git a/src/main/java/com/chen/api/util/spi/impl/FileSearch.java b/src/main/java/com/chen/api/util/spi/impl/FileSearch.java new file mode 100644 index 0000000..ae9e080 --- /dev/null +++ b/src/main/java/com/chen/api/util/spi/impl/FileSearch.java @@ -0,0 +1,18 @@ +package com.chen.api.util.spi.impl; + +import com.chen.api.util.spi.Search; + +import java.util.List; + +/** + * @author : chen weijie + * @Date: 2020-06-15 11:04 + */ +public class FileSearch implements Search { + + @Override + public List search(String word) { + System.out.println("now use file system search. keyword:" + word); + return null; + } +} diff --git a/src/main/java/com/chen/api/util/syncthread/LockConditionDemo.java b/src/main/java/com/chen/api/util/syncthread/LockConditionDemo.java new file mode 100644 index 0000000..fc25733 --- /dev/null +++ b/src/main/java/com/chen/api/util/syncthread/LockConditionDemo.java @@ -0,0 +1,44 @@ +package com.chen.api.util.syncthread; + +import java.util.concurrent.locks.Condition; +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReentrantLock; + +/** + * @author : chen weijie + * @Date: 2020-07-01 13:28 + */ +public class LockConditionDemo { + + private Lock lock = new ReentrantLock(); + private Condition condition = lock.newCondition(); + + public static void main(String[] args) throws InterruptedException { + + //使用同一个LockConditionDemo对象,使得lock、condition一样 + LockConditionDemo demo = new LockConditionDemo(); + new Thread(() -> demo.await(), "thread1").start(); + Thread.sleep(3000); + new Thread(() -> demo.signal(), "thread2").start(); + } + + private void await() { + try { + lock.lock(); + System.out.println("开始等待await! ThreadName:" + Thread.currentThread().getName()); + condition.await(); + System.out.println("等待await结束! ThreadName:" + Thread.currentThread().getName()); + } catch (InterruptedException e) { + e.printStackTrace(); + } finally { + lock.unlock(); + } + } + + private void signal() { + lock.lock(); + System.out.println("发送通知signal! ThreadName:" + Thread.currentThread().getName()); + condition.signal(); + lock.unlock(); + } +} diff --git a/src/main/java/com/chen/api/util/syncthread/LockManyConditionDemo.java b/src/main/java/com/chen/api/util/syncthread/LockManyConditionDemo.java new file mode 100644 index 0000000..feb22f8 --- /dev/null +++ b/src/main/java/com/chen/api/util/syncthread/LockManyConditionDemo.java @@ -0,0 +1,51 @@ +package com.chen.api.util.syncthread; + +import java.util.concurrent.locks.Condition; +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReentrantLock; + +/** + * @author : chen weijie + * @Date: 2020-07-01 13:30 + */ +public class LockManyConditionDemo { + + private Lock lock = new ReentrantLock(); + private Condition conditionA = lock.newCondition(); + private Condition conditionB = lock.newCondition(); + + public static void main(String[] args) throws InterruptedException { + + LockManyConditionDemo demo = new LockManyConditionDemo(); + + new Thread(() -> demo.getAwait(demo.conditionA), "thread1_conditionA").start(); + new Thread(() -> demo.getAwait(demo.conditionB), "thread2_conditionB").start(); + new Thread(() -> demo.getSignal(demo.conditionA), "thread3_conditionA").start(); + System.out.println("稍等5秒再通知其他的线程!"); + Thread.sleep(5000); + new Thread(() -> demo.getSignal(demo.conditionB), "thread4_conditionB").start(); + + } + + private void getAwait(Condition condition) { + try { + lock.lock(); + System.out.println("开始等待await! ThreadName:" + Thread.currentThread().getName()); + condition.await(); + System.out.println("等待await结束! ThreadName:" + Thread.currentThread().getName()); + } catch (InterruptedException e) { + e.printStackTrace(); + } finally { + lock.unlock(); + } + } + + private void getSignal(Condition condition) { + lock.lock(); + System.out.println("发送通知signal! ThreadName:" + Thread.currentThread().getName()); + condition.signal(); + lock.unlock(); + } + + +} diff --git a/src/main/java/com/chen/api/util/syncthread/SynchronizedPrint.java b/src/main/java/com/chen/api/util/syncthread/SynchronizedPrint.java new file mode 100644 index 0000000..a86bdff --- /dev/null +++ b/src/main/java/com/chen/api/util/syncthread/SynchronizedPrint.java @@ -0,0 +1,30 @@ +package com.chen.api.util.syncthread; + +/** + * @author : chen weijie + * @Date: 2020-07-01 13:18 + */ +public class SynchronizedPrint implements Runnable { + + private static final Object lock = new Object(); + private static int count = 0; + + + @Override + public void run() { + + while (true) { + synchronized (lock) { + if (count % 2 == 0) { + try { + lock.wait(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + count++; + lock.notifyAll(); + } + } + } +} diff --git a/src/main/java/com/chen/api/util/thread/countDownLatch/CountDownLatchTest.java b/src/main/java/com/chen/api/util/thread/countDownLatch/CountDownLatchTest.java index 3e67d94..182842f 100644 --- a/src/main/java/com/chen/api/util/thread/countDownLatch/CountDownLatchTest.java +++ b/src/main/java/com/chen/api/util/thread/countDownLatch/CountDownLatchTest.java @@ -9,7 +9,7 @@ public class CountDownLatchTest { - private static volatile CountDownLatch latch = new CountDownLatch(30); + private static volatile CountDownLatch latch = new CountDownLatch(30); public static void main(String[] args) throws InterruptedException { @@ -38,12 +38,12 @@ static class WorkerTask implements Runnable { public void run() { System.out.println("子线程任务正在执行"); try { - Thread.sleep(2000); - + Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } finally { latch.countDown(); + System.out.println(Thread.currentThread().getName() + " down:" + latch.toString()); } diff --git a/src/main/java/com/chen/api/util/thread/deadlock/DeadLockDemo.java b/src/main/java/com/chen/api/util/thread/deadlock/DeadLockDemo.java new file mode 100644 index 0000000..66e001d --- /dev/null +++ b/src/main/java/com/chen/api/util/thread/deadlock/DeadLockDemo.java @@ -0,0 +1,50 @@ +package com.chen.api.util.thread.deadlock; + +/** + * @author : chen weijie + * @Date: 2020-04-06 00:03 + */ +public class DeadLockDemo { + private static Byte[] resource1 = new Byte[0];//资源 1 + private static Byte[] resource2 = new Byte[0];//资源 2 + public static void main(String[] args) { + new Thread(() -> { + synchronized (resource1) { + System.out.println(Thread.currentThread() + "get resource1"); + try { + Thread.sleep(1000); + } catch (InterruptedException e) { + e.printStackTrace(); + } + System.out.println(Thread.currentThread() + "waiting get resource2"); + synchronized (resource2) { + System.out.println(Thread.currentThread() + "get resource2"); + } + try { + Thread.sleep(1000); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + }, "线程 1").start(); + new Thread(() -> { + synchronized (resource2) { + System.out.println(Thread.currentThread() + "get resource2"); + try { + Thread.sleep(1000); + } catch (InterruptedException e) { + e.printStackTrace(); + } + System.out.println(Thread.currentThread() + "waiting get resource1"); + synchronized (resource1) { + System.out.println(Thread.currentThread() + "get resource1"); + } + try { + Thread.sleep(1000); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + }, "线程 2").start(); + } +} diff --git a/src/main/java/com/chen/api/util/thread/forkjoinpool/ForkJoinPoolTest.java b/src/main/java/com/chen/api/util/thread/forkjoinpool/ForkJoinPoolTest.java new file mode 100644 index 0000000..529c30e --- /dev/null +++ b/src/main/java/com/chen/api/util/thread/forkjoinpool/ForkJoinPoolTest.java @@ -0,0 +1,61 @@ +package com.chen.api.util.thread.forkjoinpool; + +import java.util.concurrent.ExecutionException; +import java.util.concurrent.ForkJoinPool; +import java.util.concurrent.ForkJoinTask; +import java.util.concurrent.RecursiveTask; + +/** + * @author : chen weijie + * @Date: 2020-06-11 18:45 + */ +public class ForkJoinPoolTest { + + + static class Task extends RecursiveTask { + + private int start; + + private int end; + private int mid; + + public Task(int start, int end) { + this.start = start; + this.end = end; + } + + @Override + protected Integer compute() { + int sum = 0; + if (end - start < 6) { + // 当任务很小时,直接进行计算 + for (int i = start; i <= end; i++) { + sum += i; + } + System.out.println(Thread.currentThread().getName() + " count sum: " + sum); + } else { + + mid = (end - start) / 2 + start; + Task leftTask = new Task(start, mid); + Task rightTask = new Task(mid + 1, end); + leftTask.fork(); + rightTask.fork(); + sum += leftTask.join(); + sum += rightTask.join(); + } + return sum; + } + } + + + public static void main(String[] args) throws ExecutionException, InterruptedException { + ForkJoinPool forkJoinPool = new ForkJoinPool(); + Task countTask = new Task(1, 100); + ForkJoinTask result = forkJoinPool.submit(countTask); + System.out.println("result: "+result.get()); + forkJoinPool.shutdown(); + } + + + +} diff --git a/src/main/java/com/chen/api/util/thread/join/JoinTest.java b/src/main/java/com/chen/api/util/thread/join/JoinTest.java new file mode 100644 index 0000000..e34273a --- /dev/null +++ b/src/main/java/com/chen/api/util/thread/join/JoinTest.java @@ -0,0 +1,39 @@ +package com.chen.api.util.thread.join; + +/** + * @author : chen weijie + * @Date: 2020-07-28 18:25 + */ +public class JoinTest { + + public static void main(String[] args) { + + Thread t = new Thread(new Runnable() { + @Override + public void run() { + for (int i = 0; i < 200; i++) { + + try { + Thread.sleep(100); + System.out.println("==="+i); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + + } + }); + t.start(); + + try { + t.join(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + + System.out.println(12345); + + + } + +} diff --git a/src/main/java/com/chen/api/util/thread/mutex/TestMutex.java b/src/main/java/com/chen/api/util/thread/mutex/TestMutex.java new file mode 100644 index 0000000..948e237 --- /dev/null +++ b/src/main/java/com/chen/api/util/thread/mutex/TestMutex.java @@ -0,0 +1,81 @@ +package com.chen.api.util.thread.mutex; + + +import com.chen.api.util.lock.aqs.Mutex; + +import java.util.concurrent.BrokenBarrierException; +import java.util.concurrent.CyclicBarrier; + +/** + * https://www.cnblogs.com/chengxiao/archive/2017/07/24/7141160.html + * + * @author : chen weijie + * @Date: 2019-12-02 15:55 + */ +public class TestMutex { + + + private static CyclicBarrier cyclicBarrier = new CyclicBarrier(31); + + + private static int a = 0; + + private static Mutex mutex = new Mutex(); + + public static void main(String args[]) throws BrokenBarrierException, InterruptedException { + + + for (int i = 0; i < 30; i++) { + + Thread thread = new Thread(() -> { + + for (int j = 0; j < 10000; j++) { + // 没有同步措施 + incremnet1(); + } + try { + //等30个线程累加完毕 + cyclicBarrier.await(); + } catch (InterruptedException | BrokenBarrierException e) { + e.printStackTrace(); + } + }); + thread.start(); + } + cyclicBarrier.await(); + System.out.println("加锁前,a=" + a); + // 加锁后 + //重置 +// cyclicBarrier.reset(); + + a = 0; + for (int i = 0; i < 30; i++) { + new Thread(() -> { + for (int i1 = 0; i1 < 10000; i1++) { + increment2();//a++采用Mutex进行同步处理 + } + try { + cyclicBarrier.await();//等30个线程累加完毕 + } catch (Exception e) { + e.printStackTrace(); + } + }).start(); + } + cyclicBarrier.await(); + System.out.println("加锁后,a=" + a); + + } + + + public static void incremnet1() { + a++; + } + + public static void increment2() { + mutex.lock(); + a++; + mutex.unlock(); + } + + +} diff --git a/src/main/java/com/chen/api/util/thread/print/PrintAB.java b/src/main/java/com/chen/api/util/thread/print/PrintAB.java new file mode 100644 index 0000000..9e59228 --- /dev/null +++ b/src/main/java/com/chen/api/util/thread/print/PrintAB.java @@ -0,0 +1,63 @@ +package com.chen.api.util.thread.print; + +import org.junit.Test; + +import java.util.Stack; + +/** + * @author : chen weijie + * @Date: 2020-06-30 19:49 + */ +public class PrintAB { + /* + 1. 任务:两个线程交替的打印从1到100里面的奇数和偶数 + 2. 但是你如果查看打印结果会发现,其实当第一个线程运行的时候 + 另一个线程也没有闲着,也会在else里面打印,只是没有进入到它的if里面 + 3. 这样的方式可以满足交替打印的目的,但是效率不是很高,不推荐,我们再去尝试一下其它的方式 + 4. volatile 是必须要加的 + + */ + + public static int i = 1; + + public static volatile boolean flag = false; + + public static void test1() { + new Thread(() -> { + while (i <= 100) { + if (flag == false) { + System.out.println(Thread.currentThread().getName() + i); + i++; + flag = true; + }else { +// System.out.println("奇"+i); + } + } + }, "奇数线程:").start(); + + new Thread(() -> { + while (i <= 100) { + if (flag == true) { + System.out.println(Thread.currentThread().getName() + i); + i++; + flag = false; + }else { +// System.out.println("偶"+i); + } + } + }, "偶数线程:").start(); + + + } + + @Test + public void test1_1(){ + test1(); + } + + + + + + +} diff --git a/src/main/java/com/chen/api/util/thread/study/chapter1/daemonThread/MyThread.java b/src/main/java/com/chen/api/util/thread/study/chapter1/daemonThread/MyThread.java index 53566fb..2c107e1 100644 --- a/src/main/java/com/chen/api/util/thread/study/chapter1/daemonThread/MyThread.java +++ b/src/main/java/com/chen/api/util/thread/study/chapter1/daemonThread/MyThread.java @@ -15,7 +15,7 @@ public void run() { while (true) { try { i++; - System.out.println("i=" + i); + System.out.println( Thread.currentThread().getName()+",i=" + i); Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); diff --git a/src/main/java/com/chen/api/util/thread/study/chapter1/daemonThread/MyThread2.java b/src/main/java/com/chen/api/util/thread/study/chapter1/daemonThread/MyThread2.java new file mode 100644 index 0000000..553330c --- /dev/null +++ b/src/main/java/com/chen/api/util/thread/study/chapter1/daemonThread/MyThread2.java @@ -0,0 +1,24 @@ +package com.chen.api.util.thread.study.chapter1.daemonThread; + +/** + * @author : chen weijie + * @Date: 2020-07-10 11:17 + */ +public class MyThread2 { + + public static void main(String[] args) { + + + new Thread(new Runnable() { + @Override + public void run() { + System.out.println(123); + } + },"测试线程").start(); + + + } + + + +} diff --git a/src/main/java/com/chen/api/util/thread/study/chapter1/daemonThread/Test.java b/src/main/java/com/chen/api/util/thread/study/chapter1/daemonThread/Test.java index 6bccefa..26822e3 100644 --- a/src/main/java/com/chen/api/util/thread/study/chapter1/daemonThread/Test.java +++ b/src/main/java/com/chen/api/util/thread/study/chapter1/daemonThread/Test.java @@ -13,16 +13,25 @@ public static void main(String[] args) { try { MyThread myThread = new MyThread(); - myThread.setDaemon(true); - myThread.start(); - Thread.sleep(10000); +// myThread.setDaemon(true); +// myThread.start(); +// +// System.out.println("我离开daemon对象也不在打印了,也就是停止了"); + - System.out.println("我离开daemon对象也不在打印了,也就是停止了"); + // thread传入Mythread对象,因为myThread继承了thread,而thread实现了runnable接口 + Thread thread = new Thread(myThread,"测试传入thread的线程"); + thread.start(); + Thread.sleep(10000); } catch (InterruptedException e) { e.printStackTrace(); } + + + + } } diff --git a/src/main/java/com/chen/api/util/thread/study/chapter1/interruptThread/InterruptThread.java b/src/main/java/com/chen/api/util/thread/study/chapter1/interruptThread/InterruptThread.java index 727b531..9f1ec17 100644 --- a/src/main/java/com/chen/api/util/thread/study/chapter1/interruptThread/InterruptThread.java +++ b/src/main/java/com/chen/api/util/thread/study/chapter1/interruptThread/InterruptThread.java @@ -12,6 +12,10 @@ public class InterruptThread extends Thread { @Override public void run() { for (int i = 0; i < 5000000; i++) { + + if (Thread.currentThread().isInterrupted()) { + return; + } System.out.println("i====" + i); } diff --git a/src/main/java/com/chen/api/util/thread/study/chapter1/notShareVariable/MyThread.java b/src/main/java/com/chen/api/util/thread/study/chapter1/notShareVariable/MyThread.java index c5c3692..1dfd4e5 100644 --- a/src/main/java/com/chen/api/util/thread/study/chapter1/notShareVariable/MyThread.java +++ b/src/main/java/com/chen/api/util/thread/study/chapter1/notShareVariable/MyThread.java @@ -18,8 +18,7 @@ public MyThread(String name) { @Override public void run() { super.run(); - while (i > 0) { - i--; + while (i-- > 0) { System.out.println(Thread.currentThread().getName() + "计算count==" + i); } diff --git a/src/main/java/com/chen/api/util/thread/study/chapter1/threadTest/MyThread.java b/src/main/java/com/chen/api/util/thread/study/chapter1/threadTest/MyThread.java index 32feea0..b9af95c 100644 --- a/src/main/java/com/chen/api/util/thread/study/chapter1/threadTest/MyThread.java +++ b/src/main/java/com/chen/api/util/thread/study/chapter1/threadTest/MyThread.java @@ -8,10 +8,16 @@ */ public class MyThread extends Thread { + private int i = 10; @Override public void run() { - Thread.currentThread().setName("MyThread线程.."); - System.out.println(Thread.currentThread().getName() + "正在运行.."); + i--; + try { + Thread.sleep(1); + } catch (InterruptedException e) { + e.printStackTrace(); + } + System.out.println(Thread.currentThread().getName() + "正在运行..i = "+i); } } diff --git a/src/main/java/com/chen/api/util/thread/study/chapter1/threadTest/MyThreadTest.java b/src/main/java/com/chen/api/util/thread/study/chapter1/threadTest/MyThreadTest.java index d4ee746..a09a815 100644 --- a/src/main/java/com/chen/api/util/thread/study/chapter1/threadTest/MyThreadTest.java +++ b/src/main/java/com/chen/api/util/thread/study/chapter1/threadTest/MyThreadTest.java @@ -11,7 +11,12 @@ public class MyThreadTest { public static void main(String[] args) { MyThread myThread = new MyThread(); - myThread.start(); + + for (int i = 0; i < 10; i++) { + Thread thread = new Thread(myThread,"线程"+(10-i)); + thread.start(); + } + System.out.println("运行结束!"); } diff --git a/src/main/java/com/chen/api/util/thread/study/chapter3/join_interrupt/Test.java b/src/main/java/com/chen/api/util/thread/study/chapter3/join_interrupt/Test.java index 7be8158..ba2fa4a 100644 --- a/src/main/java/com/chen/api/util/thread/study/chapter3/join_interrupt/Test.java +++ b/src/main/java/com/chen/api/util/thread/study/chapter3/join_interrupt/Test.java @@ -11,7 +11,7 @@ public static void main(String[] args) { try { ThreadB threadB = new ThreadB(); threadB.start(); - Thread.sleep(10); + Thread.sleep(100); ThreadC threadC = new ThreadC(threadB); threadC.start(); } catch (Exception e) { diff --git a/src/main/java/com/chen/api/util/thread/study/chapter3/join_interrupt/ThreadA.java b/src/main/java/com/chen/api/util/thread/study/chapter3/join_interrupt/ThreadA.java index 19cc393..ed698f0 100644 --- a/src/main/java/com/chen/api/util/thread/study/chapter3/join_interrupt/ThreadA.java +++ b/src/main/java/com/chen/api/util/thread/study/chapter3/join_interrupt/ThreadA.java @@ -10,6 +10,11 @@ public class ThreadA extends Thread { public void run() { for (int i = 0; i < 10000; i++) { String a = new String("a"); + try { + Thread.sleep(100); + } catch (InterruptedException e) { + e.printStackTrace(); + } System.out.println("ThreadA test....."); } diff --git a/src/main/java/com/chen/api/util/thread/study/chapter3/test4/MyThread.java b/src/main/java/com/chen/api/util/thread/study/chapter3/test4/MyThread.java new file mode 100644 index 0000000..a1ecc99 --- /dev/null +++ b/src/main/java/com/chen/api/util/thread/study/chapter3/test4/MyThread.java @@ -0,0 +1,71 @@ +package com.chen.api.util.thread.study.chapter3.test4; + +/** + * @author : chen weijie + * @Date: 2020-07-11 18:11 + */ +public class MyThread { + + + + + + + public static void main(String[] args) { + + Object lock = new Object(); + + new Thread(new Runnable() { + @Override + public void run() { + synchronized (lock){ + for (int i = 0; i < 1000; i++) { + if (i % 2 == 0) { + System.out.println(Thread.currentThread().getName() + ",i=" + i); + } + try { + lock.wait(); + lock.notify(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + } + } + },"thread-A").start(); + + new Thread(new Runnable() { + @Override + public void run() { + synchronized (lock){ + for (int i = 0; i < 1000; i++) { + if (i % 2 != 0) { + System.out.println(Thread.currentThread().getName() + ",i=" + i); + } + try { + lock.notify(); + lock.wait(); + } catch (Exception e) { + e.printStackTrace(); + } + + } + } + } + },"thread-B").start(); + + + + + } + + + + + + + + + + +} diff --git a/src/main/java/com/chen/api/util/thread/study/chapter3/test4/Service.java b/src/main/java/com/chen/api/util/thread/study/chapter3/test4/Service.java new file mode 100644 index 0000000..29516cd --- /dev/null +++ b/src/main/java/com/chen/api/util/thread/study/chapter3/test4/Service.java @@ -0,0 +1,26 @@ +package com.chen.api.util.thread.study.chapter3.test4; + +/** + * @author : chen weijie + * @Date: 2020-07-11 18:36 + */ +public class Service { + + public void testMethod(Object lock) { + synchronized (lock) { + System.out.println(Thread.currentThread().getName()+",begin...."); + try { +// Thread.sleep(1); + lock.wait(5000); + } catch (InterruptedException e) { + e.printStackTrace(); + } + System.out.println(Thread.currentThread().getName()+",end...."); + + } + + + } + + +} diff --git a/src/main/java/com/chen/api/util/thread/study/chapter3/test4/TestThread.java b/src/main/java/com/chen/api/util/thread/study/chapter3/test4/TestThread.java new file mode 100644 index 0000000..e4701ba --- /dev/null +++ b/src/main/java/com/chen/api/util/thread/study/chapter3/test4/TestThread.java @@ -0,0 +1,23 @@ +package com.chen.api.util.thread.study.chapter3.test4; + +/** + * @author : chen weijie + * @Date: 2020-07-11 18:40 + */ +public class TestThread { + + public static void main(String[] args) { + + Object lock = new Object(); + ThreadA threadA = new ThreadA(lock); + threadA.setName("threadA"); + threadA.start(); + ThreadB threadB = new ThreadB(lock); + threadB.setName("threadB"); + threadB.start(); + + + } + + +} diff --git a/src/main/java/com/chen/api/util/thread/study/chapter3/test4/ThreadA.java b/src/main/java/com/chen/api/util/thread/study/chapter3/test4/ThreadA.java new file mode 100644 index 0000000..069b4b1 --- /dev/null +++ b/src/main/java/com/chen/api/util/thread/study/chapter3/test4/ThreadA.java @@ -0,0 +1,24 @@ +package com.chen.api.util.thread.study.chapter3.test4; + +/** + * @author : chen weijie + * @Date: 2020-07-11 18:34 + */ +public class ThreadA extends Thread { + + + private Object lock; + + public ThreadA(Object lock) { + this.lock = lock; + } + + + @Override + public void run() { + Service service = new Service(); + service.testMethod(lock); + + } + +} diff --git a/src/main/java/com/chen/api/util/thread/study/chapter3/test4/ThreadB.java b/src/main/java/com/chen/api/util/thread/study/chapter3/test4/ThreadB.java new file mode 100644 index 0000000..cbdfa8c --- /dev/null +++ b/src/main/java/com/chen/api/util/thread/study/chapter3/test4/ThreadB.java @@ -0,0 +1,21 @@ +package com.chen.api.util.thread.study.chapter3.test4; + +/** + * @author : chen weijie + * @Date: 2020-07-11 18:34 + */ +public class ThreadB extends Thread { + + private Object lock; + + public ThreadB(Object lock) { + this.lock = lock; + } + + @Override + public void run() { + Service service = new Service(); + service.testMethod(lock); + } + +} diff --git a/src/main/java/com/chen/api/util/thread/study/chapter4/conditionExecute/Run.java b/src/main/java/com/chen/api/util/thread/study/chapter4/conditionExecute/Run.java index 585b78e..b6e9abd 100644 --- a/src/main/java/com/chen/api/util/thread/study/chapter4/conditionExecute/Run.java +++ b/src/main/java/com/chen/api/util/thread/study/chapter4/conditionExecute/Run.java @@ -1,7 +1,5 @@ package com.chen.api.util.thread.study.chapter4.conditionExecute; -import com.chen.api.util.thread.study.chapter2.throwExceptionNoLock.ThreadB; - import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.ReentrantLock; @@ -12,7 +10,7 @@ * @Date: 2018-05-21 01:11 */ public class Run { - volatile private static int nextPrintWho = 1; + private volatile static int nextPrintWho = 1; private static ReentrantLock lock = new ReentrantLock(); final private static Condition conditionA = lock.newCondition(); final private static Condition conditionB = lock.newCondition(); @@ -21,32 +19,28 @@ public class Run { public static void main(String[] args) { - Thread threadA = new Thread() { + Thread threadA = new Thread(() -> { - @Override - public void run() { - - try { - lock.lock(); - while (nextPrintWho != 1) { - conditionA.await(); - } + try { + lock.lock(); + while (nextPrintWho != 1) { + conditionA.await(); + } - for (int i = 0; i < 3; i++) { - System.out.println("threadA:" + (i + 1)); - } + for (int i = 0; i < 3; i++) { + System.out.println("threadA:" + (i + 1)); + } - nextPrintWho = 2; - conditionB.signalAll(); + nextPrintWho = 2; + conditionB.signalAll(); - } catch (InterruptedException e) { - e.printStackTrace(); - } finally { - lock.unlock(); - } + } catch (InterruptedException e) { + e.printStackTrace(); + } finally { + lock.unlock(); } - }; + }); Thread threadB = new Thread() { diff --git a/src/main/java/com/chen/api/util/thread/study/chapter4/readWriteLockBegin1/Run.java b/src/main/java/com/chen/api/util/thread/study/chapter4/readWriteLockBegin1/Run.java index 7723b23..2306543 100644 --- a/src/main/java/com/chen/api/util/thread/study/chapter4/readWriteLockBegin1/Run.java +++ b/src/main/java/com/chen/api/util/thread/study/chapter4/readWriteLockBegin1/Run.java @@ -17,13 +17,14 @@ public void run() { }; - Thread threadA = new Thread(runnable); - threadA.setName("a"); - threadA.start(); - - Thread threadB = new Thread(runnable); - threadB.setName("b"); - threadB.start(); + for (int i = 0; i < 10; i++) { + Thread threadA = new Thread(runnable); + threadA.setName("a." + i); + threadA.start(); + Thread threadB = new Thread(runnable); + threadB.setName("b." + i); + threadB.start(); + } } diff --git a/src/main/java/com/chen/api/util/thread/study/chapter4/readWriteLockBegin2/Run.java b/src/main/java/com/chen/api/util/thread/study/chapter4/readWriteLockBegin2/Run.java index 81b679e..e677e72 100644 --- a/src/main/java/com/chen/api/util/thread/study/chapter4/readWriteLockBegin2/Run.java +++ b/src/main/java/com/chen/api/util/thread/study/chapter4/readWriteLockBegin2/Run.java @@ -18,13 +18,17 @@ public void run() { }; - Thread threadA = new Thread(runnable); - threadA.setName("a"); - threadA.start(); + for (int i = 0; i < 10; i++) { + Thread threadA = new Thread(runnable); + threadA.setName("a." + i); + threadA.start(); + Thread threadB = new Thread(runnable); + threadB.setName("b." + i); + threadB.start(); + } + + - Thread threadB = new Thread(runnable); - threadB.setName("b"); - threadB.start(); } diff --git a/src/main/java/com/chen/api/util/thread/study/chapter4/readWriteLockBegin2/Service.java b/src/main/java/com/chen/api/util/thread/study/chapter4/readWriteLockBegin2/Service.java index 96b3f87..f20c0fe 100644 --- a/src/main/java/com/chen/api/util/thread/study/chapter4/readWriteLockBegin2/Service.java +++ b/src/main/java/com/chen/api/util/thread/study/chapter4/readWriteLockBegin2/Service.java @@ -17,7 +17,7 @@ public void write() { try { lock.writeLock().lock(); System.out.println("获得写锁:" + Thread.currentThread().getName() + " " + System.currentTimeMillis()); - Thread.sleep(10000); + Thread.sleep(1000); } finally { lock.writeLock().unlock(); } diff --git a/src/main/java/com/chen/api/util/thread/study/chapter4/readWriteLockBegin3/Run.java b/src/main/java/com/chen/api/util/thread/study/chapter4/readWriteLockBegin3/Run.java index 4362ae2..70b8560 100644 --- a/src/main/java/com/chen/api/util/thread/study/chapter4/readWriteLockBegin3/Run.java +++ b/src/main/java/com/chen/api/util/thread/study/chapter4/readWriteLockBegin3/Run.java @@ -24,11 +24,16 @@ public void run() { } }; - Thread threadA = new Thread(readTask); - threadA.start(); - Thread threadB = new Thread(writeTask); - threadB.start(); + for (int i = 0; i < 10; i++) { + Thread threadA = new Thread(readTask); + threadA.setName("a." + i); + threadA.start(); + Thread threadB = new Thread(writeTask); + threadB.setName("b." + i); + threadB.start(); + } + } diff --git a/src/main/java/com/chen/api/util/thread/study/chapter4/readWriteLockBegin3/Service.java b/src/main/java/com/chen/api/util/thread/study/chapter4/readWriteLockBegin3/Service.java index 3252223..2c99c6e 100644 --- a/src/main/java/com/chen/api/util/thread/study/chapter4/readWriteLockBegin3/Service.java +++ b/src/main/java/com/chen/api/util/thread/study/chapter4/readWriteLockBegin3/Service.java @@ -17,7 +17,7 @@ public void read() { try { lock.readLock().lock(); System.out.println("thread:" + Thread.currentThread().getName() + "获得读锁,time==" + System.currentTimeMillis()); - Thread.sleep(10000); + Thread.sleep(2000); } catch (Exception e) { e.printStackTrace(); } finally { @@ -32,7 +32,7 @@ public void write() { try { lock.writeLock().lock(); System.out.println("thread:" + Thread.currentThread().getName() + "获得写锁,time==" + System.currentTimeMillis()); - Thread.sleep(10000); + Thread.sleep(2000); } catch (Exception e) { e.printStackTrace(); } finally { diff --git a/src/main/java/com/chen/api/util/thread/threadPool/ScheduledThreadPoolTest.java b/src/main/java/com/chen/api/util/thread/threadPool/ScheduledThreadPoolTest.java new file mode 100644 index 0000000..5f371c5 --- /dev/null +++ b/src/main/java/com/chen/api/util/thread/threadPool/ScheduledThreadPoolTest.java @@ -0,0 +1,22 @@ +package com.chen.api.util.thread.threadPool; + +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; + +/** + * @author : chen weijie + * @Date: 2019-10-22 23:27 + */ +public class ScheduledThreadPoolTest { + + + public static void main(String[] args) { + + ScheduledExecutorService pool = Executors.newScheduledThreadPool(10); + + pool.scheduleAtFixedRate((Runnable) () -> System.out.println(123), 1, 5, TimeUnit.SECONDS); + + } + +} diff --git a/src/main/java/com/chen/dataStructure/self/bitmap/BitMap.java b/src/main/java/com/chen/dataStructure/self/bitmap/BitMap.java new file mode 100644 index 0000000..c6bf37c --- /dev/null +++ b/src/main/java/com/chen/dataStructure/self/bitmap/BitMap.java @@ -0,0 +1,49 @@ +package com.chen.dataStructure.self.bitmap; + +/** + * @author : chen weijie + * @Date: 2020-05-01 10:44 + */ +public class BitMap { + + private char[] bytes; + private int nbits; + + public BitMap(int nbits) { + this.nbits = nbits; + this.bytes = new char[nbits / 8 + 1]; + } + + public void set(int k) { + + if (k > nbits) { + return; + } + int byteIndex = k / 8; + int bitIndex = k % 8; + bytes[byteIndex] |= (1 << bitIndex); + } + + public boolean get(int k) { + if (k > nbits) { + return false; + } + int byteIndex = k / 8; + int bitIndex = k % 8; + return (bytes[byteIndex] & (1 << bitIndex)) != 0; + } + + public static void main(String[] args) { + + BitMap bitMap = new BitMap(16); + + bitMap.set(12); + System.out.println(bitMap.get(12)); + + + + } + + + +} diff --git a/src/main/java/com/chen/dataStructure/self/stack/ArrayStack2.java b/src/main/java/com/chen/dataStructure/self/stack/ArrayStack2.java new file mode 100644 index 0000000..bc57eb0 --- /dev/null +++ b/src/main/java/com/chen/dataStructure/self/stack/ArrayStack2.java @@ -0,0 +1,36 @@ +package com.chen.dataStructure.self.stack; + +/** + * @author Chen WeiJie + * @date 2020-03-30 11:02:05 + **/ +public class ArrayStack2 { + + + private int[] elements; + + private int capacity; + + private int size; + + + public ArrayStack2(int n) { + + this.elements = new int[n]; + this.capacity = n; + this.size = 0; + } + + + public void push(int element) { + elements[++size] = element; + } + + + public int pop() { + int element = elements[--size]; + return element; + } + + +} diff --git a/src/main/java/com/chen/dataStructure/study/queen/priorityQueue/MaxHeap.java b/src/main/java/com/chen/dataStructure/study/queen/priorityQueue/MaxHeap.java new file mode 100644 index 0000000..6328838 --- /dev/null +++ b/src/main/java/com/chen/dataStructure/study/queen/priorityQueue/MaxHeap.java @@ -0,0 +1,42 @@ +package com.chen.dataStructure.study.queen.priorityQueue; + +import java.util.Comparator; +import java.util.PriorityQueue; + +/** + * PriorityQueue 默认实现的是小顶堆,如果传入comparator参数定义排序,则可以实现大顶堆。 + * + * @author : chen weijie + * @Date: 2020-08-30 01:23 + */ +public class MaxHeap { + + private int size; + + public PriorityQueue queue = new PriorityQueue<>(size, new Comparator() { + @Override + public int compare(Integer o1, Integer o2) { + return o2 - o1; + } + }); + + public MaxHeap(int size, int[] nums) { + this.size = size; + for (int n : nums) { + add(n); + } + } + + + private Integer add(int val) { + + if (queue.size() < size) { + queue.offer(val); + } else if (queue.peek() != null && queue.peek() > val) { + queue.poll(); + queue.offer(val); + } + return queue.peek(); + } + +} diff --git a/src/main/java/com/chen/designPattern/abstractFactory/Test.java b/src/main/java/com/chen/designPattern/abstractFactory/Test.java index 85d0c32..6b9e9e4 100644 --- a/src/main/java/com/chen/designPattern/abstractFactory/Test.java +++ b/src/main/java/com/chen/designPattern/abstractFactory/Test.java @@ -1,6 +1,10 @@ package com.chen.designPattern.abstractFactory; -/** 抽象工厂类 +/** + * 抽象工厂类 https://blog.csdn.net/jason0539/article/details/44976775 + * + * 抽象工厂和工厂方法模式 https://blog.csdn.net/Olive_ZT/article/details/78861388 + * * @Author chenweijie * @Date 2017/8/27 2:27 */ @@ -8,11 +12,11 @@ public class Test { public static void main(String[] args) { - FactoryBMW bmw320 =new BMW320(); + FactoryBMW bmw320 = new BMW320(); bmw320.getContainer(); bmw320.getEngine(); - FactoryBMW bmw520 =new BMW520(); + FactoryBMW bmw520 = new BMW520(); bmw520.getContainer(); bmw520.getEngine(); diff --git a/src/main/java/com/chen/designPattern/adapter/Adaptee.java b/src/main/java/com/chen/designPattern/adapter/Adaptee.java deleted file mode 100644 index 7d84329..0000000 --- a/src/main/java/com/chen/designPattern/adapter/Adaptee.java +++ /dev/null @@ -1,15 +0,0 @@ -package com.chen.designPattern.adapter; - -/** - * 适配者 - * 需要适配的类。 - * @Author chenweijie - * @Date 2017/8/27 3:00 - */ -public class Adaptee { - - public void specificRequest(){ - - System.out.println("特殊的请求!"); - } -} diff --git a/src/main/java/com/chen/designPattern/adapter/Adapter.java b/src/main/java/com/chen/designPattern/adapter/Adapter.java index 7c67508..ee5f09b 100644 --- a/src/main/java/com/chen/designPattern/adapter/Adapter.java +++ b/src/main/java/com/chen/designPattern/adapter/Adapter.java @@ -1,22 +1,13 @@ package com.chen.designPattern.adapter; /** - * 适配器 (http://alexpdh.com/2017/06/24/adapter-pattern/) - * 通过在内部包装一个适配者对象,把源接口转换成目标接口。 - * - * @Author chenweijie - * @Date 2017/8/27 3:01 + * @author : chen weijie + * @Date: 2020-04-21 01:42 */ -public class Adapter implements Target { - - private Adaptee adaptee; - +public class Adapter extends SpecialMethod implements StardMethod { @Override public void request() { - adaptee = new Adaptee(); - adaptee.specificRequest(); - + super.printSpecial(); } - } diff --git a/src/main/java/com/chen/designPattern/adapter/Client.java b/src/main/java/com/chen/designPattern/adapter/Client.java new file mode 100644 index 0000000..a1555ba --- /dev/null +++ b/src/main/java/com/chen/designPattern/adapter/Client.java @@ -0,0 +1,16 @@ +package com.chen.designPattern.adapter; + +/** + * https://blog.csdn.net/jason0539/article/details/22468457 + * @author : chen weijie + * @Date: 2020-04-21 01:43 + */ +public class Client { + + public static void main(String[] args) { + + StardMethod stardMethod = new Adapter(); + stardMethod.request(); + + } +} diff --git a/src/main/java/com/chen/designPattern/adapter/SpecialMethod.java b/src/main/java/com/chen/designPattern/adapter/SpecialMethod.java new file mode 100644 index 0000000..de696b3 --- /dev/null +++ b/src/main/java/com/chen/designPattern/adapter/SpecialMethod.java @@ -0,0 +1,13 @@ +package com.chen.designPattern.adapter; + +/** + * @author : chen weijie + * @Date: 2020-04-21 01:41 + */ +public class SpecialMethod { + + + public void printSpecial(){ + System.out.println("i'm a special method"); + } +} diff --git a/src/main/java/com/chen/designPattern/adapter/StardMethod.java b/src/main/java/com/chen/designPattern/adapter/StardMethod.java new file mode 100644 index 0000000..b02bbfa --- /dev/null +++ b/src/main/java/com/chen/designPattern/adapter/StardMethod.java @@ -0,0 +1,11 @@ +package com.chen.designPattern.adapter; + +/** + * @author : chen weijie + * @Date: 2020-04-21 01:41 + */ +public interface StardMethod { + + + void request(); +} diff --git a/src/main/java/com/chen/designPattern/adapter/Target.java b/src/main/java/com/chen/designPattern/adapter/Target.java deleted file mode 100644 index 85dd2f6..0000000 --- a/src/main/java/com/chen/designPattern/adapter/Target.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.chen.designPattern.adapter; - -/** - * 目标 - * 这是客户所期待的接口。目标可以是具体的或抽象的类,也可以是接口。 - * - * @Author chenweijie - * @Date 2017/8/27 3:00 - */ -public interface Target { - - void request(); -} diff --git a/src/main/java/com/chen/designPattern/adapter/TestMain.java b/src/main/java/com/chen/designPattern/adapter/TestMain.java deleted file mode 100644 index 245839f..0000000 --- a/src/main/java/com/chen/designPattern/adapter/TestMain.java +++ /dev/null @@ -1,18 +0,0 @@ -package com.chen.designPattern.adapter; - -/** - * 测试类 - * - * @Author chenweijie - * @Date 2017/8/27 3:05 - */ -public class TestMain { - - public static void main(String[] args) { - - Target target = new Adapter(); - target.request(); - - } - -} diff --git a/src/main/java/com/chen/designPattern/modelPattern/Station.java b/src/main/java/com/chen/designPattern/modelPattern/Station.java index 287354b..48df5cb 100644 --- a/src/main/java/com/chen/designPattern/modelPattern/Station.java +++ b/src/main/java/com/chen/designPattern/modelPattern/Station.java @@ -1,6 +1,9 @@ package com.chen.designPattern.modelPattern; /**抽象模板 + * + * https://blog.csdn.net/jason0539/article/details/45037535 + * * Created by Chen Weijie on 2017/8/17. */ public abstract class Station { diff --git a/src/main/java/com/chen/designPattern/normalFactory/ClassForNameFactory.java b/src/main/java/com/chen/designPattern/normalFactory/ClassForNameFactory.java deleted file mode 100644 index f030e77..0000000 --- a/src/main/java/com/chen/designPattern/normalFactory/ClassForNameFactory.java +++ /dev/null @@ -1,22 +0,0 @@ -package com.chen.designPattern.normalFactory; - -/** - * Created by Chen Weijie on 2017/8/5. - */ -public class ClassForNameFactory { - - - public static Sender getInstance(String name){ - - Sender sender =null; - try { - sender=(Sender)Class.forName(name).newInstance(); - } catch (InstantiationException | IllegalAccessException | ClassNotFoundException e) { - e.printStackTrace(); - } - return sender; - - - } - -} diff --git a/src/main/java/com/chen/designPattern/normalFactory/MailSender.java b/src/main/java/com/chen/designPattern/normalFactory/MailSender.java deleted file mode 100644 index d38463b..0000000 --- a/src/main/java/com/chen/designPattern/normalFactory/MailSender.java +++ /dev/null @@ -1,11 +0,0 @@ -package com.chen.designPattern.normalFactory; - -/** 具体产品2 - * Created by chenwj3 on 2017/1/19. - */ -public class MailSender implements Sender { - @Override - public void send() { - System.out.println("this is a mailSender"); - } -} diff --git a/src/main/java/com/chen/designPattern/normalFactory/Main.java b/src/main/java/com/chen/designPattern/normalFactory/Main.java deleted file mode 100644 index 8777cf9..0000000 --- a/src/main/java/com/chen/designPattern/normalFactory/Main.java +++ /dev/null @@ -1,22 +0,0 @@ -package com.chen.designPattern.normalFactory; - -/** - * 客户类 - * Created by chenwj3 on 2017/1/19. - */ -public class Main { - - public static void main(String args[]) { - - SendFactory sendFactory = new SendFactory(); - Sender sender = sendFactory.produce("mail"); - sender.send(); - - Sender sender1 =ClassForNameFactory.getInstance("com.ifeng.chen.designPattern.normalFactory.SmsSender"); - sender1.send(); - - - } - - -} diff --git a/src/main/java/com/chen/designPattern/normalFactory/SendFactory.java b/src/main/java/com/chen/designPattern/normalFactory/SendFactory.java deleted file mode 100644 index afe2ba4..0000000 --- a/src/main/java/com/chen/designPattern/normalFactory/SendFactory.java +++ /dev/null @@ -1,23 +0,0 @@ -package com.chen.designPattern.normalFactory; - -/** - * 简单工厂模式(先创建一个接口 然后创建2个实例,再创建一个工厂类) - * 工厂类 - * Created by chenwj3 on 2017/1/19. - */ -public class SendFactory { - - public Sender produce(String type){ - if ("mail".equals(type)){ - return new MailSender(); - }else if ("sms".equals(type)){ - return new SmsSender(); - }else { - System.out.println("please write write type!"); - return null; - } - } - - - -} diff --git a/src/main/java/com/chen/designPattern/normalFactory/Sender.java b/src/main/java/com/chen/designPattern/normalFactory/Sender.java deleted file mode 100644 index 002d224..0000000 --- a/src/main/java/com/chen/designPattern/normalFactory/Sender.java +++ /dev/null @@ -1,10 +0,0 @@ -package com.chen.designPattern.normalFactory; - -/** - * 抽象产品 - * Created by chenwj3 on 2017/1/19. - */ -public interface Sender { - - void send(); -} diff --git a/src/main/java/com/chen/designPattern/normalFactory/SmsSender.java b/src/main/java/com/chen/designPattern/normalFactory/SmsSender.java deleted file mode 100644 index a51df82..0000000 --- a/src/main/java/com/chen/designPattern/normalFactory/SmsSender.java +++ /dev/null @@ -1,12 +0,0 @@ -package com.chen.designPattern.normalFactory; - -/** - * 具体产品 - * Created by chenwj3 on 2017/1/19. - */ -public class SmsSender implements Sender { - @Override - public void send() { - System.out.println("this is a smsSender"); - } -} diff --git a/src/main/java/com/chen/designPattern/proxy/BuyHouse.java b/src/main/java/com/chen/designPattern/proxy/BuyHouse.java new file mode 100644 index 0000000..65cce48 --- /dev/null +++ b/src/main/java/com/chen/designPattern/proxy/BuyHouse.java @@ -0,0 +1,10 @@ +package com.chen.designPattern.proxy; + +/** + * @author : chen weijie + * @Date: 2020-04-21 02:00 + */ +public interface BuyHouse { + + void buyHouse(); +} diff --git a/src/main/java/com/chen/designPattern/proxy/BuyHouseImpl.java b/src/main/java/com/chen/designPattern/proxy/BuyHouseImpl.java new file mode 100644 index 0000000..3db203d --- /dev/null +++ b/src/main/java/com/chen/designPattern/proxy/BuyHouseImpl.java @@ -0,0 +1,13 @@ +package com.chen.designPattern.proxy; + +/** + * @author : chen weijie + * @Date: 2020-04-21 02:01 + */ +public class BuyHouseImpl implements BuyHouse { + + @Override + public void buyHouse() { + System.out.println("买房"); + } +} diff --git a/src/main/java/com/chen/designPattern/proxy/Proxy.java b/src/main/java/com/chen/designPattern/proxy/Proxy.java index 0c39397..8ae7ee3 100644 --- a/src/main/java/com/chen/designPattern/proxy/Proxy.java +++ b/src/main/java/com/chen/designPattern/proxy/Proxy.java @@ -1,29 +1,23 @@ package com.chen.designPattern.proxy; /** - * 代理模式 (http://www.jianshu.com/p/6f6bb2f0ece9) - * 代理 - * - * @Author chenweijie - * @Date 2017/8/27 3:58 + * @author : chen weijie + * @Date: 2020-04-21 02:01 */ -public class Proxy implements Subject { +public class Proxy implements BuyHouse { - private Subject subject; + private BuyHouse buyHouse; - @Override - public void request() { - System.out.println("PreProcess"); - subject.request(); - System.out.println("PostProcess"); + public Proxy(BuyHouse buyHouse) { + this.buyHouse = buyHouse; } - public Subject getSubject() { - return subject; - } + @Override + public void buyHouse() { + System.out.println("买房前准备"); + buyHouse.buyHouse(); + System.out.println("买房后装修"); - public void setSubject(Subject subject) { - this.subject = subject; } } diff --git a/src/main/java/com/chen/designPattern/proxy/RealSubject.java b/src/main/java/com/chen/designPattern/proxy/RealSubject.java deleted file mode 100644 index a2ec5f1..0000000 --- a/src/main/java/com/chen/designPattern/proxy/RealSubject.java +++ /dev/null @@ -1,14 +0,0 @@ -package com.chen.designPattern.proxy; - -/** - * 是原对象(本文把原对象称为"委托对象") - * @Author chenweijie - * @Date 2017/8/27 4:02 - */ -public class RealSubject implements Subject { - - @Override - public void request() { - System.out.println("我是原对象"); - } -} diff --git a/src/main/java/com/chen/designPattern/proxy/Subject.java b/src/main/java/com/chen/designPattern/proxy/Subject.java deleted file mode 100644 index 29d7317..0000000 --- a/src/main/java/com/chen/designPattern/proxy/Subject.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.chen.designPattern.proxy; - -/** - * 是委托对象和代理对象都共同实现的接口 - * - * @Author chenweijie - * @Date 2017/8/27 4:01 - */ -public interface Subject { - - void request(); - -} diff --git a/src/main/java/com/chen/designPattern/proxy/Test.java b/src/main/java/com/chen/designPattern/proxy/Test.java index 5473d5e..35510fc 100644 --- a/src/main/java/com/chen/designPattern/proxy/Test.java +++ b/src/main/java/com/chen/designPattern/proxy/Test.java @@ -1,21 +1,18 @@ package com.chen.designPattern.proxy; /** - * 测试类 + * https://www.cnblogs.com/daniels/p/8242592.html * - * @Author chenweijie - * @Date 2017/8/27 4:04 + * @author : chen weijie + * @Date: 2020-04-21 02:03 */ public class Test { public static void main(String[] args) { - RealSubject realSubject = new RealSubject(); + Proxy proxy = new Proxy(new BuyHouseImpl()); - Proxy proxy = new Proxy(); - proxy.setSubject(realSubject); - - proxy.request(); + proxy.buyHouse(); } diff --git a/src/main/java/com/chen/designPattern/proxy/dynamicProxy/jdk/Test.java b/src/main/java/com/chen/designPattern/proxy/dynamicProxy/jdk/Test.java index 6cc2441..da3771c 100644 --- a/src/main/java/com/chen/designPattern/proxy/dynamicProxy/jdk/Test.java +++ b/src/main/java/com/chen/designPattern/proxy/dynamicProxy/jdk/Test.java @@ -4,6 +4,8 @@ import java.lang.reflect.Proxy; /** + * https://www.cnblogs.com/daniels/p/8242592.html + * * @author : chen weijie * @Date: 2019-06-07 17:58 */ @@ -21,9 +23,9 @@ public static void main(String[] args) { * 第二个参数:people.getClass().getInterfaces(),这里为代理类提供的接口是真实对象实现的接口,这样代理对象就能像真实对象一样调用接口中的所有方法 * 第三个参数:handler,我们将代理对象关联到上面的InvocationHandler对象上 */ - People proxy = (People) Proxy.newProxyInstance(people.getClass().getClassLoader(), people.getClass().getInterfaces(), workHandler); + People peopleProxy = (People) Proxy.newProxyInstance(people.getClass().getClassLoader(), people.getClass().getInterfaces(), workHandler); // System.out.println(proxy.toString()); - System.out.println(proxy.work()); + System.out.println(peopleProxy.work()); } } diff --git a/src/main/java/com/chen/designPattern/singleton/Singleton4.java b/src/main/java/com/chen/designPattern/singleton/Singleton4.java new file mode 100644 index 0000000..f659b3e --- /dev/null +++ b/src/main/java/com/chen/designPattern/singleton/Singleton4.java @@ -0,0 +1,33 @@ +package com.chen.designPattern.singleton; + +/** + * @author : chen weijie + * @Date: 2019-11-11 14:14 + */ +public class Singleton4 { + + private Singleton4(){} + + private volatile static Singleton4 singleton4; + + + public static Singleton4 getGetInstance() { + + if (singleton4 == null) { + + synchronized (Singleton4.class) { + if (singleton4 == null) { + singleton4 = new Singleton4(); + } + } + } + return singleton4; + } + + + + + + + +} diff --git "a/src/main/java/com/chen/java/\347\237\245\350\257\206\347\202\271\346\200\273\347\273\223.md" "b/src/main/java/com/chen/java/\347\237\245\350\257\206\347\202\271\346\200\273\347\273\223.md" new file mode 100644 index 0000000..65da506 --- /dev/null +++ "b/src/main/java/com/chen/java/\347\237\245\350\257\206\347\202\271\346\200\273\347\273\223.md" @@ -0,0 +1,349 @@ + +# 知识点 + +## java基础 + + +[java基础视频](https://pan.baidu.com/s/18pp6g1xKVGCfUATf_nMrOA) pass:5i58 + +### NIO与IO + +[NIO与IO的区别](http://blog.csdn.net/shimiso/article/details/24990499) + +### java泛型 + +[java泛型总结](https://www.cnblogs.com/coprince/p/8603492.html) + +### 多线程 + +- 并发包-详见pictures的ExcutorsService.pnge +- [多线程1]( http://www.cnblogs.com/xrq730/p/5060921.html) +- [多线程2](http://www.infoq.com/cn/articles/java-se-16-synchronized) +- [多线程3](http://www.cnblogs.com/moonandstar08/p/4973079.html) +- [线程各个状态以及转化](https://www.cnblogs.com/jijijiefang/articles/7222955.html) +- 多线程的创建方法 +- 线程池相关 +- [线程和进程的区别](https://www.zhihu.com/question/21535820) +- [线程同步的方法](https://github.com/Mr-YangCheng/ForAndroidInterview/blob/master/java/%5BJava%5D%20%E7%BA%BF%E7%A8%8B%E5%90%8C%E6%AD%A5%E7%9A%84%E6%96%B9%E6%B3%95%EF%BC%9Asychronized%E3%80%81lock%E3%80%81reentrantLock%E5%88%86%E6%9E%90.md) +- [Java并发包基石-AQS详解](https://www.cnblogs.com/chengxiao/archive/2017/07/24/7141160.html) +- [Java并发之AQS详解](https://www.cnblogs.com/waterystone/p/4920797.html) +- [AQS 原理以及 AQS 同步组件总结](https://mp.weixin.qq.com/s?__biz=Mzg2OTA0Njk0OA==&mid=2247484832&idx=1&sn=f902febd050eac59d67fc0804d7e1ad5&source=41#wechat_redirect) +- [CountDownLatch实现原理](https://blog.csdn.net/u014653197/article/details/78217571) +- [AbstractQueuedSynchronizer的介绍和原理分析](http://ifeve.com/introduce-abstractqueuedsynchronizer/) +- [线程问题汇总](http://www.importnew.com/12773.html) + +- 多线程常见的问题 +```` +①悲观锁和乐观锁(具体可以看我的这篇文章:面试必备之乐观锁与悲观锁)、 +②synchronized和lock区别以及volatile和synchronized的区别, +③可重入锁与非可重入锁的区别、 +④多线程是解决什么问题的、 +⑤线程池解决什么问题、 +⑥线程池的原理、 +⑦线程池使用时的注意事项、 +⑧AQS原理、 +⑨ReentranLock源码,设计原理,整体过程等等问题。 +```` + +- AQS的工具 + +1. Semaphore(信号量)-允许多个线程同时访问: synchronized 和 ReentrantLock 都是一次只允许一个线程访问某个资源,Semaphore(信号量)可以指定多个线程同时访问某个资源。 + +2. CountDownLatch (倒计时器):CountDownLatch是一个同步工具类,用来协调多个线程之间的同步。这个工具通常用来控制线程等待,它可以让某一个线程等待直到倒计时结束,再开始执行。 +3. CyclicBarrier(循环栅栏): CyclicBarrier 和 CountDownLatch非常类似,它也可以实现线程间的技术等待,但是它的功能比 CountDownLatch 更加复杂和强大。主要应用场景和 CountDownLatch 类似。CyclicBarrier的字面意思是可循环使用(Cyclic)的屏障(Barrier)。它要做的事情是,让一组线程到达一个屏障(也可以叫同步点)时被阻塞,直到最后一个线程到达屏障时,屏障才会开门,所有被屏障拦截的线程才会继续干活。CyclicBarrier默认的构造方法是 CyclicBarrier(int parties),其参数表示屏障拦截的线程数量,每个线程调用await方法告诉 CyclicBarrier 我已经到达了屏障,然后当前线程被阻塞 + +### java 内存模型 + +#### 重排序 + +具体的编译器实现可以产生任意它喜欢的代码 -- 只要所有执行这些代码产生的结果,能够和内存模型预测的结果保持一致 + +- 编译器生成指令的次序,可以不同于源代码; +- 处理器可以乱序或者并行的执行指令; +- 缓存会改变写入提交主内存的变量的次序; + +#### 内存可见性 + +由于现代可共享内存的多处理器架构可能导致一个线程无法马上(甚至永远)看到另一个线程操作产生的结果。所以 Java 内存模型规定了 JVM 的一种最小保证:什么时候写入一个变量对其他线程可见。 + +在现代可共享内存的多处理器体系结构中每个处理器都有自己的缓存,并周期性的与主内存协调一致。假设线程 A 写入一个变量值 V,随后另一个线程 B 读取变量 V 的值,在下列情况下,线程 B 读取的值可能不是线程 A 写入的最新值: + +- 执行线程 A 的处理器把变量 V 缓存到寄存器中。 +- 执行线程 A 的处理器把变量 V 缓存到自己的缓存中,但还没有同步刷新到主内存中去。 +- 执行线程 B 的处理器的缓存中有变量 V 的旧值。 + + +#### Happens-before 关系 + +happens-before 关系保证:如果线程 A 与线程 B 满足 happens-before 关系,则线程 A 执行动作的结果对于线程 B 是可见的。如果两个操作未按 happens-before 排序,JVM 将可以对他们任意重排序。 + +- 程序次序法则:如果在程序中,所有动作 A 出现在动作 B 之前,则线程中的每动作 A 都 happens-before 于该线程中的每一个动作 B。 +- 监视器锁法则:对一个监视器的解锁 happens-before 于每个后续对同一监视器的加锁。 +- Volatile 变量法则:对 Volatile 域的写入操作 happens-before 于每个后续对同一 Volatile 的读操作。 +- 传递性:如果 A happens-before 于 B,且 B happens-before C,则 A happens-before C。 + + + +### 锁机制 +- [锁的种类和概念](http://www.importnew.com/19472.html) +- [synchronized reentrantlock区别 和应用场景](http://blog.csdn.net/everlasting_188/article/details/51038557) +- **死锁的必要条件** +``` +1.互斥 至少有一个资源处于非共享状态 +2.占有并等待 +3.非抢占 +4.循环等待 + +解决死锁:第一个是死锁预防,就是不让上面的四个条件同时成立。二是,合理分配资源。 + +``` + + +### java的集合数据结构 + +- [hashMap的源码解析1.7](https://www.cnblogs.com/peizhe123/p/5790252.html) +- [hashMap的源码解析1.8](https://zhuanlan.zhihu.com/p/21673805) +- Arraylist的源码解析 +- [Vector和ArrayList的区别](https://www.cnblogs.com/wanlipeng/archive/2010/10/21/1857791.html) +- [concurrentHashMap]( https://www.ibm.com/developerworks/cn/java/java-lo-concurrenthashmap/index.html) +- [concurrentHashMap-1.8](https://www.cnblogs.com/yangming1996/p/8031199.html) +- [java的队列-queue](https://blog.csdn.net/qq_33524158/article/details/78578370) +- [set集合使用](https://www.jianshu.com/p/b48c47a42916) +- [java集合使用及源码](https://www.jianshu.com/u/c98c50394601) + + +### jdk8的新特性 + +- [jdk8的新特性](http://www.jianshu.com/p/5b800057f2d8) +- 兰姆达表达式 +- 函数式接口 (functionalInterface注解 要求只有一个抽象方法) +- 接口的默认方法和静态方法 +- 集合之流式操作 + + +### JVM + +- [jvm的总结](http://www.jianshu.com/p/54eb60cfa7bd) +- [类加载的过程](http://blog.csdn.net/shuangyue/article/details/9262791) +- [垃圾回收机制垃圾回收机制](http://www.cnblogs.com/redcreen/archive/2011/05/04/2037057.html) +- java内存模型 +- [虚拟机参数](http://www.cnblogs.com/redcreen/archive/2011/05/04/2037057.html) + + +### 动态代理 + +- [JDK动态代理和CGLIB代理的区别](https://www.cnblogs.com/bigmonkeys/p/7823268.html) +- [JDK和CGLIB生成动态代理类的区别以及Spring动态代理机制](https://www.jianshu.com/p/abb674bb418c) +- [CGLIB动态代理实现原理](https://blog.csdn.net/yhl_jxy/article/details/80633194) +- [Java动态代理InvocationHandler](https://blog.csdn.net/yaomingyang/article/details/80981004) + + + + + + + +## 设计模式 + +### 设计模式 +- 单例模式(2种模式以及调优) +- 静态工厂模式 +- 工厂方法模式 +- 策略模式 +- 代理模式 +- 模板方法模式 +- 适配器模式 + + +## 框架技术 + + + +### mybatis + +- [常见问题](http://www.cnblogs.com/huajiezh/p/6415388.html) + +### springboot + +[常用注解](https://blog.csdn.net/lafengwnagzi/article/details/53034369) + +### springcloud + +### spring +- [Spring问答](http://www.importnew.com/15851.html) +- [Spring问答2](http://blog.csdn.net/qq1137623160/article/details/71194429) +- [bean的生命周期](http://www.jianshu.com/p/3944792a5fff) + + +### springMVC + +- [springmvc的原理流程](https://www.cnblogs.com/wang-meng/p/5701987.html) + +### springAOP + +- [aop详解](http://www.cnblogs.com/hongwz/p/5764917.html) +- [spring aop实战](https://juejin.im/post/5a55af9e518825734d14813f) + +### springIOC +- [ioc简介](http://www.cnblogs.com/xrq730/p/4919025.html) +- [ioc的源码解析](https://javadoop.com/post/spring-ioc) + +### vert相关 +- [简介](http://www.importnew.com/23334.html) + + + + +## 数据库 + +### mongodb + +- [简介](https://my.oschina.net/340StarObserver/blog/735267) +- [简介2](http://www.jianshu.com/p/b77a33fbe824 ) + +- 性能调优 +- 服务器部署 +- 索引的实现 + +### mysql +- [数据库事务的四大特性以及事务的隔离级别](https://www.cnblogs.com/fjdingsd/p/5273008.html) +- [MySQL数据库优化总结](https://www.cnblogs.com/villion/archive/2009/07/23/1893765.html) +- [mysql常见优化](https://www.cnblogs.com/ggjucheng/archive/2012/11/07/2758058.html) +- [MySQL存储引擎--MyISAM与InnoDB区别](https://blog.csdn.net/xifeijian/article/details/20316775) +- [数据库的三范式](https://blog.csdn.net/sinat_35512245/article/details/52923516) + + +## 网络 + +### http相关 + +- [整个流程](http://m.mamicode.com/info-detail-1357508.html) +- [三次握手四次挥手](https://github.com/jawil/blog/issues/14) +- TCP和UDP的区别 +- 七层模型 +- [HTTP与HTTPS的区别](http://www.mahaixiang.cn/internet/1233.html) +- [从输入URL到页面加载发生了什么](https://segmentfault.com/a/1190000006879700) + + + +## 数据结构 + +### 数据结构 + + +- [常见树的简介](https://www.jianshu.com/p/4c2d8e6b0215) +- [二叉查找树和平衡二叉树](https://www.jianshu.com/p/857f809b0ea8) +- 红黑树 +- [b+数](https://ivanzz1001.github.io/records/post/data-structure/2018/06/16/ds-bplustree) +- [链表相关](http://www.cnblogs.com/xrq730/p/4919025.html) +- [合并数组](http://www.cnblogs.com/A_ming/archive/2010/04/15/1712313.html) +- [一致性hash](https://www.jianshu.com/p/b398250d661a) + + + +## 算法 +### 算法 + +- [动画的形式呈现解LeetCode题目的思路](https://github.com/MisterBooo/LeetCodeAnimation) +- [刷算法](https://www.weiweiblog.cn/jzoffer_java/) +- [排序的时间复杂度](http://www.cnblogs.com/nannanITeye/archive/2013/04/11/3013737.html) +- 冒泡排序 +- 快速排序 +- 二分查找 +- 全排列 + + +## 中间件 + +### sharding-jdbc + +- [spring整合sharding-jdbc使用实例](https://www.cnblogs.com/zwt1990/p/6762135.html) +- [springboot整合sharding-jdbc使用实例](https://blog.csdn.net/mingpingyao/article/details/94701585) +- [sharding-jdbc概述](https://www.cnblogs.com/duanxz/p/3467106.html) + + + +### es +- [es简介](http://lxwei.github.io/posts/Elasticsearch-%E7%AE%80%E4%BB%8B.html) +- [es](http://www.jianshu.com/p/492d4311ed04) +- 基本概念和优势 +- [es基本原理和倒排索引](https://github.com/doocs/advanced-java/blob/master/docs/high-concurrency/es-write-query-search.md) + + + +### redis + +- [简介](https://github.com/chenwj1103/fhhDoc/tree/master/redis、http://blog.csdn.net/qq1137623160/article/details/71246011) +- [redis的过期键的实现](http://blog.csdn.net/xiangnan129/article/details/54928672) +- value类型介绍 +- 内存优化策略 +- 集群配置(哨兵模式 cluster模式 单点模式 3.2.4) +- 性能调优 +- 键删除策略 +- 持久化(RDB AOF) +- 服务器数据结构 +- 选举策略 + +### kafka + +- [入门](http://blog.csdn.net/hmsiwtv/article/details/46960053) + + +### thrift和dubbo +- [thrift简介](https://www.cnblogs.com/chenny7/p/4224720.html) + +- dubbo + + + + + +### nginx +- 基本概念 +- [Nginx请求反向代理](http://www.jianshu.com/p/bed000e1830b) + +### zookeeper +- [zookeeper合集](https://www.cnblogs.com/leeSmall/p/9563547.html) +- [zookeeper简介](https://www.cnblogs.com/wangyayun/p/6811734.html) +- [zookeeper集群搭建](https://www.cnblogs.com/wuxl360/p/5817489.html) +- [zookeeper实现分布式锁](https://www.cnblogs.com/liuyang0/p/6800538.html) +- [zookeeper实现分布式配置文件](https://www.cnblogs.com/leeSmall/p/9614601.html) + + +## linux服务器 + +### linux命令 + +- [linux常用命令](https://blog.52itstyle.com/archives/166/) +- 查看负载 + + +## 云技术 +- docker +- k8s + + +## 操作系统 + +- [操作系统的进程调度算法](https://blog.csdn.net/u011080472/article/details/51217754) +- [计算机系统的层次存储结构详解](https://blog.csdn.net/sinat_35512245/article/details/54746315) +- + + +## 其它 + +- jekins +- jmeter +- + + + + + +## 项目经验类 + + +### 项目描述 +- fhh自媒体平台 +- fhh-service项目 +- kafka流平台 diff --git a/src/main/java/com/chen/spring/bean/AcPersonServiceTest.java b/src/main/java/com/chen/spring/bean/AcPersonServiceTest.java new file mode 100644 index 0000000..a14ef4a --- /dev/null +++ b/src/main/java/com/chen/spring/bean/AcPersonServiceTest.java @@ -0,0 +1,25 @@ +package com.chen.spring.bean; + +import org.springframework.context.ApplicationContext; +import org.springframework.context.support.ClassPathXmlApplicationContext; + +/** + * @author : chen weijie + * @Date: 2020-06-08 17:44 + */ +public class AcPersonServiceTest { + + public static void main(String[] args) { + + System.out.println("开始初始化容器"); + ApplicationContext ac = new ClassPathXmlApplicationContext("application.xml"); + System.out.println("xml加载完毕"); + Person person1 = (Person) ac.getBean("person1"); + System.out.println(person1); + System.out.println("关闭容器"); + ((ClassPathXmlApplicationContext) ac).close(); + + + } + +} diff --git a/src/main/java/com/chen/spring/bean/MyBeanPostProcessor.java b/src/main/java/com/chen/spring/bean/MyBeanPostProcessor.java new file mode 100644 index 0000000..71640e5 --- /dev/null +++ b/src/main/java/com/chen/spring/bean/MyBeanPostProcessor.java @@ -0,0 +1,23 @@ +package com.chen.spring.bean; + +import org.springframework.beans.BeansException; +import org.springframework.beans.factory.config.BeanPostProcessor; + +/** + * @author : chen weijie + * @Date: 2020-06-08 17:42 + */ +public class MyBeanPostProcessor implements BeanPostProcessor { + + @Override + public Object postProcessBeforeInitialization(Object o, String s) throws BeansException { + System.out.println("postProcessBeforeInitialization被调用"); + return o; + } + + @Override + public Object postProcessAfterInitialization(Object o, String s) throws BeansException { + System.out.println("postProcessAfterInitialization被调用"); + return o; + } +} diff --git a/src/main/java/com/chen/spring/bean/Person.java b/src/main/java/com/chen/spring/bean/Person.java new file mode 100644 index 0000000..cfd85e8 --- /dev/null +++ b/src/main/java/com/chen/spring/bean/Person.java @@ -0,0 +1,71 @@ +package com.chen.spring.bean; + +import org.springframework.beans.BeansException; +import org.springframework.beans.factory.*; +import org.springframework.context.ApplicationContext; +import org.springframework.context.ApplicationContextAware; + +/** + * @author : chen weijie + * @Date: 2020-06-08 17:37 + */ +public class Person implements BeanNameAware, BeanFactoryAware, ApplicationContextAware, InitializingBean, DisposableBean { + + + private String name; + + public Person() { + System.out.println("Person类构造方法"); + } + + @Override + public void setBeanName(String s) { + // TODO Auto-generated method stub + System.out.println("setBeanName被调用,beanName:" + s); + } + + /** + * 自定义的初始化函数 + */ + public void myInit() { + System.out.println("myInit被调用"); + } + + /** + * 自定义的销毁方法 + */ + public void myDestroy() { + System.out.println("myDestroy被调用"); + } + + @Override + public void setBeanFactory(BeanFactory beanFactory) throws BeansException { + System.out.println("setBeanFactory被调用,beanFactory"); + } + + @Override + public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { + System.out.println("setApplicationContext被调用"); + } + + @Override + public void afterPropertiesSet() throws Exception { + // TODO Auto-generated method stub + System.out.println("afterPropertiesSet被调用"); + } + + @Override + public void destroy() throws Exception { + // TODO Auto-generated method stub + System.out.println("destory被调用"); + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + System.out.println("set方法被调用"); + } +} diff --git a/src/main/java/com/chen/util/GuavaCacheServie.java b/src/main/java/com/chen/util/GuavaCacheServie.java new file mode 100644 index 0000000..4ffad62 --- /dev/null +++ b/src/main/java/com/chen/util/GuavaCacheServie.java @@ -0,0 +1,104 @@ +package com.chen.util; + +import com.google.common.cache.CacheBuilder; +import com.google.common.cache.CacheLoader; +import com.google.common.cache.LoadingCache; +import org.junit.Test; + +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.Random; +import java.util.concurrent.TimeUnit; + +/** + * @author : chen weijie + * @Date: 2020-08-01 11:19 + */ +public class GuavaCacheServie { + + + LoadingCache cache = CacheBuilder.newBuilder() + //设置并发级别为8,并发级别是指可以同时写缓存的线程数 + .concurrencyLevel(8) + //设置缓存容器的初始容量为10 + .initialCapacity(10) + //设置缓存最大容量为100,超过100之后就会按照LRU最近虽少使用算法来移除缓存项 + .maximumSize(100) + //是否需要统计缓存情况,该操作消耗一定的性能,生产环境应该去除 + .recordStats() + //设置写缓存后n秒钟过期 + .expireAfterWrite(60, TimeUnit.SECONDS) + //设置读写缓存后n秒钟过期,实际很少用到,类似于expireAfterWrite + //.expireAfterAccess(17, TimeUnit.SECONDS) + //只阻塞当前数据加载线程,其他线程返回旧值 + //.refreshAfterWrite(13, TimeUnit.SECONDS) + //设置缓存的移除通知 + .removalListener(notification -> { + System.out.println(notification.getKey() + " " + notification.getValue() + " 被移除,原因:" + notification.getCause()); + }) + //build方法中可以指定CacheLoader,在缓存不存在时通过CacheLoader的实现自动加载缓存 + .build(new DemoCacheLoader()); + + + public void setCache() throws InterruptedException { + + //模拟线程并发 + Thread a = new Thread(() -> { + //非线程安全的时间格式化工具 + SimpleDateFormat simpleDateFormat = new SimpleDateFormat("HH:mm:ss"); + try { + for (int i = 0; i < 10; i++) { + String value = cache.get(1); + System.out.println(Thread.currentThread().getName() + " " + simpleDateFormat.format(new Date()) + " " + value); + TimeUnit.SECONDS.sleep(1); + } + } catch (Exception ignored) { + } + }); + + Thread b = new Thread(() -> { + SimpleDateFormat simpleDateFormat = new SimpleDateFormat("HH:mm:ss"); + try { + for (int i = 0; i < 10; i++) { + String value = cache.get(1); + System.out.println(Thread.currentThread().getName() + " " + simpleDateFormat.format(new Date()) + " " + value); + TimeUnit.SECONDS.sleep(2); + } + } catch (Exception ignored) { + } + }); + + a.start(); + b.start(); + a.join(); + b.join(); + + //缓存状态查看 + System.out.println(cache.stats().toString()); + + } + + /** + * 随机缓存加载,实际使用时应实现业务的缓存加载逻辑,例如从数据库获取数据 + */ + public static class DemoCacheLoader extends CacheLoader { + @Override + public String load(Integer key) throws Exception { + System.out.println(Thread.currentThread().getName() + " 加载数据开始"); + TimeUnit.SECONDS.sleep(1); + Random random = new Random(); + System.out.println(Thread.currentThread().getName() + " 加载数据结束"); + return "value:" + random.nextInt(10000); + } + } + + @Test + public void testCase(){ + try { + setCache(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + +} diff --git a/src/main/java/com/chen/util/LimitFlowCount.java b/src/main/java/com/chen/util/LimitFlowCount.java new file mode 100644 index 0000000..a0ae7ed --- /dev/null +++ b/src/main/java/com/chen/util/LimitFlowCount.java @@ -0,0 +1,32 @@ +package com.chen.util; + +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; + +/** + * @author : chen weijie + * @Date: 2020-06-09 19:30 + */ +public class LimitFlowCount { + + + /** + * 每秒重置计数器 + */ + private static AtomicInteger counter = new AtomicInteger(); + + public static void main(String[] args) { + + ScheduledExecutorService scheduledExecutorService = Executors.newSingleThreadScheduledExecutor(); + + scheduledExecutorService.scheduleAtFixedRate(new Runnable() { + @Override + public void run() { + counter.set(0); + } + },0,1, TimeUnit.SECONDS); + } + +} diff --git a/src/main/java/com/chen/util/zookeeper/demo3/ZooKeeperDistributedLock.java b/src/main/java/com/chen/util/zookeeper/demo3/ZooKeeperDistributedLock.java index f9e762f..a31a918 100644 --- a/src/main/java/com/chen/util/zookeeper/demo3/ZooKeeperDistributedLock.java +++ b/src/main/java/com/chen/util/zookeeper/demo3/ZooKeeperDistributedLock.java @@ -31,9 +31,7 @@ public ZooKeeperDistributedLock(String productId) { String address = "127.0.0.1:2182,127.0.0.1:2183,127.0.0.1:2184"; zk = new ZooKeeper(address, sessionTimeout, this); connectedLatch.await(); - } catch (IOException e) { - throw new LockException(e); - } catch (InterruptedException e) { + } catch (IOException | InterruptedException e) { throw new LockException(e); } } @@ -50,20 +48,6 @@ public void process(WatchedEvent event) { } } - public void acquireDistributedLock() { - try { - if (this.tryLock()) { - return; - } else { - waitForLock(waitNode, sessionTimeout); - } - } catch (KeeperException e) { - throw new LockException(e); - } catch (InterruptedException e) { - throw new LockException(e); - } - } - public boolean tryLock() { try { @@ -111,6 +95,28 @@ private boolean waitForLock(String waitNode, long waitTime) throws InterruptedEx return true; } + + /** + * 获取分布式锁 + */ + public void acquireDistributedLock() { + try { + if (this.tryLock()) { + return; + } else { + waitForLock(waitNode, sessionTimeout); + } + } catch (KeeperException e) { + throw new LockException(e); + } catch (InterruptedException e) { + throw new LockException(e); + } + } + + + /** + * 释放分布式锁 + */ public void unlock() { try { // 删除/locks/10000000000节点 diff --git a/src/main/resources/META-INF.services.com.chen.api.util.spi.Search/com.chen.api.util.spi.impl.DatabaseSearch b/src/main/resources/META-INF.services.com.chen.api.util.spi.Search/com.chen.api.util.spi.impl.DatabaseSearch new file mode 100644 index 0000000..e69de29 diff --git a/src/main/resources/META-INF.services.com.chen.api.util.spi.Search/com.chen.api.util.spi.impl.FileSearch b/src/main/resources/META-INF.services.com.chen.api.util.spi.Search/com.chen.api.util.spi.impl.FileSearch new file mode 100644 index 0000000..e69de29 diff --git a/src/main/resources/application.xml b/src/main/resources/application.xml index a505d72..c674548 100644 --- a/src/main/resources/application.xml +++ b/src/main/resources/application.xml @@ -5,4 +5,11 @@ + + + + + + + \ No newline at end of file diff --git a/src/main/test/com/chen/test/ArrayListTest.java b/src/main/test/com/chen/test/ArrayListTest.java new file mode 100644 index 0000000..79f0305 --- /dev/null +++ b/src/main/test/com/chen/test/ArrayListTest.java @@ -0,0 +1,38 @@ +package com.chen.test; + +import com.alibaba.fastjson.JSONObject; + +import java.util.ArrayList; + +/** + * @author : chen weijie + * @Date: 2020-04-12 11:26 + */ +public class ArrayListTest { + + + public static void main(String[] args) { + + + ArrayList arrayList = new ArrayList(); + System.out.printf("Before add:arrayList.size() = %d\n", arrayList.size()); + arrayList.add(1); + arrayList.add(3); + arrayList.add(5); + arrayList.add(7); + arrayList.add(9); + + + Integer[] arrays = arrayList.toArray(new Integer[0]); + + + Integer[] arrays2 = new Integer[arrayList.size()]; + + arrays2 = arrayList.toArray(arrays2); + + System.out.println(JSONObject.toJSONString(arrays2)); + + + } + +} diff --git a/src/main/test/com/chen/test/ArraySum.java b/src/main/test/com/chen/test/ArraySum.java new file mode 100644 index 0000000..a539e56 --- /dev/null +++ b/src/main/test/com/chen/test/ArraySum.java @@ -0,0 +1,38 @@ +package com.chen.test; + +import org.junit.Test; + +/** + * @author : chen weijie + * @Date: 2020-04-25 05:24 + */ +public class ArraySum { + + + public void findSum(int[] array, int sum) { + + for (int i = 0; i < array.length; i++) { + int currSum = 0; + int left = i; + int right = i; + while (currSum < sum) { + currSum += array[right++]; + } + + if (currSum == sum) { + for (int k = left; k < right; k++) { + System.out.println(array[k]); + } + } + System.out.println("----"); + } + } + + @Test + public void test() { + int[] num = {1, 2, 2, 3, 4, 5, 6, 7, 8, 9}; + int sum = 7; + findSum(num, sum); + } + +} diff --git a/src/main/test/com/chen/test/Bsearch.java b/src/main/test/com/chen/test/Bsearch.java new file mode 100644 index 0000000..fca36fb --- /dev/null +++ b/src/main/test/com/chen/test/Bsearch.java @@ -0,0 +1,56 @@ +package com.chen.test; + +/** + * @author : chen weijie + * @Date: 2020-04-22 07:18 + */ +public class Bsearch { + + + public int search(int[] array, int target, int high, int low) { + + if (array.length == 0) { + return -1; + } + + if (low > high) { + return -1; + } + + int mid = high - (high - low) >>> 1; + if (target > array[mid]) { + low = mid + 1; + search(array, target, high, low); + } else if (target < array[mid]) { + high = mid - 1; + search(array, target, high, low); + } else { + return mid; + } + + return -1; + } + + + public int search2(int[] array, int target) { + + int high = array.length - 1; + int low = 0; + int mid = high - (high - low) >>> 1; + + while (high > low) { + if (target > array[mid]) { + low = mid + 1; + } else if (target < array[mid]) { + high = mid - 1; + } else { + return mid; + } + } + return -1; + } + + + + +} diff --git a/src/main/test/com/chen/test/BubbleSort.java b/src/main/test/com/chen/test/BubbleSort.java new file mode 100644 index 0000000..c1dc9db --- /dev/null +++ b/src/main/test/com/chen/test/BubbleSort.java @@ -0,0 +1,34 @@ +package com.chen.test; + +/** + * @author : chen weijie + * @Date: 2020-04-25 05:07 + */ +public class BubbleSort { + + + public void solution(int[] array) { + + + boolean flag = false; + + int length = array.length; + for (int i = 0; i < length - 1; i++) { + for (int j = 0; j < length - 1 - i; 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; + } + } + + + } + + +} diff --git a/src/main/test/com/chen/test/BubbleSortTest.java b/src/main/test/com/chen/test/BubbleSortTest.java new file mode 100644 index 0000000..dd10afe --- /dev/null +++ b/src/main/test/com/chen/test/BubbleSortTest.java @@ -0,0 +1,68 @@ +package com.chen.test; + +/** + * @author : chen weijie + * @Date: 2020-05-19 23:38 + */ +public class BubbleSortTest { + + + public static void solution(int[] array) { + + if (array == null || array.length == 0) { + return; + } + + boolean flag = false; + + for (int i = 0; i < array.length; i++) { + for (int j = 1; j < array.length - i; 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; + } + } + } + + + public static void bubbleSort1(int[] numbers) { + + int size = numbers.length; + + boolean flag = false; + for (int i = 0; i < size - 1; i++) { + for (int j = 0; j < size - 1 - i; 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; + } + + } + + } + + public static void main(String[] args) { + + int[] array = {3, 0, 10, 4}; + bubbleSort1(array); + for (int i = 0; i < array.length; i++) { + System.out.println(array[i]); + } + + + } + + +} diff --git a/src/main/test/com/chen/test/ChoiceSortTest.java b/src/main/test/com/chen/test/ChoiceSortTest.java new file mode 100644 index 0000000..09f84b8 --- /dev/null +++ b/src/main/test/com/chen/test/ChoiceSortTest.java @@ -0,0 +1,46 @@ +package com.chen.test; + +import org.junit.Test; + +/** + * @author : chen weijie + * @Date: 2020-04-26 23:24 + */ +public class ChoiceSortTest { + + + @Test + public void solution() { + + int[] array = {4, 6, 1, 2, 5, 10, 0, 11}; + + + for (int i = 0; i < array.length - 1; 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; + } + //第 i轮排序的结果为 + System.out.print("第" + (i + 1) + "轮排序后的结果为:"); + display(array); + } + } + + //遍历显示数组 + public static void display(int[] array) { + for (int i = 0; i < array.length; i++) { + System.out.print(array[i] + " "); + } + System.out.println(); + } + + + +} diff --git a/src/main/test/com/chen/test/ChoiceTest.java b/src/main/test/com/chen/test/ChoiceTest.java new file mode 100644 index 0000000..8780ff3 --- /dev/null +++ b/src/main/test/com/chen/test/ChoiceTest.java @@ -0,0 +1,55 @@ +package com.chen.test; + +/** + * @author : chen weijie + * @Date: 2020-05-25 10:10 + */ +public class ChoiceTest { + + + public static void choiceTest(int[] array) { + + + for (int i = 0; i < array.length - 1; 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[i]; + array[i] = array[min]; + array[min] = temp; + } + //第 i轮排序的结果为 + System.out.print("第" + (i + 1) + "轮排序后的结果为:"); + display(array); + } + + } + + //遍历显示数组 + public static void display(int[] array) { + for (int i = 0; i < array.length; i++) { + System.out.print(array[i] + " "); + } + System.out.println(); + } + + public static void main(String[] args) { + + int[] array = {4, 2, 8, 9, 5, 7, 6, 1, 3}; + //未排序数组顺序为 + System.out.println("未排序数组顺序为:"); + display(array); + System.out.println("-----------------------"); + choiceTest(array); + System.out.println("-----------------------"); + System.out.println("经过选择排序后的数组顺序为:"); + display(array); + } + + +} diff --git a/src/main/test/com/chen/test/CountDownTest.java b/src/main/test/com/chen/test/CountDownTest.java index 81a46d1..168d2fb 100644 --- a/src/main/test/com/chen/test/CountDownTest.java +++ b/src/main/test/com/chen/test/CountDownTest.java @@ -17,13 +17,16 @@ public static void main(String[] args) { for (int i = 0; i < 10; i++) { new Thread(() -> { - System.out.println(UUID.randomUUID().toString()); - try { - Thread.sleep(1000); - } catch (InterruptedException e) { - e.printStackTrace(); + synchronized (countDownLatch.getClass()){ + System.out.println(UUID.randomUUID().toString()); + try { + Thread.sleep(1000); + } catch (InterruptedException e) { + e.printStackTrace(); + } + countDownLatch.countDown(); } - countDownLatch.countDown(); + }).start(); } diff --git a/src/main/test/com/chen/test/FindTwoPointTest.java b/src/main/test/com/chen/test/FindTwoPointTest.java new file mode 100644 index 0000000..d745da7 --- /dev/null +++ b/src/main/test/com/chen/test/FindTwoPointTest.java @@ -0,0 +1,34 @@ +package com.chen.test; + +/** + * @author : chen weijie + * @Date: 2020-04-23 08:53 + */ +public class FindTwoPointTest { + + + public int solution(int[] n, int target) { + + + int min = 0; + int max = n.length; + int mid = min + (max - min) >>> 1; + + while (max > min) { + if (target == n[mid]) { + return mid; + } + if (target > n[mid]) { + min = mid + 1; + } else { + max = mid - 1; + } + } + + return -1; + + + } + + +} diff --git a/src/main/test/com/chen/test/InsertSort.java b/src/main/test/com/chen/test/InsertSort.java new file mode 100644 index 0000000..763461b --- /dev/null +++ b/src/main/test/com/chen/test/InsertSort.java @@ -0,0 +1,47 @@ +package com.chen.test; + +/** + * @author : chen weijie + * @Date: 2020-05-25 10:23 + */ +public class InsertSort { + + + + + public static void testSort(int [] array){ + + for (int i = 1; i < array.length; i++) { + int temp = array[i]; + int left = i - 1; + while (left >= 0 && temp < array[left]) { + array[left + 1] = array[left]; + left--; + } + array[left + 1] = temp; + } + + } + + //遍历显示数组 + public static void display(int[] array) { + for (int i = 0; i < array.length; i++) { + System.out.print(array[i] + " "); + } + System.out.println(); + } + + public static void main(String[] args) { + int[] array = {6,8,1,2,4}; + //未排序数组顺序为 + System.out.println("未排序数组顺序为:"); + display(array); + System.out.println("-----------------------"); + testSort(array); + System.out.println("-----------------------"); + System.out.println("经过插入排序后的数组顺序为:"); + display(array); + } + + +} diff --git a/src/main/test/com/chen/test/InsertSortTest.java b/src/main/test/com/chen/test/InsertSortTest.java new file mode 100644 index 0000000..4f5f4ac --- /dev/null +++ b/src/main/test/com/chen/test/InsertSortTest.java @@ -0,0 +1,39 @@ +package com.chen.test; + +import org.junit.Test; + +/** + * @author : chen weijie + * @Date: 2020-04-26 23:39 + */ +public class InsertSortTest { + + + @Test + public void solution() { + + int[] array = {4, 1, 0, 10, 5}; + + for (int i = 1; i < array.length; i++) { + int temp = array[i]; + int leftIndex = i - 1; + while (leftIndex >= 0 && temp < array[leftIndex]) { + array[leftIndex + 1] = array[leftIndex]; + leftIndex--; + } + array[leftIndex + 1] = temp; + display(array); + } + } + + + //遍历显示数组 + public static void display(int[] array) { + for (int i = 0; i < array.length; i++) { + System.out.print(array[i] + " "); + } + System.out.println(); + } + + +} diff --git a/src/main/test/com/chen/test/LengthOfLongestSubstring.java b/src/main/test/com/chen/test/LengthOfLongestSubstring.java new file mode 100644 index 0000000..94db34d --- /dev/null +++ b/src/main/test/com/chen/test/LengthOfLongestSubstring.java @@ -0,0 +1,47 @@ +package com.chen.test; + +import org.junit.Test; + +import java.util.HashSet; +import java.util.Set; + +/** + * @author : chen weijie + * @Date: 2020-05-02 09:48 + */ +public class LengthOfLongestSubstring { + + public int lengthOfLongestSubstring(String s) { + + if (s == null || "".equals(s)) { + return 0; + } + + if (" ".equals(s)) { + return 1; + } + + char[] chars = s.toCharArray(); + int maxLength = 0; + Set set = new HashSet<>(); + for (int i = 0; i < chars.length; i++) { + for (int j = i; j < chars.length; j++) { + if (set.contains(chars[j])) { + set.clear(); + break; + } + set.add(chars[j]); + maxLength = Math.max(maxLength, set.size()); + } + } + return maxLength; + } + + + @Test + public void testCase() { + System.out.println(lengthOfLongestSubstring("a")); + } + + +} diff --git a/src/main/test/com/chen/test/LinkList/Solution.java b/src/main/test/com/chen/test/LinkList/Solution.java new file mode 100644 index 0000000..e734239 --- /dev/null +++ b/src/main/test/com/chen/test/LinkList/Solution.java @@ -0,0 +1,8 @@ +package com.chen.test.LinkList; + +/** + * @author : chen weijie + * @Date: 2020-05-03 14:42 + */ +public class Solution { +} diff --git a/src/main/test/com/chen/test/LinkedListDemo.java b/src/main/test/com/chen/test/LinkedListDemo.java new file mode 100644 index 0000000..ab68ed0 --- /dev/null +++ b/src/main/test/com/chen/test/LinkedListDemo.java @@ -0,0 +1,130 @@ +package com.chen.test; + +import java.util.Iterator; +import java.util.LinkedList; + +/** + * @author : chen weijie + * @Date: 2020-04-12 16:34 + */ +public class LinkedListDemo { + + + public static void main(String[] args) { + + LinkedList linkedList = new LinkedList(); + linkedList.addFirst(0); + linkedList.add(1); + linkedList.add(2, 2); + linkedList.addLast(3); +// linkedList.add(0,1); + + System.out.println("linkedList:" + linkedList); + + + System.out.println("getFirst()获得第一个元素: " + linkedList.getFirst()); // 返回此列表的第一个元素 + System.out.println("getLast()获得第最后一个元素: " + linkedList.getLast()); // 返回此列表的最后一个元素 + System.out.println("removeFirst()删除第一个元素并返回: " + linkedList.removeFirst()); // 移除并返回此列表的第一个元素 + System.out.println("removeLast()删除最后一个元素并返回: " + linkedList.removeLast()); // 移除并返回此列表的最后一个元素 + System.out.println("After remove:" + linkedList); + System.out.println("contains()方法判断列表是否包含1这个元素:" + linkedList.contains(1)); // 判断此列表包含指定元素,如果是,则返回true + System.out.println("该linkedList的大小 : " + linkedList.size()); // 返回此列表的元素个数 + + /************************** 位置访问操作 ************************/ + System.out.println("-----------------------------------------"); + linkedList.set(1, 3); // 将此列表中指定位置的元素替换为指定的元素 + System.out.println("After set(1, 3):" + linkedList); + System.out.println("get(1)获得指定位置(这里为1)的元素: " + linkedList.get(1)); // 返回此列表中指定位置处的元素 + + /************************** Search操作 ************************/ + System.out.println("-----------------------------------------"); + linkedList.add(3); + System.out.println("indexOf(3): " + linkedList.indexOf(3)); // 返回此列表中首次出现的指定元素的索引 + System.out.println("lastIndexOf(3): " + linkedList.lastIndexOf(3));// 返回此列表中最后出现的指定元素的索引 + + /************************** Queue操作 ************************/ + System.out.println("-----------------------------------------"); + System.out.println("peek(): " + linkedList.peek()); // 获取但不移除此列表的头 + System.out.println("element(): " + linkedList.element()); // 获取但不移除此列表的头 + linkedList.poll(); // 获取并移除此列表的头 + System.out.println("After poll():" + linkedList); + linkedList.remove(); + System.out.println("After remove():" + linkedList); // 获取并移除此列表的头 + linkedList.offer(4); + System.out.println("After offer(4):" + linkedList); // 将指定元素添加到此列表的末尾 + + /************************** Deque操作 ************************/ + System.out.println("-----------------------------------------"); + linkedList.offerFirst(2); // 在此列表的开头插入指定的元素 + System.out.println("After offerFirst(2):" + linkedList); + linkedList.offerLast(5); // 在此列表末尾插入指定的元素 + System.out.println("After offerLast(5):" + linkedList); + System.out.println("peekFirst(): " + linkedList.peekFirst()); // 获取但不移除此列表的第一个元素 + System.out.println("peekLast(): " + linkedList.peekLast()); // 获取但不移除此列表的第一个元素 + linkedList.pollFirst(); // 获取并移除此列表的第一个元素 + System.out.println("After pollFirst():" + linkedList); + linkedList.pollLast(); // 获取并移除此列表的最后一个元素 + System.out.println("After pollLast():" + linkedList); + linkedList.push(2); // 将元素推入此列表所表示的堆栈(插入到列表的头) + System.out.println("After push(2):" + linkedList); + linkedList.pop(); // 从此列表所表示的堆栈处弹出一个元素(获取并移除列表第一个元素) + System.out.println("After pop():" + linkedList); + linkedList.add(3); + linkedList.removeFirstOccurrence(3); // 从此列表中移除第一次出现的指定元素(从头部到尾部遍历列表) + System.out.println("After removeFirstOccurrence(3):" + linkedList); + linkedList.removeLastOccurrence(3); // 从此列表中移除最后一次出现的指定元素(从尾部到头部遍历列表) + System.out.println("After removeFirstOccurrence(3):" + linkedList); + + /************************** 遍历操作 ************************/ + System.out.println("-----------------------------------------"); + linkedList.clear(); + for (int i = 0; i < 100000; i++) { + linkedList.add(i); + } + // 迭代器遍历 + long start = System.currentTimeMillis(); + Iterator iterator = linkedList.iterator(); + while (iterator.hasNext()) { + iterator.next(); + } + long end = System.currentTimeMillis(); + System.out.println("Iterator:" + (end - start) + " ms"); + + // 顺序遍历(随机遍历) + start = System.currentTimeMillis(); + for (int i = 0; i < linkedList.size(); i++) { + linkedList.get(i); + } + end = System.currentTimeMillis(); + System.out.println("for:" + (end - start) + " ms"); + + // 另一种for循环遍历 + start = System.currentTimeMillis(); + for (Integer i : linkedList) + ; + end = System.currentTimeMillis(); + System.out.println("for2:" + (end - start) + " ms"); + + // 通过pollFirst()或pollLast()来遍历LinkedList + LinkedList temp1 = new LinkedList<>(); + temp1.addAll(linkedList); + start = System.currentTimeMillis(); + while (temp1.size() != 0) { + temp1.pollFirst(); + } + end = System.currentTimeMillis(); + System.out.println("pollFirst()或pollLast():" + (end - start) + " ms"); + + // 通过removeFirst()或removeLast()来遍历LinkedList + LinkedList temp2 = new LinkedList<>(); + temp2.addAll(linkedList); + start = System.currentTimeMillis(); + while (temp2.size() != 0) { + temp2.removeFirst(); + } + end = System.currentTimeMillis(); + System.out.println("removeFirst()或removeLast():" + (end - start) + " ms"); + + + } +} diff --git a/src/main/test/com/chen/test/MergeSort.java b/src/main/test/com/chen/test/MergeSort.java new file mode 100644 index 0000000..6b74520 --- /dev/null +++ b/src/main/test/com/chen/test/MergeSort.java @@ -0,0 +1,46 @@ +package com.chen.test; + +/** + * @author : chen weijie + * @Date: 2020-04-22 07:43 + */ +public class MergeSort { + + + public void solution(int[] a, int[] b) { + + int[] result = new int[a.length + b.length]; + + int i = 0, j = 0, l = 0; + + while (i < a.length && j < b.length) { + if (a[i] < b[j]) { + result[l++] = a[i++]; + } else { + result[l++] = b[j++]; + } + } + + while (j < b.length) { + result[l++] = b[j++]; + } + while (i < a.length) { + result[l++] = a[i++]; + } + } + + + public boolean checkSort(int[] array) { + + boolean change = true; + for (int i = 0; i < array.length && change; i++) { + for (int j = 0; j < array.length - 1 - i; j++) { + change = array[j] <= array[j + 1]; + } + } + return change; + } + + + +} diff --git a/src/main/test/com/chen/test/MergeToList.java b/src/main/test/com/chen/test/MergeToList.java new file mode 100644 index 0000000..b6d97c0 --- /dev/null +++ b/src/main/test/com/chen/test/MergeToList.java @@ -0,0 +1,38 @@ +package com.chen.test; + +/** + * @author : chen weijie + * @Date: 2020-05-01 23:39 + */ +public class MergeToList { + + + 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/test/com/chen/test/Mutex.java b/src/main/test/com/chen/test/Mutex.java new file mode 100644 index 0000000..83fb62b --- /dev/null +++ b/src/main/test/com/chen/test/Mutex.java @@ -0,0 +1,63 @@ +package com.chen.test; + +import java.util.concurrent.locks.AbstractQueuedSynchronizer; + +/** + * @author Chen WeiJie + * @date 2020-04-23 16:50:07 + **/ +public class Mutex { + + + public static class Sync extends AbstractQueuedSynchronizer { + + + @Override + protected boolean isHeldExclusively() { + return getState() == 1; + } + + + @Override + protected boolean tryAcquire(int arg) { + + if (compareAndSetState(0, 1)) { + setExclusiveOwnerThread(Thread.currentThread()); + return true; + } + return false; + } + + @Override + protected boolean tryRelease(int arg) { + + if (getState() == 0) { + throw new IllegalMonitorStateException(); + } + setExclusiveOwnerThread(null); + setState(0); + return true; + } + + } + + private final Sync sync = new Sync(); + + public void lock() { + sync.acquire(1); + } + + + public boolean tryLock() { + return sync.tryAcquire(1); + } + + public void unlock() { + sync.release(1); + } + + public boolean isLocked() { + return sync.isHeldExclusively(); + } + +} diff --git a/src/main/test/com/chen/test/MybatisIntercepter.java b/src/main/test/com/chen/test/MybatisIntercepter.java new file mode 100644 index 0000000..0591d99 --- /dev/null +++ b/src/main/test/com/chen/test/MybatisIntercepter.java @@ -0,0 +1,28 @@ +package com.chen.test; + +import org.apache.ibatis.plugin.Interceptor; +import org.apache.ibatis.plugin.Invocation; + +import java.util.Properties; + +/** + * @author : chen weijie + * @Date: 2020-04-15 01:59 + */ +public class MybatisIntercepter implements Interceptor { + + @Override + public Object intercept(Invocation invocation) throws Throwable { + return null; + } + + @Override + public Object plugin(Object o) { + return null; + } + + @Override + public void setProperties(Properties properties) { + + } +} diff --git a/src/main/test/com/chen/test/QuickSortTest.java b/src/main/test/com/chen/test/QuickSortTest.java new file mode 100644 index 0000000..b0998f7 --- /dev/null +++ b/src/main/test/com/chen/test/QuickSortTest.java @@ -0,0 +1,50 @@ +package com.chen.test; + +import org.junit.Test; + +/** + * @author : chen weijie + * @Date: 2020-04-27 00:15 + */ +public class QuickSortTest { + + + @Test + public void solution() { + + int[] array = {4, 3, 1, 0, 6, 5, 10}; + + sort(array, 0, array.length - 1); + } + + + public void sort(int[] array, int low, int high) { + Integer pivot = getPivot(array, low, high); + sort(array, low, pivot - 1); + sort(array, pivot + 1, high); + for (int num : array) { + System.out.print(num); + } + } + + + private int getPivot(int[] array, int low, int high) { + 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; + } + + +} diff --git a/src/main/test/com/chen/test/RecursionTest.java b/src/main/test/com/chen/test/RecursionTest.java new file mode 100644 index 0000000..07e0ec0 --- /dev/null +++ b/src/main/test/com/chen/test/RecursionTest.java @@ -0,0 +1,39 @@ +package com.chen.test; + +import org.junit.Test; + +/** + * @author : chen weijie + * @Date: 2020-04-23 08:47 + */ +public class RecursionTest { + + + @Test + public void test1() { + + int n = 3; + int temp = 1; + for (int i = 1; i <= n; i++) { + temp = temp * i; + } + System.out.println(temp); + } + + public int solution(int n) { + + if (n == 1) { + return 1; + } + return solution(n - 1) * n; + } + + @Test + public void test() { + + System.out.println(solution(4)); + + } + + +} diff --git a/src/main/test/com/chen/test/RevertLinkList.java b/src/main/test/com/chen/test/RevertLinkList.java new file mode 100644 index 0000000..f155515 --- /dev/null +++ b/src/main/test/com/chen/test/RevertLinkList.java @@ -0,0 +1,24 @@ +package com.chen.test; + +/** + * @author : chen weijie + * @Date: 2020-04-27 00:44 + */ +public class RevertLinkList { + + public static class Node{ + + private int value; + + private Node next; + + public Node(int value){ + this.value =value; + } + } + + + + + +} diff --git a/src/main/test/com/chen/test/Test.java b/src/main/test/com/chen/test/Test.java new file mode 100644 index 0000000..27b5183 --- /dev/null +++ b/src/main/test/com/chen/test/Test.java @@ -0,0 +1,17 @@ +package com.chen.test; + +/** + * @author : chen weijie + * @Date: 2020-09-03 23:20 + */ +public class Test { + + + public static void main(String[] args) { + + while (true){ + System.out.println(System.currentTimeMillis()); + } + + } +} diff --git a/src/main/test/com/chen/test/Test2.java b/src/main/test/com/chen/test/Test2.java new file mode 100644 index 0000000..802e57d --- /dev/null +++ b/src/main/test/com/chen/test/Test2.java @@ -0,0 +1,24 @@ +package com.chen.test; + +import java.util.Date; + +/** + * @author Chen WeiJie + * @date 2020-04-27 15:22:48 + **/ +public class Test2 { + + + public static void main(String[] args) { + + Date d = new Date(); + + Date d2 = d; + + System.out.println(d.compareTo(d2)); + + + + + } +} diff --git a/src/main/test/com/chen/test/TestArray.java b/src/main/test/com/chen/test/TestArray.java new file mode 100644 index 0000000..72aacd3 --- /dev/null +++ b/src/main/test/com/chen/test/TestArray.java @@ -0,0 +1,20 @@ +package com.chen.test; + +/** + * @author : chen weijie + * @Date: 2020-07-21 14:54 + */ +public class TestArray { + + + public static void main(String[] args) { + + int[][] array = new int[4][5]; + array[0] = new int[]{5, 6, 7, 8, 5}; + + char[] characters = args[0].toCharArray(); + + } + + +} diff --git a/src/main/test/com/chen/test/TestCPUCount.java b/src/main/test/com/chen/test/TestCPUCount.java new file mode 100644 index 0000000..171cee1 --- /dev/null +++ b/src/main/test/com/chen/test/TestCPUCount.java @@ -0,0 +1,16 @@ +package com.chen.test; + +/** + * @author : chen weijie + * @Date: 2020-06-03 18:30 + */ +public class TestCPUCount { + + + public static void main(String[] args) { + + int n = Runtime.getRuntime().availableProcessors(); + System.out.println(n); + + } +} diff --git a/src/main/test/com/chen/test/TestClockWiseOutPut.java b/src/main/test/com/chen/test/TestClockWiseOutPut.java new file mode 100644 index 0000000..154cd0d --- /dev/null +++ b/src/main/test/com/chen/test/TestClockWiseOutPut.java @@ -0,0 +1,53 @@ +package com.chen.test; + +import org.junit.Test; + +/** + * @author : chen weijie + * @Date: 2020-04-23 08:16 + */ +public class TestClockWiseOutPut { + + + @Test + public void test() { + + int[][] array = new int[100][100]; + int n = 4; + int count = 1; + for (int i = 0; i < n; i++) { + for (int j = 0; j < n; j++) { + array[i][j] = count++; + } + } + output(0, n - 1, array); + } + + + public void output(int start, int end, int[][] array) { + if (end < start || start < 0) { + return; + } + + for (int i = start; i <= end; i++) { + System.out.println(array[start][i]); + } + + for (int i = start + 1; i <= end; i++) { + System.out.println(array[i][end]); + } + + for (int i = end - 1; i >= start; i--) { + System.out.println(array[end][i]); + } + + for (int i = end - 1; i >= start + 1; i--) { + System.out.println(array[start][i]); + } + + output(start + 1, end - 1, array); + + } + + +} diff --git a/src/main/test/com/chen/test/TestFor.java b/src/main/test/com/chen/test/TestFor.java new file mode 100644 index 0000000..d5722b1 --- /dev/null +++ b/src/main/test/com/chen/test/TestFor.java @@ -0,0 +1,22 @@ +package com.chen.test; + +/** + * @author : chen weijie + * @Date: 2020-05-02 16:07 + */ +public class TestFor { + + public static void main(String[] args) { + + for (int i = 0; i < 10; i++) { + System.out.println(i); + } + + System.out.println("------------"); + for (int i = 0; i < 10; ++i) { + System.out.println(i); + } + + + } +} diff --git a/src/main/test/com/chen/test/TestJSON.java b/src/main/test/com/chen/test/TestJSON.java new file mode 100644 index 0000000..2ec2ebf --- /dev/null +++ b/src/main/test/com/chen/test/TestJSON.java @@ -0,0 +1,37 @@ +package com.chen.test; + +import com.alibaba.fastjson.JSONObject; + +/** + * @author : chen weijie + * @Date: 2020-06-12 11:48 + */ +public class TestJSON { + + + static class People { + + Integer age; + + public Integer getAge() { + return age; + } + + public void setAge(Integer age) { + this.age = age; + } + } + + + public static void main(String[] args) { + + + String json = "{\"age\":\"43\"}"; + + People people =JSONObject.parseObject(json,People.class); + + + + + } +} diff --git a/src/main/test/com/chen/test/TestLinkRevert.java b/src/main/test/com/chen/test/TestLinkRevert.java new file mode 100644 index 0000000..d0a75e8 --- /dev/null +++ b/src/main/test/com/chen/test/TestLinkRevert.java @@ -0,0 +1,47 @@ +package com.chen.test; + +/** + * @author Chen WeiJie + * @date 2020-05-27 17:26:50 + **/ +public class TestLinkRevert { + + + /** + * Definition for singly-linked list. + * public class ListNode { + * int val; + * ListNode next; + * ListNode(int x) { val = x; } + * } + */ + public class ListNode { + int val; + ListNode next; + + ListNode(int x) { + val = x; + } + } + + class Solution { + + public ListNode reverseBetween(ListNode head, int m, int n) { + ListNode pre = new ListNode(0); + ListNode ans = pre; + pre.next = head; + for (int i = 0; i < m - 1; i++) { + pre = pre.next; + } + ListNode end = pre.next; + for (int i = m; i < n; i++) { + ListNode tmp = end.next; + end.next = tmp.next; + tmp.next = pre.next; + pre.next = tmp; + } + return ans.next; + } + } + +} diff --git a/src/main/test/com/chen/test/TestMaxSubArray.java b/src/main/test/com/chen/test/TestMaxSubArray.java new file mode 100644 index 0000000..01feff7 --- /dev/null +++ b/src/main/test/com/chen/test/TestMaxSubArray.java @@ -0,0 +1,35 @@ +package com.chen.test; + +import org.junit.Test; + +/** + * @author : chen weijie + * @Date: 2020-05-03 10:49 + */ +public class TestMaxSubArray { + + + public int maxSubArray(int[] nums) { + + int max = Integer.MIN_VALUE; + + + for (int i = 0; i < nums.length; i++) { + int temp = 0; + for (int j = i; j < nums.length; j++) { + temp = temp + nums[j]; + max = Math.max(max, temp); + } + } + return max; + } + + + @Test + public void print() { + int[] array = {-2, 1, -3, 4, -1, 2, 1, -5, 4}; + System.out.println(maxSubArray(array)); + } + + +} diff --git a/src/main/test/com/chen/test/TestMode.java b/src/main/test/com/chen/test/TestMode.java index 40d1192..0f003e9 100644 --- a/src/main/test/com/chen/test/TestMode.java +++ b/src/main/test/com/chen/test/TestMode.java @@ -10,7 +10,7 @@ public class TestMode { public static void main(String[] args) { - int n = 1922353 % 400; + int n = 34856084 % 400; System.out.println(n); diff --git a/src/main/test/com/chen/test/TestMutex.java b/src/main/test/com/chen/test/TestMutex.java new file mode 100644 index 0000000..66933d0 --- /dev/null +++ b/src/main/test/com/chen/test/TestMutex.java @@ -0,0 +1,79 @@ +package com.chen.test; + +import java.util.concurrent.BrokenBarrierException; +import java.util.concurrent.CyclicBarrier; + +/** + * @author Chen WeiJie + * @date 2020-04-23 17:02:02 + **/ +public class TestMutex { + + + private static CyclicBarrier barrier = new CyclicBarrier(31); + + private static int a = 0; + + private static Mutex mutex = new Mutex(); + + + public static void main(String[] args) throws BrokenBarrierException, InterruptedException { + + + for (int i = 0; i < 30; i++) { + + new Thread(() -> { + for (int j = 0; j < 10000; j++) { + increment(); + } + try { + barrier.await(); + } catch (InterruptedException e) { + e.printStackTrace(); + } catch (BrokenBarrierException e) { + e.printStackTrace(); + } + }).start(); + } + + barrier.await(); + System.out.println("a===" + a); + barrier.reset(); + a = 0; + + for (int i = 0; i < 30; i++) { + new Thread(() -> { + for (int j = 0; j < 10000; j++) { + increment2(); + } + try { + barrier.await(); + } catch (InterruptedException e) { + e.printStackTrace(); + } catch (BrokenBarrierException e) { + e.printStackTrace(); + } + }).start(); + } + + barrier.await(); + System.out.println("a===" + a); + + + } + + + public static void increment() { + + a++; + } + + + public static void increment2() { + mutex.lock(); + a++; + mutex.unlock(); + } + + +} diff --git a/src/main/test/com/chen/test/TestPool.java b/src/main/test/com/chen/test/TestPool.java new file mode 100644 index 0000000..83512ab --- /dev/null +++ b/src/main/test/com/chen/test/TestPool.java @@ -0,0 +1,22 @@ +package com.chen.test; + +/** + * @author : chen weijie + * @Date: 2020-06-06 16:40 + */ +public class TestPool { + + + public static void main(String[] args) { + + System.out.println(count(10)); + } + + + public static int count(int i) { + int c = i + i; + return count(c); + } + + +} diff --git a/src/main/test/com/chen/test/TestRevertLinkList.java b/src/main/test/com/chen/test/TestRevertLinkList.java new file mode 100644 index 0000000..4d30295 --- /dev/null +++ b/src/main/test/com/chen/test/TestRevertLinkList.java @@ -0,0 +1,43 @@ +package com.chen.test; + +import org.junit.Test; + +/** + * @author : chen weijie + * @Date: 2020-04-28 18:37 + */ +public class TestRevertLinkList { + + + public static class ListNode { + + private int value; + + private ListNode next; + + public ListNode(int value) { + this.value = value; + } + } + + + @Test + public ListNode solution() { + + + ListNode head = new ListNode(3); + + ListNode pre = null; + ListNode next = null; + + while (head != null) { + next = head.next; + head.next = pre; + pre = head; + head = next; + } + return pre; + + } + +} diff --git a/src/main/test/com/chen/test/TestStreamFilter.java b/src/main/test/com/chen/test/TestStreamFilter.java new file mode 100644 index 0000000..0050cb6 --- /dev/null +++ b/src/main/test/com/chen/test/TestStreamFilter.java @@ -0,0 +1,34 @@ +package com.chen.test; + +import com.alibaba.fastjson.JSONObject; + +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; + +/** + * @author Chen WeiJie + * @date 2019-12-31 14:52:47 + **/ +public class TestStreamFilter { + + public static void main(String[] args) { + + +// List list = Arrays.asList(1, 2, 3, 4, 5).stream().filter(o -> o != 4).collect(Collectors.toList()); +// System.out.println(JSONObject.toJSONString(list)); + + List stringList = new ArrayList<>(); + stringList.add("test"); + stringList.add("test"); + + stringList = stringList.stream().distinct().collect(Collectors.toList()); + + System.out.println(JSONObject.toJSONString(stringList)); + + + + + } + +} diff --git a/src/main/test/com/chen/test/TestTask.java b/src/main/test/com/chen/test/TestTask.java new file mode 100644 index 0000000..7e3b386 --- /dev/null +++ b/src/main/test/com/chen/test/TestTask.java @@ -0,0 +1,23 @@ +package com.chen.test; + +/** + * @author : chen weijie + * @Date: 2019-11-29 18:08 + */ +public class TestTask { + + + public static void main(String[] args) { + + + for (int i = 0; i < 10; i++) { + Thread thread = new Thread(new WorkTask(i)); + thread.start(); + } + + + + } + + +} diff --git a/src/main/test/com/chen/test/TestThread.java b/src/main/test/com/chen/test/TestThread.java index be7bce9..4513f6f 100644 --- a/src/main/test/com/chen/test/TestThread.java +++ b/src/main/test/com/chen/test/TestThread.java @@ -7,7 +7,7 @@ public class TestThread { public static void main(String[] args) { - System.out.println("主线程ID:" + Thread.currentThread().getId()); + System.out.println("主线程ID:" + java.lang.Thread.currentThread().getId()); MyThread thread1 = new MyThread("thread1"); thread1.start(); MyThread thread2 = new MyThread("thread2"); diff --git a/src/main/test/com/chen/test/WorkTask.java b/src/main/test/com/chen/test/WorkTask.java new file mode 100644 index 0000000..b6554db --- /dev/null +++ b/src/main/test/com/chen/test/WorkTask.java @@ -0,0 +1,23 @@ +package com.chen.test; + +/** + * @author : chen weijie + * @Date: 2019-11-29 18:06 + */ +public class WorkTask implements Runnable { + + + private int value; + + + public WorkTask(int value) { + this.value = value; + } + + @Override + public void run() { + + System.out.println(value); + + } +} diff --git a/src/main/test/com/chen/test/abstractFacory/BMW320.java b/src/main/test/com/chen/test/abstractFacory/BMW320.java new file mode 100644 index 0000000..bbfd531 --- /dev/null +++ b/src/main/test/com/chen/test/abstractFacory/BMW320.java @@ -0,0 +1,18 @@ +package com.chen.test.abstractFacory; + +/** + * @author : chen weijie + * @Date: 2020-04-21 01:19 + */ +public class BMW320 implements BMWFactory { + + @Override + public void buildBMW() { + Container container = new BMW320Container(); + container.buildContainer(); + + Engine engine = new BMW320Engine(); + engine.buildEngine(); + + } +} diff --git a/src/main/test/com/chen/test/abstractFacory/BMW320Container.java b/src/main/test/com/chen/test/abstractFacory/BMW320Container.java new file mode 100644 index 0000000..c69cb20 --- /dev/null +++ b/src/main/test/com/chen/test/abstractFacory/BMW320Container.java @@ -0,0 +1,13 @@ +package com.chen.test.abstractFacory; + +/** + * @author : chen weijie + * @Date: 2020-04-21 01:16 + */ +public class BMW320Container implements Container { + + @Override + public void buildContainer() { + System.out.println("build 320 container"); + } +} diff --git a/src/main/test/com/chen/test/abstractFacory/BMW320Engine.java b/src/main/test/com/chen/test/abstractFacory/BMW320Engine.java new file mode 100644 index 0000000..71dcf97 --- /dev/null +++ b/src/main/test/com/chen/test/abstractFacory/BMW320Engine.java @@ -0,0 +1,14 @@ +package com.chen.test.abstractFacory; + +/** + * @author : chen weijie + * @Date: 2020-04-21 01:17 + */ +public class BMW320Engine implements Engine { + + + @Override + public void buildEngine() { + System.out.println("build 320 engine"); + } +} diff --git a/src/main/test/com/chen/test/abstractFacory/BMW520.java b/src/main/test/com/chen/test/abstractFacory/BMW520.java new file mode 100644 index 0000000..9996ed1 --- /dev/null +++ b/src/main/test/com/chen/test/abstractFacory/BMW520.java @@ -0,0 +1,18 @@ +package com.chen.test.abstractFacory; + +/** + * @author : chen weijie + * @Date: 2020-04-21 01:19 + */ +public class BMW520 implements BMWFactory { + + @Override + public void buildBMW() { + Container container = new BMW520Container(); + container.buildContainer(); + + Engine engine = new BMW520Engine(); + engine.buildEngine(); + + } +} diff --git a/src/main/test/com/chen/test/abstractFacory/BMW520Container.java b/src/main/test/com/chen/test/abstractFacory/BMW520Container.java new file mode 100644 index 0000000..3d71ad9 --- /dev/null +++ b/src/main/test/com/chen/test/abstractFacory/BMW520Container.java @@ -0,0 +1,13 @@ +package com.chen.test.abstractFacory; + +/** + * @author : chen weijie + * @Date: 2020-04-21 01:16 + */ +public class BMW520Container implements Container { + + @Override + public void buildContainer() { + System.out.println("build 520 container"); + } +} diff --git a/src/main/test/com/chen/test/abstractFacory/BMW520Engine.java b/src/main/test/com/chen/test/abstractFacory/BMW520Engine.java new file mode 100644 index 0000000..e1c3236 --- /dev/null +++ b/src/main/test/com/chen/test/abstractFacory/BMW520Engine.java @@ -0,0 +1,13 @@ +package com.chen.test.abstractFacory; + +/** + * @author : chen weijie + * @Date: 2020-04-21 01:18 + */ +public class BMW520Engine implements Engine{ + + @Override + public void buildEngine() { + System.out.println("build 520 engine"); + } +} diff --git a/src/main/test/com/chen/test/abstractFacory/BMWFactory.java b/src/main/test/com/chen/test/abstractFacory/BMWFactory.java new file mode 100644 index 0000000..de5a7d3 --- /dev/null +++ b/src/main/test/com/chen/test/abstractFacory/BMWFactory.java @@ -0,0 +1,10 @@ +package com.chen.test.abstractFacory; + +/** + * @author : chen weijie + * @Date: 2020-04-21 01:18 + */ +public interface BMWFactory { + + void buildBMW(); +} diff --git a/src/main/test/com/chen/test/abstractFacory/Container.java b/src/main/test/com/chen/test/abstractFacory/Container.java new file mode 100644 index 0000000..375ab67 --- /dev/null +++ b/src/main/test/com/chen/test/abstractFacory/Container.java @@ -0,0 +1,11 @@ +package com.chen.test.abstractFacory; + +/** + * @author : chen weijie + * @Date: 2020-04-21 01:15 + */ +public interface Container { + + + void buildContainer(); +} diff --git a/src/main/test/com/chen/test/abstractFacory/Engine.java b/src/main/test/com/chen/test/abstractFacory/Engine.java new file mode 100644 index 0000000..34c9e65 --- /dev/null +++ b/src/main/test/com/chen/test/abstractFacory/Engine.java @@ -0,0 +1,10 @@ +package com.chen.test.abstractFacory; + +/** + * @author : chen weijie + * @Date: 2020-04-21 01:15 + */ +public interface Engine { + + void buildEngine(); +} diff --git a/src/main/test/com/chen/test/abstractFacory/Test.java b/src/main/test/com/chen/test/abstractFacory/Test.java new file mode 100644 index 0000000..be15cdb --- /dev/null +++ b/src/main/test/com/chen/test/abstractFacory/Test.java @@ -0,0 +1,19 @@ +package com.chen.test.abstractFacory; + +/** + * @author : chen weijie + * @Date: 2020-04-21 01:21 + */ +public class Test { + + public static void main(String[] args) { + BMWFactory bmw320 = new BMW320(); + + BMWFactory bmw520 = new BMW520(); + + bmw320.buildBMW(); + bmw520.buildBMW(); + + + } +} diff --git a/src/main/test/com/chen/test/agent/Teacher.java b/src/main/test/com/chen/test/agent/Teacher.java index f31e09a..6e8b70e 100644 --- a/src/main/test/com/chen/test/agent/Teacher.java +++ b/src/main/test/com/chen/test/agent/Teacher.java @@ -9,7 +9,6 @@ public class Teacher implements People { @Override public void work() { - System.out.println("老师的工作时教书"); } } diff --git a/src/main/test/com/chen/test/designPattern/Singleton.java b/src/main/test/com/chen/test/designPattern/Singleton.java new file mode 100644 index 0000000..c76f052 --- /dev/null +++ b/src/main/test/com/chen/test/designPattern/Singleton.java @@ -0,0 +1,27 @@ +package com.chen.test.designPattern; + +/** + * @author : chen weijie + * @Date: 2020-04-21 00:15 + */ +public class Singleton { + + + private Singleton() { + } + + private static volatile Singleton singleton = null; + + public static Singleton getInstance() { + if (singleton == null) { + synchronized (Singleton.class) { + if (singleton == null) { + singleton = new Singleton(); + } + } + } + return singleton; + } + + +} diff --git a/src/main/test/com/chen/test/factory/Main.java b/src/main/test/com/chen/test/factory/Main.java new file mode 100644 index 0000000..b46a5d5 --- /dev/null +++ b/src/main/test/com/chen/test/factory/Main.java @@ -0,0 +1,8 @@ +package com.chen.test.factory; + +/** + * @author : chen weijie + * @Date: 2019-11-14 23:20 + */ +public class Main { +} diff --git a/src/main/test/com/chen/test/factory/continar/BMW320.java b/src/main/test/com/chen/test/factory/continar/BMW320.java new file mode 100644 index 0000000..741e5a6 --- /dev/null +++ b/src/main/test/com/chen/test/factory/continar/BMW320.java @@ -0,0 +1,22 @@ +package com.chen.test.factory.continar; + +/** + * @author : chen weijie + * @Date: 2019-11-15 00:01 + */ +public class BMW320 implements BMWFactory { + + @Override + public Container getContainer() { + ContainerA containerA = new ContainerA(); + containerA.printContainerName(); + return containerA; + } + + @Override + public Engine getEngine() { + EngineA engineA = new EngineA(); + engineA.printEngineName(); + return engineA; + } +} diff --git a/src/main/test/com/chen/test/factory/continar/BMW520.java b/src/main/test/com/chen/test/factory/continar/BMW520.java new file mode 100644 index 0000000..f9dee51 --- /dev/null +++ b/src/main/test/com/chen/test/factory/continar/BMW520.java @@ -0,0 +1,18 @@ +package com.chen.test.factory.continar; + +/** + * @author : chen weijie + * @Date: 2019-11-15 00:02 + */ +public class BMW520 implements BMWFactory { + + @Override + public Container getContainer() { + return new ContainerB(); + } + + @Override + public Engine getEngine() { + return new EngineB(); + } +} diff --git a/src/main/test/com/chen/test/factory/continar/BMWFactory.java b/src/main/test/com/chen/test/factory/continar/BMWFactory.java new file mode 100644 index 0000000..a7e8153 --- /dev/null +++ b/src/main/test/com/chen/test/factory/continar/BMWFactory.java @@ -0,0 +1,14 @@ +package com.chen.test.factory.continar; + +/** + * @author : chen weijie + * @Date: 2019-11-15 00:00 + */ +public interface BMWFactory { + + + Container getContainer(); + + Engine getEngine(); + +} diff --git a/src/main/test/com/chen/test/factory/continar/Container.java b/src/main/test/com/chen/test/factory/continar/Container.java new file mode 100644 index 0000000..e712ba3 --- /dev/null +++ b/src/main/test/com/chen/test/factory/continar/Container.java @@ -0,0 +1,14 @@ +package com.chen.test.factory.continar; + +/** + * @author : chen weijie + * @Date: 2019-11-14 23:56 + */ +public interface Container { + + + + void printContainerName(); + + +} diff --git a/src/main/test/com/chen/test/factory/continar/ContainerA.java b/src/main/test/com/chen/test/factory/continar/ContainerA.java new file mode 100644 index 0000000..b77c6bd --- /dev/null +++ b/src/main/test/com/chen/test/factory/continar/ContainerA.java @@ -0,0 +1,14 @@ +package com.chen.test.factory.continar; + +/** + * @author : chen weijie + * @Date: 2019-11-14 23:58 + */ +public class ContainerA implements Container { + + @Override + public void printContainerName() { + + System.out.println("i am container a"); + } +} diff --git a/src/main/test/com/chen/test/factory/continar/ContainerB.java b/src/main/test/com/chen/test/factory/continar/ContainerB.java new file mode 100644 index 0000000..c9437d1 --- /dev/null +++ b/src/main/test/com/chen/test/factory/continar/ContainerB.java @@ -0,0 +1,14 @@ +package com.chen.test.factory.continar; + +/** + * @author : chen weijie + * @Date: 2019-11-14 23:58 + */ +public class ContainerB implements Container { + + + @Override + public void printContainerName() { + System.out.println("i am container b"); + } +} diff --git a/src/main/test/com/chen/test/factory/continar/Engine.java b/src/main/test/com/chen/test/factory/continar/Engine.java new file mode 100644 index 0000000..1766b88 --- /dev/null +++ b/src/main/test/com/chen/test/factory/continar/Engine.java @@ -0,0 +1,11 @@ +package com.chen.test.factory.continar; + +/** + * @author : chen weijie + * @Date: 2019-11-14 23:59 + */ +public interface Engine { + + + void printEngineName(); +} diff --git a/src/main/test/com/chen/test/factory/continar/EngineA.java b/src/main/test/com/chen/test/factory/continar/EngineA.java new file mode 100644 index 0000000..a533bf3 --- /dev/null +++ b/src/main/test/com/chen/test/factory/continar/EngineA.java @@ -0,0 +1,13 @@ +package com.chen.test.factory.continar; + +/** + * @author : chen weijie + * @Date: 2019-11-14 23:59 + */ +public class EngineA implements Engine { + + @Override + public void printEngineName() { + System.out.println("EngineA "); + } +} diff --git a/src/main/test/com/chen/test/factory/continar/EngineB.java b/src/main/test/com/chen/test/factory/continar/EngineB.java new file mode 100644 index 0000000..7a8ea91 --- /dev/null +++ b/src/main/test/com/chen/test/factory/continar/EngineB.java @@ -0,0 +1,14 @@ +package com.chen.test.factory.continar; + +/** + * @author : chen weijie + * @Date: 2019-11-15 00:00 + */ +public class EngineB implements Engine { + + + @Override + public void printEngineName() { + System.out.println("EngineB "); + } +} diff --git a/src/main/test/com/chen/test/factory/continar/Main.java b/src/main/test/com/chen/test/factory/continar/Main.java new file mode 100644 index 0000000..bd18316 --- /dev/null +++ b/src/main/test/com/chen/test/factory/continar/Main.java @@ -0,0 +1,23 @@ +package com.chen.test.factory.continar; + +/** + * @author : chen weijie + * @Date: 2019-11-15 00:03 + */ +public class Main { + + public static void main(String[] args) { + + + BMWFactory bmw320Factory = new BMW320(); + bmw320Factory.getContainer(); + bmw320Factory.getEngine(); + + BMWFactory bmw520Factory = new BMW520(); + bmw520Factory.getContainer(); + bmw520Factory.getEngine(); + + + } + +} diff --git a/src/main/test/com/chen/test/factory/factorymethod/BMW.java b/src/main/test/com/chen/test/factory/factorymethod/BMW.java new file mode 100644 index 0000000..ba4fd21 --- /dev/null +++ b/src/main/test/com/chen/test/factory/factorymethod/BMW.java @@ -0,0 +1,11 @@ +package com.chen.test.factory.factorymethod; + +/** + * @author : chen weijie + * @Date: 2019-11-14 23:33 + */ +public interface BMW { + + void say(); + +} diff --git a/src/main/test/com/chen/test/factory/factorymethod/BMW320.java b/src/main/test/com/chen/test/factory/factorymethod/BMW320.java new file mode 100644 index 0000000..f80d303 --- /dev/null +++ b/src/main/test/com/chen/test/factory/factorymethod/BMW320.java @@ -0,0 +1,14 @@ +package com.chen.test.factory.factorymethod; + +/** + * @author : chen weijie + * @Date: 2019-11-14 23:34 + */ +public class BMW320 implements BMW { + + + @Override + public void say() { + System.out.println("im bmw 320"); + } +} diff --git a/src/main/test/com/chen/test/factory/factorymethod/BMW320Factory.java b/src/main/test/com/chen/test/factory/factorymethod/BMW320Factory.java new file mode 100644 index 0000000..79a5156 --- /dev/null +++ b/src/main/test/com/chen/test/factory/factorymethod/BMW320Factory.java @@ -0,0 +1,13 @@ +package com.chen.test.factory.factorymethod; + +/** + * @author : chen weijie + * @Date: 2019-11-14 23:37 + */ +public class BMW320Factory implements BMWFacory { + + @Override + public BMW320 createBMW() { + return new BMW320(); + } +} diff --git a/src/main/test/com/chen/test/factory/factorymethod/BMW520.java b/src/main/test/com/chen/test/factory/factorymethod/BMW520.java new file mode 100644 index 0000000..c9b4829 --- /dev/null +++ b/src/main/test/com/chen/test/factory/factorymethod/BMW520.java @@ -0,0 +1,14 @@ +package com.chen.test.factory.factorymethod; + +/** + * @author : chen weijie + * @Date: 2019-11-14 23:34 + */ +public class BMW520 implements BMW { + + + @Override + public void say() { + System.out.println(" im BMW 520"); + } +} diff --git a/src/main/test/com/chen/test/factory/factorymethod/BMW520Factory.java b/src/main/test/com/chen/test/factory/factorymethod/BMW520Factory.java new file mode 100644 index 0000000..30b9e1a --- /dev/null +++ b/src/main/test/com/chen/test/factory/factorymethod/BMW520Factory.java @@ -0,0 +1,13 @@ +package com.chen.test.factory.factorymethod; + +/** + * @author : chen weijie + * @Date: 2019-11-14 23:37 + */ +public class BMW520Factory implements BMWFacory { + + @Override + public BMW520 createBMW() { + return new BMW520(); + } +} diff --git a/src/main/test/com/chen/test/factory/factorymethod/BMWFacory.java b/src/main/test/com/chen/test/factory/factorymethod/BMWFacory.java new file mode 100644 index 0000000..1ecb4c3 --- /dev/null +++ b/src/main/test/com/chen/test/factory/factorymethod/BMWFacory.java @@ -0,0 +1,13 @@ +package com.chen.test.factory.factorymethod; + +/** + * @author : chen weijie + * @Date: 2019-11-14 23:35 + */ +public interface BMWFacory { + + + BMW createBMW(); + + +} diff --git a/src/main/test/com/chen/test/factory/factorymethod/Test.java b/src/main/test/com/chen/test/factory/factorymethod/Test.java new file mode 100644 index 0000000..8176bce --- /dev/null +++ b/src/main/test/com/chen/test/factory/factorymethod/Test.java @@ -0,0 +1,17 @@ +package com.chen.test.factory.factorymethod; + +/** + * @author : chen weijie + * @Date: 2019-11-14 23:39 + */ +public class Test { + + + public static void main(String[] args) { + + BMW320Factory bmw320Factory = new BMW320Factory(); + BMW320 bmw320 = bmw320Factory.createBMW(); + bmw320.say(); + + } +} diff --git a/src/main/test/com/chen/test/factory/staticFactory/EmailSender.java b/src/main/test/com/chen/test/factory/staticFactory/EmailSender.java new file mode 100644 index 0000000..4c6d5ec --- /dev/null +++ b/src/main/test/com/chen/test/factory/staticFactory/EmailSender.java @@ -0,0 +1,14 @@ +package com.chen.test.factory.staticFactory; + +/** + * @author : chen weijie + * @Date: 2019-11-14 23:21 + */ +public class EmailSender implements Sender { + + @Override + public void send() { + + System.out.println("email sender"); + } +} diff --git a/src/main/test/com/chen/test/factory/staticFactory/Main.java b/src/main/test/com/chen/test/factory/staticFactory/Main.java new file mode 100644 index 0000000..bb8b5d6 --- /dev/null +++ b/src/main/test/com/chen/test/factory/staticFactory/Main.java @@ -0,0 +1,18 @@ +package com.chen.test.factory.staticFactory; + +/** + * @author : chen weijie + * @Date: 2019-11-14 23:23 + */ +public class Main { + + + public static void main(String[] args) { + + Sender emailSender = SendFactory.getEmailSender(); + + emailSender.send(); + + + } +} diff --git a/src/main/test/com/chen/test/factory/staticFactory/SendFactory.java b/src/main/test/com/chen/test/factory/staticFactory/SendFactory.java new file mode 100644 index 0000000..890f774 --- /dev/null +++ b/src/main/test/com/chen/test/factory/staticFactory/SendFactory.java @@ -0,0 +1,20 @@ +package com.chen.test.factory.staticFactory; + +/** + * @author : chen weijie + * @Date: 2019-11-14 23:22 + */ +public class SendFactory { + + + public static EmailSender getEmailSender(){ + return new EmailSender(); + } + + + public static SmsSender getSmsSender(){ + return new SmsSender(); + } + + +} diff --git a/src/main/test/com/chen/test/factory/staticFactory/Sender.java b/src/main/test/com/chen/test/factory/staticFactory/Sender.java new file mode 100644 index 0000000..d2478ec --- /dev/null +++ b/src/main/test/com/chen/test/factory/staticFactory/Sender.java @@ -0,0 +1,10 @@ +package com.chen.test.factory.staticFactory; + +/** + * @author : chen weijie + * @Date: 2019-11-14 23:21 + */ +public interface Sender { + + void send(); +} diff --git a/src/main/test/com/chen/test/factory/staticFactory/SmsSender.java b/src/main/test/com/chen/test/factory/staticFactory/SmsSender.java new file mode 100644 index 0000000..f8adef2 --- /dev/null +++ b/src/main/test/com/chen/test/factory/staticFactory/SmsSender.java @@ -0,0 +1,15 @@ +package com.chen.test.factory.staticFactory; + +/** + * @author : chen weijie + * @Date: 2019-11-14 23:22 + */ +public class SmsSender implements Sender { + + + @Override + public void send() { + + System.out.println("sms sender"); + } +} diff --git a/src/main/test/com/chen/test/factoryMethod/BMW.java b/src/main/test/com/chen/test/factoryMethod/BMW.java new file mode 100644 index 0000000..caa3453 --- /dev/null +++ b/src/main/test/com/chen/test/factoryMethod/BMW.java @@ -0,0 +1,11 @@ +package com.chen.test.factoryMethod; + +/** + * @author : chen weijie + * @Date: 2020-04-21 01:01 + */ +public interface BMW { + + void buildBMW(); + +} diff --git a/src/main/test/com/chen/test/factoryMethod/BMW320.java b/src/main/test/com/chen/test/factoryMethod/BMW320.java new file mode 100644 index 0000000..a51dbbc --- /dev/null +++ b/src/main/test/com/chen/test/factoryMethod/BMW320.java @@ -0,0 +1,20 @@ +package com.chen.test.factoryMethod; + +/** + * @author : chen weijie + * @Date: 2020-04-21 01:01 + */ +public class BMW320 implements BMW { + + private String bmwName; + + public BMW320(String bmwName) { + this.bmwName = bmwName; + } + + + @Override + public void buildBMW() { + System.out.println("build:" + this.bmwName); + } +} diff --git a/src/main/test/com/chen/test/factoryMethod/BMW320Factory.java b/src/main/test/com/chen/test/factoryMethod/BMW320Factory.java new file mode 100644 index 0000000..db2fce8 --- /dev/null +++ b/src/main/test/com/chen/test/factoryMethod/BMW320Factory.java @@ -0,0 +1,13 @@ +package com.chen.test.factoryMethod; + +/** + * @author : chen weijie + * @Date: 2020-04-21 01:06 + */ +public class BMW320Factory implements BMWFactory { + + @Override + public BMW buildBMW() { + return new BMW320("320"); + } +} diff --git a/src/main/test/com/chen/test/factoryMethod/BMW520.java b/src/main/test/com/chen/test/factoryMethod/BMW520.java new file mode 100644 index 0000000..33c23b8 --- /dev/null +++ b/src/main/test/com/chen/test/factoryMethod/BMW520.java @@ -0,0 +1,19 @@ +package com.chen.test.factoryMethod; + +/** + * @author : chen weijie + * @Date: 2020-04-21 01:03 + */ +public class BMW520 implements BMW { + + private String name; + + public BMW520(String name) { + this.name = name; + } + + @Override + public void buildBMW() { + System.out.println("build BMW :" + name); + } +} diff --git a/src/main/test/com/chen/test/factoryMethod/BMW520Factory.java b/src/main/test/com/chen/test/factoryMethod/BMW520Factory.java new file mode 100644 index 0000000..d19de2e --- /dev/null +++ b/src/main/test/com/chen/test/factoryMethod/BMW520Factory.java @@ -0,0 +1,14 @@ +package com.chen.test.factoryMethod; + +/** + * @author : chen weijie + * @Date: 2020-04-21 01:05 + */ +public class BMW520Factory implements BMWFactory { + + + @Override + public BMW buildBMW() { + return new BMW320("bmw520"); + } +} diff --git a/src/main/test/com/chen/test/factoryMethod/BMWFactory.java b/src/main/test/com/chen/test/factoryMethod/BMWFactory.java new file mode 100644 index 0000000..09e1f7e --- /dev/null +++ b/src/main/test/com/chen/test/factoryMethod/BMWFactory.java @@ -0,0 +1,12 @@ +package com.chen.test.factoryMethod; + +/** + * @author : chen weijie + * @Date: 2020-04-21 01:04 + */ +public interface BMWFactory { + + + BMW buildBMW(); + +} diff --git a/src/main/test/com/chen/test/factoryMethod/Test.java b/src/main/test/com/chen/test/factoryMethod/Test.java new file mode 100644 index 0000000..c53aa9b --- /dev/null +++ b/src/main/test/com/chen/test/factoryMethod/Test.java @@ -0,0 +1,19 @@ +package com.chen.test.factoryMethod; + +/** + * @author : chen weijie + * @Date: 2020-04-21 01:06 + */ +public class Test { + + public static void main(String[] args) { + + BMWFactory bmwFactory = new BMW320Factory(); + BMW bmw320 = bmwFactory.buildBMW(); + bmw320.buildBMW(); + + BMWFactory bmwFactory2 = new BMW520Factory(); + BMW bmw520 = bmwFactory2.buildBMW(); + bmw520.buildBMW(); + } +} diff --git a/src/main/test/com/chen/test/modelPattern/Bus.java b/src/main/test/com/chen/test/modelPattern/Bus.java new file mode 100644 index 0000000..18875ef --- /dev/null +++ b/src/main/test/com/chen/test/modelPattern/Bus.java @@ -0,0 +1,22 @@ +package com.chen.test.modelPattern; + +/** + * @author : chen weijie + * @Date: 2020-04-21 01:50 + */ +public class Bus extends Station { + @Override + void safetyCheck() { + System.out.println("bus safetyCheck"); + } + + @Override + void ticketCheck() { + System.out.println("bus ticketCheck"); + } + + @Override + void cabageCheck() { + System.out.println("bus cabageCheck"); + } +} diff --git a/src/main/test/com/chen/test/modelPattern/Station.java b/src/main/test/com/chen/test/modelPattern/Station.java new file mode 100644 index 0000000..fd6147c --- /dev/null +++ b/src/main/test/com/chen/test/modelPattern/Station.java @@ -0,0 +1,25 @@ +package com.chen.test.modelPattern; + +/** + * @author : chen weijie + * @Date: 2020-04-21 01:47 + */ +public abstract class Station { + + + abstract void safetyCheck(); + + abstract void ticketCheck(); + + + abstract void cabageCheck(); + + public void play() { + + safetyCheck(); + ticketCheck(); + cabageCheck(); + } + + +} diff --git a/src/main/test/com/chen/test/modelPattern/Subway.java b/src/main/test/com/chen/test/modelPattern/Subway.java new file mode 100644 index 0000000..c884185 --- /dev/null +++ b/src/main/test/com/chen/test/modelPattern/Subway.java @@ -0,0 +1,23 @@ +package com.chen.test.modelPattern; + +/** + * @author : chen weijie + * @Date: 2020-04-21 01:51 + */ +public class Subway extends Station { + + @Override + void safetyCheck() { + System.out.println("Subway safetyCheck"); + } + + @Override + void ticketCheck() { + System.out.println("Subway ticketCheck"); + } + + @Override + void cabageCheck() { + System.out.println("Subway cabageCheck"); + } +} diff --git a/src/main/test/com/chen/test/modelPattern/Test.java b/src/main/test/com/chen/test/modelPattern/Test.java new file mode 100644 index 0000000..22d7f82 --- /dev/null +++ b/src/main/test/com/chen/test/modelPattern/Test.java @@ -0,0 +1,19 @@ +package com.chen.test.modelPattern; + +/** + * @author : chen weijie + * @Date: 2020-04-21 01:51 + */ +public class Test { + + public static void main(String[] args) { + + Station subway = new Subway(); + subway.play(); + + Station bus = new Bus(); + bus.play(); + + } + +} diff --git a/src/main/test/com/chen/test/proxy/Proxy.java b/src/main/test/com/chen/test/proxy/Proxy.java new file mode 100644 index 0000000..1b51776 --- /dev/null +++ b/src/main/test/com/chen/test/proxy/Proxy.java @@ -0,0 +1,22 @@ +package com.chen.test.proxy; + +/** + * @author : chen weijie + * @Date: 2019-11-15 17:40 + */ +public class Proxy implements Subject { + + + private Subject subject; + + public Proxy(Subject subject) { + this.subject = subject; + } + + + @Override + public void request() { + subject.request(); + } + +} diff --git a/src/main/test/com/chen/test/proxy/RealSubject.java b/src/main/test/com/chen/test/proxy/RealSubject.java new file mode 100644 index 0000000..6c95a99 --- /dev/null +++ b/src/main/test/com/chen/test/proxy/RealSubject.java @@ -0,0 +1,15 @@ +package com.chen.test.proxy; + +/** + * @author : chen weijie + * @Date: 2019-11-15 17:40 + */ +public class RealSubject implements Subject { + + + @Override + public void request() { + + System.out.println("real subject request"); + } +} diff --git a/src/main/test/com/chen/test/proxy/Subject.java b/src/main/test/com/chen/test/proxy/Subject.java new file mode 100644 index 0000000..87abee3 --- /dev/null +++ b/src/main/test/com/chen/test/proxy/Subject.java @@ -0,0 +1,12 @@ +package com.chen.test.proxy; + +/** + * @author : chen weijie + * @Date: 2019-11-15 17:39 + */ +public interface Subject { + + + void request(); + +} diff --git a/src/main/test/com/chen/test/proxy/Test.java b/src/main/test/com/chen/test/proxy/Test.java new file mode 100644 index 0000000..a245d3d --- /dev/null +++ b/src/main/test/com/chen/test/proxy/Test.java @@ -0,0 +1,21 @@ +package com.chen.test.proxy; + +/** + * @author : chen weijie + * @Date: 2019-11-15 17:42 + */ +public class Test { + + + public static void main(String[] args) { + + + Subject realSubject = new RealSubject(); + + Proxy proxy = new Proxy(realSubject); + + proxy.request(); + + + } +} diff --git a/src/main/test/com/chen/test/proxy/dynaticProxy/People.java b/src/main/test/com/chen/test/proxy/dynaticProxy/People.java new file mode 100644 index 0000000..40b7d46 --- /dev/null +++ b/src/main/test/com/chen/test/proxy/dynaticProxy/People.java @@ -0,0 +1,12 @@ +package com.chen.test.proxy.dynaticProxy; + +/** + * @author : chen weijie + * @Date: 2019-11-15 17:57 + */ +public interface People { + + + void work(); + +} diff --git a/src/main/test/com/chen/test/proxy/dynaticProxy/ProxyHandler.java b/src/main/test/com/chen/test/proxy/dynaticProxy/ProxyHandler.java new file mode 100644 index 0000000..980ff3a --- /dev/null +++ b/src/main/test/com/chen/test/proxy/dynaticProxy/ProxyHandler.java @@ -0,0 +1,26 @@ +package com.chen.test.proxy.dynaticProxy; + +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.Method; + +/** + * @author : chen weijie + * @Date: 2019-11-15 18:02 + */ +public class ProxyHandler implements InvocationHandler { + + + private T object; + + ProxyHandler(T object) { + this.object = object; + } + + @Override + public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { + System.out.println("invoke before"); + Object result = method.invoke(object, args); + System.out.println("invoke after"); + return result; + } +} diff --git a/src/main/test/com/chen/test/proxy/dynaticProxy/Teacher.java b/src/main/test/com/chen/test/proxy/dynaticProxy/Teacher.java new file mode 100644 index 0000000..00418ff --- /dev/null +++ b/src/main/test/com/chen/test/proxy/dynaticProxy/Teacher.java @@ -0,0 +1,13 @@ +package com.chen.test.proxy.dynaticProxy; + +/** + * @author : chen weijie + * @Date: 2019-11-15 18:01 + */ +public class Teacher implements People { + + @Override + public void work() { + System.out.println(" teacher work!"); + } +} diff --git a/src/main/test/com/chen/test/proxy/dynaticProxy/Test.java b/src/main/test/com/chen/test/proxy/dynaticProxy/Test.java new file mode 100644 index 0000000..1117c09 --- /dev/null +++ b/src/main/test/com/chen/test/proxy/dynaticProxy/Test.java @@ -0,0 +1,22 @@ +package com.chen.test.proxy.dynaticProxy; + +import java.lang.reflect.Proxy; + +/** + * @author : chen weijie + * @Date: 2019-11-15 18:06 + */ +public class Test { + + public static void main(String[] args) { + + + People teacher = new Teacher(); + ProxyHandler proxyHandler = new ProxyHandler(teacher); + People proxyPeople = (People) Proxy.newProxyInstance(teacher.getClass().getClassLoader(), teacher.getClass().getInterfaces(), proxyHandler); + proxyPeople.work(); + + } + + +} diff --git a/src/main/test/com/chen/test/sort/QuickSort.java b/src/main/test/com/chen/test/sort/QuickSort.java new file mode 100644 index 0000000..1641d6c --- /dev/null +++ b/src/main/test/com/chen/test/sort/QuickSort.java @@ -0,0 +1,55 @@ +package com.chen.test.sort; + +import org.junit.Test; + +/** + * @author : chen weijie + * @Date: 2020-05-25 10:43 + */ +public class QuickSort { + + + @Test + public void quickSort() { + + int[] nums = {3, 7, 2, 10, -1, 4}; + sort(nums, 0, nums.length - 1); + for (int num : nums) { + System.out.println(num); + } + } + + + public void sort(int[] array, int low, int high) { + + if (high > low) { + int pivot = quickSort(array, low, high); + sort(array, low, pivot-1); + sort(array, pivot + 1, high); + } + + } + + + public int quickSort(int[] array, int low, int high) { + + 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; + } + + +} diff --git a/src/main/test/com/chen/test/staticFactory/MailSender.java b/src/main/test/com/chen/test/staticFactory/MailSender.java new file mode 100644 index 0000000..ca590d7 --- /dev/null +++ b/src/main/test/com/chen/test/staticFactory/MailSender.java @@ -0,0 +1,13 @@ +package com.chen.test.staticFactory; + +/** + * @author : chen weijie + * @Date: 2020-04-21 00:54 + */ +public class MailSender implements Sender { + + @Override + public void send() { + System.out.println("mail sender"); + } +} diff --git a/src/main/test/com/chen/test/staticFactory/SendFactory.java b/src/main/test/com/chen/test/staticFactory/SendFactory.java new file mode 100644 index 0000000..16095bb --- /dev/null +++ b/src/main/test/com/chen/test/staticFactory/SendFactory.java @@ -0,0 +1,19 @@ +package com.chen.test.staticFactory; + +/** + * @author : chen weijie + * @Date: 2020-04-21 00:55 + */ +public class SendFactory { + + + public static Sender getMailSender() { + return new MailSender(); + } + + public static SmsSender getSmsSender() { + return new SmsSender(); + } + + +} diff --git a/src/main/test/com/chen/test/staticFactory/Sender.java b/src/main/test/com/chen/test/staticFactory/Sender.java new file mode 100644 index 0000000..9541017 --- /dev/null +++ b/src/main/test/com/chen/test/staticFactory/Sender.java @@ -0,0 +1,10 @@ +package com.chen.test.staticFactory; + +/** + * @author : chen weijie + * @Date: 2020-04-21 00:53 + */ +public interface Sender { + + void send(); +} diff --git a/src/main/test/com/chen/test/staticFactory/SmsSender.java b/src/main/test/com/chen/test/staticFactory/SmsSender.java new file mode 100644 index 0000000..36f2ba5 --- /dev/null +++ b/src/main/test/com/chen/test/staticFactory/SmsSender.java @@ -0,0 +1,14 @@ +package com.chen.test.staticFactory; + +/** + * @author : chen weijie + * @Date: 2020-04-21 00:54 + */ +public class SmsSender implements Sender { + + @Override + public void send() { + + System.out.println("SmsSender send"); + } +} diff --git a/src/main/test/com/chen/test/staticFactory/Test.java b/src/main/test/com/chen/test/staticFactory/Test.java new file mode 100644 index 0000000..00cafc4 --- /dev/null +++ b/src/main/test/com/chen/test/staticFactory/Test.java @@ -0,0 +1,19 @@ +package com.chen.test.staticFactory; + +/** + * @author : chen weijie + * @Date: 2020-04-21 00:56 + */ +public class Test { + + public static void main(String[] args) { + + Sender mailSender = SendFactory.getMailSender(); + mailSender.send(); + + Sender smsSender = SendFactory.getSmsSender(); + smsSender.send(); + + + } +} diff --git a/src/main/test/com/chen/test/strategy/HignPrice.java b/src/main/test/com/chen/test/strategy/HignPrice.java new file mode 100644 index 0000000..b39fd3a --- /dev/null +++ b/src/main/test/com/chen/test/strategy/HignPrice.java @@ -0,0 +1,14 @@ +package com.chen.test.strategy; + +/** + * @author : chen weijie + * @Date: 2020-04-21 00:36 + */ +public class HignPrice implements Price { + + + @Override + public double calcPrice(Integer p) { + return p * 0.75; + } +} diff --git a/src/main/test/com/chen/test/strategy/LowPrice.java b/src/main/test/com/chen/test/strategy/LowPrice.java new file mode 100644 index 0000000..6d90eaf --- /dev/null +++ b/src/main/test/com/chen/test/strategy/LowPrice.java @@ -0,0 +1,12 @@ +package com.chen.test.strategy; + +/** + * @author : chen weijie + * @Date: 2020-04-21 00:38 + */ +public class LowPrice implements Price { + @Override + public double calcPrice(Integer p) { + return 0.2 * p; + } +} diff --git a/src/main/test/com/chen/test/strategy/Market.java b/src/main/test/com/chen/test/strategy/Market.java new file mode 100644 index 0000000..6248989 --- /dev/null +++ b/src/main/test/com/chen/test/strategy/Market.java @@ -0,0 +1,27 @@ +package com.chen.test.strategy; + +/** + * @author : chen weijie + * @Date: 2020-04-21 00:39 + */ +public class Market { + + private Price price; + + public Market(Price price) { + this.price = price; + } + + + /** + * 计算价格 + * + * @param value + * @return + */ + public double cacul(Integer value) { + return price.calcPrice(value); + + } + +} diff --git a/src/main/test/com/chen/test/strategy/MiddlePrice.java b/src/main/test/com/chen/test/strategy/MiddlePrice.java new file mode 100644 index 0000000..256b3c5 --- /dev/null +++ b/src/main/test/com/chen/test/strategy/MiddlePrice.java @@ -0,0 +1,13 @@ +package com.chen.test.strategy; + +/** + * @author : chen weijie + * @Date: 2020-04-21 00:37 + */ +public class MiddlePrice implements Price { + + @Override + public double calcPrice(Integer p) { + return 0.5 * p; + } +} diff --git a/src/main/test/com/chen/test/strategy/Price.java b/src/main/test/com/chen/test/strategy/Price.java new file mode 100644 index 0000000..3364968 --- /dev/null +++ b/src/main/test/com/chen/test/strategy/Price.java @@ -0,0 +1,10 @@ +package com.chen.test.strategy; + +/** + * @author : chen weijie + * @Date: 2020-04-21 00:36 + */ +public interface Price { + + double calcPrice(Integer p); +} diff --git a/src/main/test/com/chen/test/strategy/Test.java b/src/main/test/com/chen/test/strategy/Test.java new file mode 100644 index 0000000..49d505f --- /dev/null +++ b/src/main/test/com/chen/test/strategy/Test.java @@ -0,0 +1,20 @@ +package com.chen.test.strategy; + +/** + * @author : chen weijie + * @Date: 2020-04-21 00:39 + */ +public class Test { + + public static void main(String[] args) { + + + Market market = new Market(new HignPrice()); + + double d = market.cacul(100); + + System.out.println(d); + + + } +} diff --git a/src/main/test/com/chen/test/thread/MyRunnable.java b/src/main/test/com/chen/test/thread/MyRunnable.java new file mode 100644 index 0000000..844130d --- /dev/null +++ b/src/main/test/com/chen/test/thread/MyRunnable.java @@ -0,0 +1,14 @@ +package com.chen.test.thread; + +/** + * @author : chen weijie + * @Date: 2020-04-06 17:45 + */ +public class MyRunnable implements Runnable { + + + @Override + public void run() { + + } +}