+ * 思路:使用两个变量 一个valley表示当天天数中最低价,
+ * 一个peek表示当前所有的天数中的最高价
+ * 因为我们可以买卖股票且是不用付手续费的,也就是我们可以卖了这一只股票,然后再把它买回来
+ * 所以上面示例2中,5-1和 (2-1)+(3-2)+(4-3)+(5-4)的效果是一样的,所以顶峰就找递增的,底就找递减的
+ */
+public class _122_BestTimeToBuyAndSellStock2 {
+ public int maxProfit(int[] prices) {
+ if (prices == null || prices.length == 0)
+ return 0;
+
+ int valley = prices[0], peek = prices[0];
+ int i = 0;
+ int maxProfit = 0;
+
+ while (i < prices.length - 1) {
+ while (i < prices.length - 1 && prices[i] >= prices[i + 1])
+ i++;
+ valley = prices[i];
+
+ while (i < prices.length - 1 && prices[i] <= prices[i + 1])
+ i++;
+ peek = prices[i];
+ maxProfit += peek - valley;
+ }
+ return maxProfit;
+ }
+}
\ No newline at end of file
diff --git a/java-note-algorithm/src/main/java/com/leosanqing/leetcode/easy/_136_singleNum.java b/java-note-algorithm/src/main/java/com/leosanqing/leetcode/easy/_136_singleNum.java
new file mode 100644
index 0000000..858ad1e
--- /dev/null
+++ b/java-note-algorithm/src/main/java/com/leosanqing/leetcode/easy/_136_singleNum.java
@@ -0,0 +1,33 @@
+package com.leosanqing.leetcode.easy;
+
+/**
+ * 描述:
+ * ` Given a non-empty array of integers, every element appears twice except for one. Find that single one.
+ * ` 给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现两次。找出那个只出现了一次的元素。
+ * ` 说明:
+ * ` 你的算法应该具有线性时间复杂度。 你可以不使用额外空间来实现吗?
+ * ` 输入: [4,1,2,1,2]
+ * ` 输出: 4
+ * `
+ * `
+ * ` 思路:使用异或运算:
+ * ` 异或运算有三个特征:
+ * ` 1、0 ^ 任何数都为 那个数 0^a = a;
+ * ` 2、两个相同的数异或结果为 0 a^a = 0;
+ * ` 3、异或具有交换律 a^b^c = a^c^b
+ */
+public class _136_singleNum {
+ public static void main(String[] args) {
+ int[] nums = {4, 2, 1, 2, 1};
+ System.out.println("singleNum(nums) = " + singleNum(nums));
+
+ }
+
+ public static int singleNum(int[] nums) {
+ int result = 0;
+ for (int num : nums) {
+ result ^= num;
+ }
+ return result;
+ }
+}
diff --git a/java-note-algorithm/src/main/java/com/leosanqing/leetcode/easy/_202_happyNumber.java b/java-note-algorithm/src/main/java/com/leosanqing/leetcode/easy/_202_happyNumber.java
new file mode 100644
index 0000000..54e38af
--- /dev/null
+++ b/java-note-algorithm/src/main/java/com/leosanqing/leetcode/easy/_202_happyNumber.java
@@ -0,0 +1,67 @@
+package com.leosanqing.leetcode.easy;
+
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * @Author: leosanqing
+ * @Date: 2020/4/15 上午10:17
+ * @Package: easy
+ * @Description: leetCode 202题
+ *
+ * ` A happy number is a number defined by the following process:
+ * ` Starting with any positive integer, replace the number by the sum of the squares of
+ * ` its digits,
+ * ` and repeat the process until the number equals 1 (where it will stay),
+ * ` or it loops endlessly in a cycle which does not include 1.
+ * ` Those numbers for which this process ends in 1 are happy numbers.
+ * `
+ * ` Input: 19
+ * ` Output: true
+ * ` Explanation:
+ * ` 1² + 9² = 82
+ * ` 8² + 2² = 68
+ * ` 6² + 8² = 100
+ * ` 1² + 0² + 0² = 1
+ * ` @Version: v1
+ * `
+ * `
+ * ` 思路:
+ * ` 我们看到最后,其实可以猜出来,只有最终变成一位数才有可能达到他的预期,
+ * ` 如果有两位数或者以上,我们肯定是要对他再一次进行运算的,所以我们就一直往下拆数字就行,
+ * ` 但是这里还有个坑,我们怎么让他不会陷入死循环呢?我们要判断他之前是否运算过,因为如果运算过,就会陷入死循环
+ * ` 我们使用 HashSet ,来判断,如果有值,那么这个肯定之前就运算过,就会陷入死循环。不可能是我们想要的 HappyNum
+ */
+public class _202_happyNumber {
+ public static void main(String[] args) {
+
+ _202_happyNumber happyNumber = new _202_happyNumber();
+ for (int i = 0; i < 10000; i++) {
+ happyNumber.isHappy(i);
+ }
+ }
+
+ public boolean isHappy(int n) {
+ int row = n;
+ Set set = new HashSet<>();
+
+ while (n > 1) {
+ int m = 0;
+ // 计算每位的平方的和
+ while (n > 0) {
+ m = m + (n % 10) * (n % 10);
+ n /= 10;
+ }
+ // 之前运算过,不可能是HappyNum,不跳出去就会陷入死循环
+ if (set.contains(m)) {
+ return false;
+ }
+ set.add(m);
+
+ n = m;
+ }
+ System.out.println(row);
+ return true;
+
+ }
+}
diff --git a/java-note-algorithm/src/main/java/com/leosanqing/leetcode/easy/_203_removeLinkedListElements.java b/java-note-algorithm/src/main/java/com/leosanqing/leetcode/easy/_203_removeLinkedListElements.java
new file mode 100644
index 0000000..096a8ff
--- /dev/null
+++ b/java-note-algorithm/src/main/java/com/leosanqing/leetcode/easy/_203_removeLinkedListElements.java
@@ -0,0 +1,51 @@
+package com.leosanqing.leetcode.easy;
+
+import com.leosanqing.leetcode.medium.list.ListNode;
+
+/**
+ * @Author: rtliu
+ * @Date: 2020/6/1 下午2:11
+ * @Package: easy
+ * @Description: Remove all elements from a linked list of integers that have value val.
+ * 删除链表中与指定值相同的节点
+ *
+ * 204. Count Primes
+ * Des:
+ * Count the number of prime numbers less than a non-negative number, n.
+ *
+ * Example:
+ *
+ * Input: 10
+ * Output: 4
+ * Explanation: There are 4 prime numbers less than 10, they are 2, 3, 5, 7.
+ */
+public class _204_countPrimes {
+ public static void main(String[] args) {
+// System.out.println(new _204_countPrimes().countPrimes(499979));
+ int num = 49997;
+ System.out.println((new _204_countPrimes().countPrimes(num)) == new _204_countPrimes().countPrimesFast(num));
+// System.out.println(new _204_countPrimes().countPrimesFast(499979));
+ }
+//
+
+ /**
+ * 效率太低 O(n²)
+ *
+ * @param n
+ * @return
+ */
+ public int countPrimes(int n) {
+ if (n <= 2) {
+ return 0;
+ }
+
+ if (n == 3) {
+ return 1;
+ }
+
+ boolean flag = false;
+ int num = 2;
+ for (int i = 3; i < n; i++) {
+ flag = false;
+
+ for (int j = 2; j <= i / 2; j++) {
+ if (i % j == 0) {
+ break;
+ }
+ if (j == i / 2) {
+ flag = true;
+ break;
+ }
+ }
+
+ if (flag) {
+ num++;
+ }
+
+ }
+ return num;
+ }
+
+ /**
+ * O(n·log(log(n)))
+ * 我们设置一个 bool 型的 数组,长度为 我们要输入的长度
+ * 从
+ *
+ * @param n
+ * @return
+ */
+ public int countPrimesFast(int n) {
+ boolean[] notPrime = new boolean[n];
+ int count = 0;
+ for (int i = 2; i < n; i++) {
+ if (!notPrime[i]) {
+ count++;
+ for (int j = 2; i * j < n; j++) {
+ notPrime[i * j] = true;
+ }
+ }
+ }
+
+ return count;
+ }
+}
diff --git a/java-note-algorithm/src/main/java/com/leosanqing/leetcode/easy/_205_isomorphicStrings.java b/java-note-algorithm/src/main/java/com/leosanqing/leetcode/easy/_205_isomorphicStrings.java
new file mode 100644
index 0000000..d2b865e
--- /dev/null
+++ b/java-note-algorithm/src/main/java/com/leosanqing/leetcode/easy/_205_isomorphicStrings.java
@@ -0,0 +1,121 @@
+package com.leosanqing.leetcode.easy;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * @Author: rtliu
+ * @Date: 2020/6/1 下午4:14
+ * @Package: com.leosanqing.leetcode.easy
+ * @Description: Given two strings s and t, determine if they are isomorphic.
+ * Two strings are isomorphic if the characters in s can be replaced to get t.
+ * All occurrences of a character must be replaced with another character while preserving the order of characters.
+ * No two characters may map to the same character but a character may map to itself.
+ *
+ * Example 2:
+ * Input: ["dog","racecar","car"]
+ * Output: ""
+ * Explanation:
+ * There is no common prefix among the input strings.
+ * @Version: 1.0
+ */
+public class _14_longestCommonPrefix {
+ // public static void main(String[] args) {
+// BigInteger bigDecimal = BigInteger.valueOf(Math.pow(2, 478));
+// System.out.println(bigDecimal);
+// }
+
+
+ public static void main(String[] args) {
+ String[] strings = new String[]{"aa", "a"};
+
+ System.out.println(longestCommonPrefix(strings));
+ }
+
+ public static String longestCommonPrefix(String[] strs) {
+ if (strs == null || strs.length == 0) {
+ return "";
+ }
+
+ String pre = strs[0];
+ for (int i = 1; i < strs.length; i++) {
+ // 每次减去一个字符,找最长的公共前缀
+ while (strs[i].indexOf(pre) != 0) {
+ pre = pre.substring(0, pre.length() - 1);
+ }
+ }
+
+ return pre;
+ }
+
+
+}
diff --git a/java-note-algorithm/src/main/java/com/leosanqing/leetcode/easy/array/_1_twoSum.java b/java-note-algorithm/src/main/java/com/leosanqing/leetcode/easy/array/_1_twoSum.java
new file mode 100644
index 0000000..cac3cbe
--- /dev/null
+++ b/java-note-algorithm/src/main/java/com/leosanqing/leetcode/easy/array/_1_twoSum.java
@@ -0,0 +1,36 @@
+package com.leosanqing.leetcode.easy.array;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * description:Given an array of integers, return indices of the two numbers such that they add up to a specific target.
+ * You may assume that each input would have exactly one solution, and you may not use the same element twice.
+ * 给你一个数组,返回数组两个元素相加等于目标值的元素的下标,返回其中一组解即可。同一个元素不能用两次;
+ *
+ * 如{1,2,5,6,7,2} 目标值 11
+ * 返回{2,3}
+ * solution: 利用HashMap存储元素以及下标,遍历元素,利用hash表,直接锁定另外一个符合条件的下标
+ */
+class _1_twoSum {
+ public static int[] twoSum(int[] nums, int target) {
+ Map map = new HashMap<>();
+ for (int i = 0; i < nums.length; i++) {
+ map.put(nums[i], i);
+ }
+ for (int i = 0; i < nums.length; i++) {
+ if (map.containsKey(target - nums[i])
+ && map.get(target - nums[i]) != i) {
+ return new int[]{i, map.get((target - nums[i]))};
+ }
+
+ }
+ return null;
+ }
+
+ public static void main(String[] args) {
+ int[] a = {1, 2, 5, 6};
+
+ twoSum(a, 7);
+ }
+}
\ No newline at end of file
diff --git a/java-note-algorithm/src/main/java/com/leosanqing/leetcode/easy/array/_26_removeDuplicates.java b/java-note-algorithm/src/main/java/com/leosanqing/leetcode/easy/array/_26_removeDuplicates.java
new file mode 100644
index 0000000..7d67561
--- /dev/null
+++ b/java-note-algorithm/src/main/java/com/leosanqing/leetcode/easy/array/_26_removeDuplicates.java
@@ -0,0 +1,35 @@
+package com.leosanqing.leetcode.easy.array;
+
+/**
+ * 描述:给定一个排序数组,你需要在原地删除重复出现的元素,使得每个元素只出现一次,返回移除后数组的新长度。
+ *
+ * 思路: 把矩阵的第一行和第一列作为标志位,如果该行或者该列有0,那么他就置为0
+ * 然后再遍历,替换
+ */
+class _73_setMatrixZeroes {
+ public void setZeroes(int[][] matrix) {
+ if (matrix == null || matrix.length == 0 || matrix[0].length == 0) {
+ return;
+ }
+
+ int col0 = 1, rows = matrix.length, cols = matrix[0].length;
+
+
+ for (int i = 0; i < rows; i++) {
+ if (matrix[i][0] == 0) {
+ col0 = 0;
+ }
+ for (int j = 0; j < cols; j++) {
+ if (matrix[i][j] == 0) {
+ matrix[i][0] = 0;
+ matrix[0][j] = 0;
+ }
+
+ }
+ }
+
+ // 遍历集合,把他们变成0
+ for (int i = rows - 1; i >= 0; i--) {
+ for (int j = cols - 1; j >= 1; j--) {
+ if (matrix[0][j] == 0 || matrix[i][0] == 0) {
+ matrix[i][j] = 0;
+ }
+ }
+
+ if (col0 == 0) {
+ matrix[i][0] = 0;
+ }
+ }
+ }
+
+
+}
\ No newline at end of file
diff --git a/java-note-algorithm/src/main/java/com/leosanqing/leetcode/medium/array/TaskEvData.java b/java-note-algorithm/src/main/java/com/leosanqing/leetcode/medium/array/TaskEvData.java
new file mode 100644
index 0000000..f0eee3f
--- /dev/null
+++ b/java-note-algorithm/src/main/java/com/leosanqing/leetcode/medium/array/TaskEvData.java
@@ -0,0 +1,31 @@
+package com.leosanqing.leetcode.medium.array;
+
+import lombok.Getter;
+import lombok.Setter;
+
+import java.io.Serializable;
+
+/**
+ * 任务实体
+ * @author zdsys-008
+ */
+@Getter
+@Setter
+public class TaskEvData implements Serializable {
+ /**
+ * 任务状态码:0[过程中]>>1[成功]>>2[失败]
+ */
+ private int status;
+ /**
+ * 任务状态解读:[运行中]>>[运行成功]>>[运行失败]
+ */
+ private String statusMsg;
+ /**
+ * 状态成功时,对应的cosurl
+ */
+ private String url;
+ /**
+ * 截图成功时,对应的存证hash
+ */
+ private String hash;
+}
diff --git a/java-note-algorithm/src/main/java/com/leosanqing/leetcode/medium/array/Test.java b/java-note-algorithm/src/main/java/com/leosanqing/leetcode/medium/array/Test.java
new file mode 100644
index 0000000..3c42628
--- /dev/null
+++ b/java-note-algorithm/src/main/java/com/leosanqing/leetcode/medium/array/Test.java
@@ -0,0 +1,56 @@
+package com.leosanqing.leetcode.medium.array;
+
+import com.alibaba.fastjson.JSONObject;
+
+import java.lang.reflect.Field;
+
+/**
+ * @Author: rtliu
+ * @Date: 2020/7/14 下午4:15
+ * @Package: com.leosanqing.leetcode.medium.array
+ * @Description:
+ * @Version:
+ */
+public class Test {
+
+ /**
+ * 数据处理 >> 暂目前只支持int + String两种类型
+ * @param jsonObject
+ * @param clazz
+ * @param
+ * @return
+ */
+ private static T dataHandle(JSONObject jsonObject, Class clazz, String data) throws ClassNotFoundException, IllegalAccessException, InstantiationException {
+ if (jsonObject != null && jsonObject.containsKey("retCode") && 0 == jsonObject.getInteger("retCode")) {
+ JSONObject dataJson = jsonObject.getJSONObject(data);
+ Field[] fields = Class.forName(clazz.getClass().getName()).getDeclaredFields();
+ T bean = (T) clazz.newInstance();
+ for (int i = 0; i < fields.length; i++){
+ fields[i].setAccessible(true);
+ String fieldName = fields[i].getName();
+ System.out.println(fieldName);
+ if (fields[i].getGenericType() == String.class) {
+ fields[i].set(String.class,dataJson.getString(fieldName));
+ }
+ if (fields[i].getGenericType() == Integer.class) {
+ fields[i].set(int.class,dataJson.getIntValue(fieldName));
+ }
+ }
+ return bean;
+ }
+ return null;
+ }
+
+ public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException {
+ JSONObject jsonObject = new JSONObject();
+ jsonObject.put("retCode",0);
+ JSONObject innerJson = new JSONObject();
+ innerJson.put("status",1);
+ innerJson.put("statusMsg","运行完成");
+ innerJson.put("url","https://www.baidu.com");
+ innerJson.put("hash","UUIDUtil.getUuid()");
+ jsonObject.put("detail",innerJson);
+ TaskEvData task = dataHandle(jsonObject,TaskEvData.class,"detail");
+ System.out.println(task);
+ }
+}
diff --git a/java-note-algorithm/src/main/java/com/leosanqing/leetcode/medium/array/_11_container_with_most_water.java b/java-note-algorithm/src/main/java/com/leosanqing/leetcode/medium/array/_11_container_with_most_water.java
new file mode 100644
index 0000000..801abeb
--- /dev/null
+++ b/java-note-algorithm/src/main/java/com/leosanqing/leetcode/medium/array/_11_container_with_most_water.java
@@ -0,0 +1,52 @@
+package com.leosanqing.leetcode.medium.array;
+
+/**
+ * @Author: rtliu
+ * @Date: 2020/7/3 下午4:44
+ * @Package: com.leosanqing.leetcode.medium.array
+ * @Description: ` Given n non-negative integers a1, a2, ..., an ,
+ * ` where each represents a point at coordinate (i, ai).
+ * ` n vertical lines are drawn such that the two endpoints of line i is at (i, ai) and (i, 0).
+ * ` Find two lines, which together with x-axis forms a container,
+ * ` such that the container contains the most water.
+ *
+ *
+ * ` Note: You may not slant the container and n is at least 2.
+ * ` The above vertical lines are represented by array [1,8,6,2,5,4,8,3,7].
+ * ` In this case, the max area of water (blue section) the container can contain is 49.
+ * `
+ * ` Example:
+ *
+ * ` Input: [1,8,6,2,5,4,8,3,7]
+ * ` Output: 49
+ * @Version: 1.0
+ */
+public class _11_container_with_most_water {
+
+ /**
+ * 这个很简单,也是很经典的问题
+ * 设置两个游标,然后比较两个游标上的容器壁的高度,盛水以矮的为主
+ * 然后移动游标,那边矮就移动哪边
+ *
+ * @param height
+ * @return
+ */
+ public int maxArea(int[] height) {
+ int left = 0;
+ int right = height.length - 1;
+
+ int max = 0;
+ while (left != right) {
+ if (height[left] > height[right]) {
+ max = Math.max(height[right] * (right - left), max);
+ right--;
+ } else {
+ max = Math.max(height[left] * (right - left), max);
+ left++;
+ }
+ }
+ return max;
+ }
+
+
+}
diff --git a/java-note-algorithm/src/main/java/com/leosanqing/leetcode/medium/array/_120_triangle.java b/java-note-algorithm/src/main/java/com/leosanqing/leetcode/medium/array/_120_triangle.java
new file mode 100644
index 0000000..8c837f4
--- /dev/null
+++ b/java-note-algorithm/src/main/java/com/leosanqing/leetcode/medium/array/_120_triangle.java
@@ -0,0 +1,77 @@
+package com.leosanqing.leetcode.medium.array;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * @Author: rtliu
+ * @Date: 2020/8/3 上午9:29
+ * @Package: com.leosanqing.leetcode.medium.list
+ * @Description: 1
+ * ` Given a triangle, find the minimum path sum from top to bottom.
+ * ` Each step you may move to adjacent numbers on the row below.
+ * ` For example, given the following triangle
+ * `
+ * ` 给定一个三角形,找到从上到下的最小路径总和。
+ * ` 您可以将每一步移至下面一行中的相邻数字。
+ * ` 例如,给定以下三角形
+ * ` [
+ * ` [2],
+ * ` [3,4],
+ * ` [6,5,7],
+ * ` [4,1,8,3]
+ * ` ]
+ * ` The minimum path sum from top to bottom is 11 (i.e., 2 + 3 + 5 + 1 = 11).
+ * @Version: 1.0
+ */
+public class _120_triangle {
+ public static void main(String[] args) {
+ int[][] list = {
+ {2},
+ {3, 4},
+ {6, 5, 7},
+ {4, 1, 8, 3}
+ };
+
+ List> lists = new ArrayList<>();
+ lists.add(Arrays.asList(2));
+ lists.add(Arrays.asList(3, 4));
+ lists.add(Arrays.asList(6, 5, 7));
+ lists.add(Arrays.asList(4, 1, 8, 3));
+ System.out.println(minimumTotal(lists));
+ }
+
+ /**
+ * 动态规划
+ * @param triangle
+ * @return
+ */
+ public static int minimumTotal(List> triangle) {
+
+ int[] ints = new int[triangle.size()];
+ int min = Integer.MAX_VALUE;
+ for (List list : triangle) {
+ // 从右到左,如果从左到右,ints[n-1]会被之前的修改覆盖
+ for (int j = list.size() - 1; j >= 0; j--) {
+ if (j == 0) {
+ ints[0] += list.get(0);
+ } else if (j == list.size() - 1) {
+ ints[j] = list.get(j) + ints[j - 1];
+ } else {
+ ints[j] = list.get(j) + Math.min(ints[j - 1], ints[j]);
+ }
+ }
+ }
+ for (int anInt : ints) {
+ if (min > anInt) {
+ min = anInt;
+ }
+ }
+
+ return min;
+
+ }
+
+
+}
diff --git a/java-note-algorithm/src/main/java/com/leosanqing/leetcode/medium/array/_121_best_time_to_buy_and_sell_stock.java b/java-note-algorithm/src/main/java/com/leosanqing/leetcode/medium/array/_121_best_time_to_buy_and_sell_stock.java
new file mode 100644
index 0000000..51c478c
--- /dev/null
+++ b/java-note-algorithm/src/main/java/com/leosanqing/leetcode/medium/array/_121_best_time_to_buy_and_sell_stock.java
@@ -0,0 +1,53 @@
+package com.leosanqing.leetcode.medium.array;
+
+/**
+ * @Author: rtliu
+ * @Date: 2020/8/3 上午10:07
+ * @Package: com.leosanqing.leetcode.medium.list
+ * @Description: `
+ * ` Say you have an array for which the ith element is the price of a given stock on day i.
+ * ` If you were only permitted to complete at most one transaction
+ * ` (i.e., buy one and sell one share of the stock), design an algorithm to find the maximum profit.
+ * ` Note that you cannot sell a stock before you buy one.
+ * `
+ * ` 假设您有一个数组,第i个元素是第i天给定股票的价格。
+ * ` 如果您只被允许最多完成一笔交易
+ * ` (即,买入并卖出一股股票),设计一种算法以找到最大的利润。
+ * ` 请注意,您不能在买股票之前卖出股票。
+ * `
+ * ` Example 1:
+ * ` Input: [7,1,5,3,6,4]
+ * ` Output: 5
+ * ` Explanation:
+ * ` Buy on day 2 (price = 1) and sell on day 5 (price = 6), profit = 6-1 = 5.
+ * ` Not 7-1 = 6, as selling price needs to be larger than buying price.
+ * ` Example 2:
+ * ` Input: [7,6,4,3,1]
+ * ` Output: 0
+ * ` Explanation:
+ * ` In this case, no transaction is done, i.e. max profit = 0.
+ * @Version: 1.0
+ */
+public class _121_best_time_to_buy_and_sell_stock {
+ public static void main(String[] args) {
+ System.out.println(maxProfit(new int[]{7,1,5,3,6,4}));
+ }
+ public static int maxProfit(int[] prices) {
+ if(prices == null || prices.length < 2){
+ return 0;
+ }
+ int buy = prices[0];
+ int profit = 0;
+ for (int i = 1; i < prices.length; i++) {
+ if (buy < prices[i]) {
+ profit = Math.max(prices[i] - buy,profit);
+ } else {
+ buy = prices[i];
+ }
+ }
+
+ return profit;
+ }
+
+
+}
diff --git a/java-note-algorithm/src/main/java/com/leosanqing/leetcode/medium/array/_122_best_time_to_buy_and_sell_stockII.java b/java-note-algorithm/src/main/java/com/leosanqing/leetcode/medium/array/_122_best_time_to_buy_and_sell_stockII.java
new file mode 100644
index 0000000..575dad6
--- /dev/null
+++ b/java-note-algorithm/src/main/java/com/leosanqing/leetcode/medium/array/_122_best_time_to_buy_and_sell_stockII.java
@@ -0,0 +1,61 @@
+package com.leosanqing.leetcode.medium.array;
+
+/**
+ * @Author: rtliu
+ * @Date: 2020/8/3 上午10:23
+ * @Package: com.leosanqing.leetcode.medium.list
+ * @Description: 1
+ * ` Say you have an array prices for which the ith element is the price of a given stock on day i.
+ * ` Design an algorithm to find the maximum profit.
+ * ` You may complete as many transactions as you like
+ * ` (i.e., buy one and sell one share of the stock multiple times).
+ * ` Note: You may not engage in multiple transactions at the same time
+ * ` (i.e., you must sell the stock before you buy again).
+ * ` Example 1:
+ * ` Input: [7,1,5,3,6,4]
+ * ` Output: 7
+ * ` Explanation:
+ * ` Buy on day 2 (price = 1) and sell on day 3 (price = 5), profit = 5-1 = 4.
+ * ` Then buy on day 4 (price = 3) and sell on day 5 (price = 6), profit = 6-3 = 3.
+ * ` Example 2:
+ * ` Input: [1,2,3,4,5]
+ * ` Output: 4
+ * ` Explanation:
+ * ` Buy on day 1 (price = 1) and sell on day 5 (price = 5), profit = 5-1 = 4.
+ * ` Note that you cannot buy on day 1, buy on day 2 and sell them later, as you are
+ * ` engaging multiple transactions at the same time. You must sell before buying again.
+ * ` Example 3:
+ * ` Input: [7,6,4,3,1]
+ * ` Output: 0
+ * ` Explanation: In this case, no transaction is done, i.e. max profit = 0.
+ * @Version: 1.0
+ */
+public class _122_best_time_to_buy_and_sell_stockII {
+ public static void main(String[] args) {
+ int[] ints = {7, 6, 4, 3, 1};
+ maxProfit(ints);
+ }
+
+ public static int maxProfit(int[] prices) {
+ if (prices == null || prices.length < 2) {
+ return 0;
+ }
+ int profit = 0;
+ int buy = prices[0];
+ for (int i = 1; i < prices.length; i++) {
+ // 只要 后面的大于前面的就继续往后,
+ if (prices[i] > prices[i - 1]) {
+ // 如果是最后一个 如[1,2,3,4,5],当他到5的时候,就要卖出了 不然就是0
+ if (i == prices.length - 1) {
+ profit += prices[i] - buy;
+ }
+ continue;
+ }
+ // 不然就 计算前面的利润 如 [1,2,5,3] 当我们 到 3 的时候,我们就要计算 5-1 的利润
+ profit += prices[i - 1] - buy;
+ buy = prices[i];
+ }
+
+ return profit;
+ }
+}
diff --git a/java-note-algorithm/src/main/java/com/leosanqing/leetcode/medium/array/_134_gas_station.java b/java-note-algorithm/src/main/java/com/leosanqing/leetcode/medium/array/_134_gas_station.java
new file mode 100644
index 0000000..333c05f
--- /dev/null
+++ b/java-note-algorithm/src/main/java/com/leosanqing/leetcode/medium/array/_134_gas_station.java
@@ -0,0 +1,99 @@
+package com.leosanqing.leetcode.medium.array;
+
+/**
+ * @Author: rtliu
+ * @Date: 2020/8/4 上午9:38
+ * @Package: com.leosanqing.leetcode.medium.array
+ * @Description: 1
+ * ` There are N gas stations along a circular route,
+ * ` where the amount of gas at station i is gas[i].
+ * ` You have a car with an unlimited gas tank and it costs cost[i] of gas to travel from station i to its
+ * next station (i+1).
+ * ` You begin the journey with an empty tank at one of the gas stations.
+ * ` Return the starting gas station's index
+ * ` if you can travel around the circuit once in the clockwise direction, otherwise return -1.
+ * `
+ * ` Note:
+ * ` If there exists a solution, it is guaranteed to be unique.
+ * ` Both input arrays are non-empty and have the same length.
+ * ` Each element in the input arrays is a non-negative integer.
+ * `
+ * ` 沿循环路线有N个加油站,
+ * ` 其中,第i个站点的天然气量为gas [i]。
+ * ` 您有一辆带无限油箱的汽车,从第i站到下一个(i + 1)的行车成本为[i]。
+ * ` 您可以从其中一个加油站的空罐开始旅程。
+ * ` 返回起始加油站的索引
+ * ` 如果您可以沿顺时针方向绕过电路一次,否则返回-1。
+ * ` 注意:
+ * ` 如果存在解决方案,则保证是唯一的。
+ * ` 两个输入数组都是非空的,并且具有相同的长度。
+ * ` 输入数组中的每个元素都是非负整数。
+ * ` Example 1:
+ * ` Input:
+ * ` gas = [1,2,3,4,5]
+ * ` cost = [3,4,5,1,2]
+ * ` Output: 3
+ * ` Explanation:
+ * ` Start at station 3 (index 3) and fill up with 4 unit of gas.
+ * ` Your tank = 0 + 4 = 4 Travel to station 4. Your tank = 4 - 1 + 5 = 8 Travel to station 0.
+ * ` Your tank = 8 - 2 + 1 = 7 Travel to station 1.
+ * ` Your tank = 7 - 3 + 2 = 6 Travel to station 2.
+ * ` Your tank = 6 - 4 + 3 = 5 Travel to station 3.
+ * ` The cost is 5. Your gas is just enough to travel back to station 3.
+ * ` Therefore, return 3 as the starting index.
+ * ` Example 2:
+ * ` Input:
+ * ` gas = [2,3,4]
+ * ` cost = [3,4,3]
+ * ` Output: -1
+ * ` Explanation:
+ * ` You can't start at station 0 or 1, as there is not enough gas to travel to the next station.
+ * ` Let's start at station 2 and fill up with 4 unit of gas.
+ * ` Your tank = 0 + 4 = 4 Travel to station 0.
+ * ` Your tank = 4 - 3 + 2 = 3 Travel to station 1.
+ * ` Your tank = 3 - 3 + 3 = 3 You cannot travel back to station 2, as it requires 4 unit of gas but you
+ * only have 3.
+ * ` Therefore, you can't travel around the circuit once no matter where you start.
+ * @Version: 1.0
+ */
+public class _134_gas_station {
+
+ public static void main(String[] args) {
+
+ int[] gas = {1, 2, 3, 4, 5};
+ int[] cost = {3, 4, 5, 1, 2};
+ System.out.println(canCompleteCircuit(gas, cost));
+ }
+
+ public static int canCompleteCircuit(int[] gas, int[] cost) {
+ int total = 0;
+
+ for (int i = 0; i < gas.length; i++) {
+ total += gas[i] - cost[i];
+ }
+ if (total < 0) {
+ return -1;
+ }
+
+ for (int i = 0; i < gas.length; i++) {
+ if (canDoIt(gas, cost, i)) {
+ return i;
+ }
+ }
+ return -1;
+ }
+
+ private static boolean canDoIt(int[] gas, int[] cost, int start) {
+ int g = 0;
+ for (int j = 0; j < gas.length; j++) {
+ int position = (j + start) % gas.length;
+ g += gas[position] - cost[position];
+ if (g < 0) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+
+}
diff --git a/java-note-algorithm/src/main/java/com/leosanqing/leetcode/medium/array/_138_copy_list_with_random_pointer.java b/java-note-algorithm/src/main/java/com/leosanqing/leetcode/medium/array/_138_copy_list_with_random_pointer.java
new file mode 100644
index 0000000..fc1e0c9
--- /dev/null
+++ b/java-note-algorithm/src/main/java/com/leosanqing/leetcode/medium/array/_138_copy_list_with_random_pointer.java
@@ -0,0 +1,52 @@
+package com.leosanqing.leetcode.medium.array;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * @Author: rtliu
+ * @Date: 2020/8/4 上午11:30
+ * @Package: com.leosanqing.leetcode.medium.array
+ * @Description: https://leetcode.com/problems/copy-list-with-random-pointer/
+ * @Version: 1.0
+ */
+public class _138_copy_list_with_random_pointer {
+ public RandomListNode copyRandomList(RandomListNode head) {
+
+ if (head == null) {
+ return null;
+ }
+ Map map = new HashMap<>();
+
+
+
+ RandomListNode node = head;
+ while(node !=null){
+ map.put(node,new RandomListNode(node.val));
+ node = node.next;
+ }
+
+ node = head;
+
+ while(node != null){
+ map.get(node).next = map.get(node.next);
+ map.get(node).random = map.get(node.random);
+ node = node.next;
+ }
+
+ return map.get(head);
+ }
+}
+
+
+class RandomListNode {
+ int val;
+ RandomListNode next;
+ RandomListNode random;
+
+ public RandomListNode(int val) {
+ this.val = val;
+ this.next = null;
+ this.random = null;
+ }
+}
\ No newline at end of file
diff --git a/java-note-algorithm/src/main/java/com/leosanqing/leetcode/medium/array/_15_3nums.java b/java-note-algorithm/src/main/java/com/leosanqing/leetcode/medium/array/_15_3nums.java
new file mode 100644
index 0000000..7ee25d1
--- /dev/null
+++ b/java-note-algorithm/src/main/java/com/leosanqing/leetcode/medium/array/_15_3nums.java
@@ -0,0 +1,67 @@
+package com.leosanqing.leetcode.medium.array;
+
+import java.util.Arrays;
+import java.util.LinkedList;
+import java.util.List;
+
+
+/**
+ * 题目: 给定一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?找出所有满足条件且不重复的三元组。
+ * 注意:答案中不可以包含重复的三元组。
+ *
+ * Input: numCourses = 2, prerequisites = [[1,0]]
+ * Output: true
+ * Explanation: There are a total of 2 courses to take.
+ * To take course 1 you should have finished course 0. So it is possible.
+ * @Version: 1.0
+ */
+public class _207_courseSchedule {
+
+ public static void main(String[] args) {
+ int[][] courses = {
+ {0, 1},
+ {1, 2},
+ {2, 3},
+ {5, 3},
+ {4, 2}
+ };
+
+ System.out.println(canFinish(6, courses));
+
+
+ }
+
+ public static boolean canFinish(int numCourses, int[][] prerequisites) {
+ if (numCourses <= 0) {
+ return false;
+ }
+ Queue queue = new LinkedList<>();
+ int[] inDegree = new int[numCourses];
+ // 因为依赖的课程在第二个位置,所以可以查看有多少个课程依赖了这个课程
+ for (int[] prerequisite : prerequisites) {
+ inDegree[prerequisite[1]]++;
+ }
+
+ // 把最基础的课程(没有其他依赖的)加入队列
+ for (int i = 0; i < inDegree.length; i++) {
+ if (inDegree[i] == 0) {
+ queue.offer(i);
+ }
+ }
+ while (!queue.isEmpty()) {
+ int x = queue.poll();
+ for (int[] prerequisite : prerequisites) {
+ if (x == prerequisite[0]) {
+ inDegree[prerequisite[1]]--;
+ // 如果没有课程依赖了,那么这个课程就要被放入之前的队列中,再次循环
+ if (inDegree[prerequisite[1]] == 0) {
+ queue.offer(prerequisite[1]);
+ }
+ }
+ }
+ }
+
+ // 如果有一个不是0,那么就说明他没有上完
+ for (int value : inDegree) {
+ if (value != 0) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+
+
+}
diff --git a/java-note-algorithm/src/main/java/com/leosanqing/leetcode/medium/array/_209_minimumSizeSubarraySum.java b/java-note-algorithm/src/main/java/com/leosanqing/leetcode/medium/array/_209_minimumSizeSubarraySum.java
new file mode 100644
index 0000000..16dd77f
--- /dev/null
+++ b/java-note-algorithm/src/main/java/com/leosanqing/leetcode/medium/array/_209_minimumSizeSubarraySum.java
@@ -0,0 +1,62 @@
+package com.leosanqing.leetcode.medium.array;
+
+/**
+ * @Author: rtliu
+ * @Date: 2020/6/17 下午2:38
+ * @Package: com.leosanqing.leetcode.medium.array
+ * @Description:
+ * Given an array of n positive integers and a positive integer s,
+ * find the minimal length of a contiguous subarray of which the sum ≥ s.
+ * If there isn't one, return 0 instead.
+ *
+ * 给定一个只有正整数的数组和一个正整数 s
+ * 返回 子数组之和大于 s 的长度
+ * 如果没有,则返回 0
+ *
+ *
+ * Example:
+ *
+ * Input: s = 7, nums = [2,3,1,2,4,3]
+ * Output: 2
+ * Explanation: the subarray [4,3] has the minimal length under the problem constraint.
+ *
+ *
+ *
+ * @Version: 1.0
+ */
+public class _209_minimumSizeSubarraySum {
+
+ public static void main(String[] args) {
+ int a[] = {2,3,1,2,4,3};
+ System.out.println(minSubArrayLen(7,a));
+ }
+
+ /**
+ * 使用滑动窗口,设置两个指针 i 和 j 充当窗口的界限
+ * @param s
+ * @param a
+ * @return
+ */
+ public static int minSubArrayLen(int s, int[] a) {
+ if (a == null || a.length == 0) {
+ return 0;
+ }
+ int i = 0, j = 0, sum = 0;
+ int min = Integer.MAX_VALUE;
+
+ // 在数组范围内
+ while (j < a.length) {
+
+ sum += a[j++];
+ // 如果和大于 s,就从前开始挨个减去
+ while (sum >= s) {
+ min = Math.min(min, j - i);
+ sum -= a[i++];
+ }
+ }
+
+ return min == Integer.MAX_VALUE ? 0 : min;
+ }
+
+
+}
diff --git a/java-note-algorithm/src/main/java/com/leosanqing/leetcode/medium/array/_210_courseScheduleII.java b/java-note-algorithm/src/main/java/com/leosanqing/leetcode/medium/array/_210_courseScheduleII.java
new file mode 100644
index 0000000..9c46f11
--- /dev/null
+++ b/java-note-algorithm/src/main/java/com/leosanqing/leetcode/medium/array/_210_courseScheduleII.java
@@ -0,0 +1,99 @@
+package com.leosanqing.leetcode.medium.array;
+
+import java.util.*;
+
+/**
+ * @Author: rtliu
+ * @Date: 2020/6/22 下午4:13
+ * @Package: com.leosanqing.leetcode.medium.array
+ * @Description: There are a total of n courses you have to take, labeled from 0 to n-1. Some courses may have
+ * prerequisites, for example to take course 0 you have to first take course 1, which is expressed as a pair: [0,1]
+ * Given the total number of courses and a list of prerequisite pairs, return the ordering of courses you should take
+ * to finish all courses. There may be multiple correct orders, you just need to return one of them. If it is
+ * impossible to finish all courses, return an empty array.
+ * @Version: 1.0
+ *
+ *
+ *
+ *
+ * Example 1:
+ *
+ * Input: 2, [[1,0]]
+ * Output: [0,1]
+ * Explanation: There are a total of 2 courses to take. To take course 1 you should have finished
+ * course 0. So the correct course order is [0,1] .
+ * Example 2:
+ *
+ * Input: 4, [[1,0],[2,0],[3,1],[3,2]]
+ * Output: [0,1,2,3] or [0,2,1,3]
+ * Explanation: There are a total of 4 courses to take. To take course 3 you should have finished both
+ * courses 1 and 2. Both courses 1 and 2 should be taken after you finished course 0.
+ * So one correct course order is [0,1,2,3]. Another correct ordering is [0,2,1,3] .
+ */
+public class _210_courseScheduleII {
+
+ public static void main(String[] args) {
+ int[][] courses = {
+ {0, 1},
+ {1, 2},
+ {2, 3},
+ {5, 3},
+ {4, 2}
+ };
+
+ canFinish(6, courses);
+
+ }
+
+
+ public static int[] canFinish(int numCourses, int[][] prerequisites) {
+
+
+ int[] answer = new int[numCourses];
+ int cur = numCourses - 1;
+
+
+ if (numCourses <= 0) {
+ return new int[]{};
+ }
+
+ Queue queue = new LinkedList<>();
+ int[] inDegree = new int[numCourses];
+ // 因为依赖的课程在第二个位置,所以可以查看有多少个课程依赖了这个课程
+ for (int[] prerequisite : prerequisites) {
+ inDegree[prerequisite[1]]++;
+ }
+
+ // 把最基础的课程(没有其他依赖的)加入队列
+ for (int i = 0; i < inDegree.length; i++) {
+ if (inDegree[i] == 0) {
+ queue.offer(i);
+ answer[cur--] = i;
+
+ }
+ }
+
+ while (!queue.isEmpty()) {
+ int x = queue.poll();
+ for (int[] prerequisite : prerequisites) {
+ if (x == prerequisite[0]) {
+ inDegree[prerequisite[1]]--;
+ // 如果没有课程依赖了,那么这个课程就要被放入之前的队列中,再次循环
+ if (inDegree[prerequisite[1]] == 0) {
+ queue.offer(prerequisite[1]);
+ answer[cur--] = prerequisite[1];
+ }
+ }
+ }
+ }
+
+ // 如果有一个不是0,那么就说明他没有上完
+ for (int value : inDegree) {
+ if (value != 0) {
+ return new int[]{};
+ }
+ }
+
+ return answer;
+ }
+}
diff --git a/java-note-algorithm/src/main/java/com/leosanqing/leetcode/medium/array/_213_houseRobberII.java b/java-note-algorithm/src/main/java/com/leosanqing/leetcode/medium/array/_213_houseRobberII.java
new file mode 100644
index 0000000..1c08918
--- /dev/null
+++ b/java-note-algorithm/src/main/java/com/leosanqing/leetcode/medium/array/_213_houseRobberII.java
@@ -0,0 +1,65 @@
+package com.leosanqing.leetcode.medium.array;
+
+/**
+ * @Author: rtliu
+ * @Date: 2020/7/2 下午2:20
+ * @Package: com.leosanqing.leetcode.medium.array
+ * @Description:
+ *` You are a professional robber planning to rob houses along a street.
+ *` Each house has a certain amount of money stashed.
+ *` All houses at this place are arranged in a circle.
+ *` That means the first house is the neighbor of the last one.
+ *` Meanwhile, adjacent houses have security system connected
+ *` and it will automatically contact the police if two adjacent houses were broken into on the same night.
+ *` Given a list of non-negative integers representing the amount of money of each house,
+ *` determine the maximum amount of money you can rob tonight without alerting the police.
+ *
+ *` Example 1:
+ *` Input: [2,3,2]
+ *` Output: 3
+ *` Explanation: You cannot rob house 1 (money = 2) and then rob house 3 (money = 2),
+ *` because they are adjacent houses.
+ *
+ *` Example 2:
+ *` Input: [1,2,3,1]
+ *` Output: 4 Explanation: Rob house 1 (money = 1) and then rob house 3 (money = 3).
+ *` Total amount you can rob = 1 + 3 = 4.
+ * @Version: 1.0
+ */
+public class _213_houseRobberII {
+
+ public static void main(String[] args) {
+ _213_houseRobberII houseRobberII = new _213_houseRobberII();
+
+ System.out.println(houseRobberII.rob(new int[]{1,5,4,1,8,7,5,14,8,4}));
+ }
+ public int rob(int[] nums) {
+ if (nums.length == 1) {
+ return nums[0];
+ }
+ return Math.max(rob0(nums), rob1(nums));
+ }
+
+ public int rob0(int[] nums){
+ int preMax = 0, curMax = 0;
+ for(int i = 0; i < nums.length - 1; i++){
+ int t = curMax;
+ curMax = Math.max(preMax + nums[i], curMax);
+ preMax = t;
+ }
+ return curMax;
+ }
+
+ public int rob1(int[] nums){
+ int preMax = 0, curMax = 0;
+ for(int i = 1; i < nums.length; i++){
+ int t = curMax;
+ curMax = Math.max(preMax + nums[i], curMax);
+ preMax = t;
+ }
+ return curMax;
+ }
+
+}
+
+
diff --git a/java-note-algorithm/src/main/java/com/leosanqing/leetcode/medium/array/_240_search_a_2D_matrixII.java b/java-note-algorithm/src/main/java/com/leosanqing/leetcode/medium/array/_240_search_a_2D_matrixII.java
new file mode 100644
index 0000000..ae3d031
--- /dev/null
+++ b/java-note-algorithm/src/main/java/com/leosanqing/leetcode/medium/array/_240_search_a_2D_matrixII.java
@@ -0,0 +1,75 @@
+package com.leosanqing.leetcode.medium.array;
+
+/**
+ * @Author: rtliu
+ * @Date: 2020/7/20 下午4:12
+ * @Package: com.leosanqing.leetcode.medium.array
+ * @Description: 1
+ * ` Write an efficient algorithm that searches for a value in an m x n matrix.
+ * ` This matrix has the following properties:
+ * ` Integers in each row are sorted in ascending from left to right.
+ * ` Integers in each column are sorted in ascending from top to bottom.
+ * ` Example:
+ * ` Consider the following matrix:
+ * ` [
+ * ` [1, 4, 7, 11, 15],
+ * ` [2, 5, 8, 12, 19],
+ * ` [3, 6, 9, 16, 22],
+ * ` [10, 13, 14, 17, 24],
+ * ` [18, 21, 23, 26, 30]
+ * ` ]
+ * ` Given target = 5, return true.
+ * `
+ * ` Given target = 20, return false.
+ * @Version: 1.0
+ */
+public class _240_search_a_2D_matrixII {
+
+ public static void main(String[] args) {
+
+ int[][] nums = {
+ {1, 5, 7, 9},
+ {1, 4, 7, 11, 15},
+ {2, 5, 8, 12, 19},
+ {3, 6, 9, 16, 22},
+ {10, 13, 14, 17, 24},
+ {18, 21, 23, 26, 30}
+
+ };
+
+ System.out.println(searchMatrix(nums,17));
+}
+
+ /**
+ * 这个题和 74题 很像。只不过这个下面一行不一定大于上面一行的任何一个数
+ * 我们从右上角开始,因为这个是行中最大的,列中最小的
+ * @param matrix
+ * @param target
+ * @return
+ */
+ public static boolean searchMatrix(int[][] matrix, int target) {
+ if (matrix == null || matrix.length == 0 || matrix[0].length == 0) {
+ return false;
+ }
+ if (matrix[0][0] > target || matrix[matrix.length - 1][matrix[0].length - 1] < target) {
+ return false;
+ }
+
+ int row = 0;
+ int column = matrix[0].length - 1;
+
+ int num;
+ while (row < matrix.length && column >= 0) {
+ num = matrix[row][column];
+ if (num == target) {
+ return true;
+ }
+ if (num < target) {
+ row++;
+ } else {
+ column--;
+ }
+ }
+ return false;
+ }
+}
diff --git a/java-note-algorithm/src/main/java/com/leosanqing/leetcode/medium/array/_33_search_in_rotated_sorted_array.java b/java-note-algorithm/src/main/java/com/leosanqing/leetcode/medium/array/_33_search_in_rotated_sorted_array.java
new file mode 100644
index 0000000..6f5fef4
--- /dev/null
+++ b/java-note-algorithm/src/main/java/com/leosanqing/leetcode/medium/array/_33_search_in_rotated_sorted_array.java
@@ -0,0 +1,111 @@
+package com.leosanqing.leetcode.medium.array;
+
+/**
+ * @Author: rtliu
+ * @Date: 2020/7/9 下午1:58
+ * @Package: com.leosanqing.leetcode.medium.array
+ * @Description: ` Suppose an array sorted in ascending order is rotated at some pivot unknown to you
+ * beforehand.
+ * ` (i.e., [0,1,2,4,5,6,7] might become [4,5,6,7,0,1,2]).
+ * ` You are given a target value to search.
+ * ` If found in the array return its index, otherwise return -1.
+ * ` You may assume no duplicate exists in the array.
+ * ` Your algorithm's runtime complexity must be in the order of O(log n).
+ *
+ *
+ * ` 假设以升序排序的数组以您不知道的某个枢轴旋转。
+ * ` (即[0,1,2,4,5,6,7]可能会变成[4,5,6,7,0,1,2])。
+ * ` 为您提供了要搜索的目标值。
+ * ` 如果在数组中找到,则返回其索引,否则返回-1。
+ * ` 您可以假设数组中不存在重复项。
+ * ` 算法的运行时复杂度必须为O(log n)的数量级。
+ * `
+ * ` Example 1:
+ * ` Input: nums = [4,5,6,7,0,1,2], target = 0
+ * ` Output: 4
+ * `
+ * ` Example 2:
+ * ` Input: nums = [4,5,6,7,0,1,2], target = 3
+ * ` Output: -1
+ * @Version: 1.0
+ */
+public class _33_search_in_rotated_sorted_array {
+
+ public static void main(String[] args) {
+ int[] nums = new int[]{4, 5, 6, 7, 0, 1, 2};
+ System.out.println(search2(nums, 0));
+ }
+
+ /**
+ * 虽然他不是全部从小到大排序,我们不能用二分法
+ * 但是他有两个部分,两个都是从小到大排序
+ *
+ * @param nums
+ * @param target
+ * @return
+ */
+ public static int search(int[] nums, int target) {
+ if (nums == null || nums.length == 0) {
+ return -1;
+ }
+
+ int left = 0, right = nums.length - 1;
+ while (left <= right) {
+ int mid = left + (right - left) / 2;
+
+ if (target == nums[mid]) {
+ return mid;
+ }
+
+ // 5,7,8,0,1,2,3,4
+ if (nums[left] > nums[mid]) {
+ // target = 7
+ if (target < nums[mid] || nums[left] <= target) {
+ right = mid - 1;
+ } else {
+ // target = 2
+ left = mid + 1;
+ }
+ } else {
+ if (target > nums[mid] || target < nums[left]) {
+ left = mid + 1;
+ } else {
+ right = mid - 1;
+ }
+ }
+ }
+
+ return -1;
+ }
+
+
+ private static int search2(int[] nums, int target) {
+ if (nums == null || nums.length == 0 || (nums.length == 1 && nums[0] != target)) {
+ return -1;
+ }
+ int left = 0, right = nums.length - 1;
+
+ while (left < right) {
+ int mid = left + (right - left) / 2;
+
+ // 说明 mid 和 target 在同一侧
+ if ((nums[mid] - nums[nums.length - 1]) * (target - nums[nums.length - 1]) > 0) {
+ if (target > nums[mid]) {
+ left = mid + 1;
+ } else {
+ right = mid;
+ }
+ } else if (target - nums[nums.length - 1] > 0) {
+ // target 在左侧
+ right = mid;
+ } else {
+ left = mid + 1;
+ }
+ }
+ if (nums[left] == target) {
+ return left;
+ }
+
+ return -1;
+ }
+}
diff --git a/java-note-algorithm/src/main/java/com/leosanqing/leetcode/medium/array/_36_valid_sudoku.java b/java-note-algorithm/src/main/java/com/leosanqing/leetcode/medium/array/_36_valid_sudoku.java
new file mode 100644
index 0000000..c473d55
--- /dev/null
+++ b/java-note-algorithm/src/main/java/com/leosanqing/leetcode/medium/array/_36_valid_sudoku.java
@@ -0,0 +1,84 @@
+package com.leosanqing.leetcode.medium.array;
+
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * @Author: rtliu
+ * @Date: 2020/7/13 上午11:46
+ * @Package: com.leosanqing.leetcode.medium.array
+ * @Description: ` ` Determine if a 9x9 Sudoku board is valid.
+ * ` ` Only the filled cells need to be validated according to the following rules:
+ * ` ` 1. Each row must contain the digits 1-9 without repetition.
+ * ` ` 2. Each column must contain the digits 1-9 without repetition.
+ * ` ` 3. Each of the 9 3x3 sub-boxes of the grid must contain the digits 1-9 without repetition.
+ * 1`
+ * 1`
+ * 1` 确定9x9数独板是否有效。
+ * 1` 仅需根据以下规则验证填充的单元格:
+ * 1` 1.每行必须包含数字1-9,不能重复。
+ * 1` 2.每列必须包含数字1-9,且不能重复。
+ * 1` 3.网格的9个3x3子框中的每个必须包含数字1-9(无重复)。
+ *
+ *
+ * ` Input:
+ * ` [
+ * ` ["8","3",".",".","7",".",".",".","."],
+ * ` ["6",".",".","1","9","5",".",".","."],
+ * ` [".","9","8",".",".",".",".","6","."],
+ * ` ["8",".",".",".","6",".",".",".","3"],
+ * ` ["4",".",".","8",".","3",".",".","1"],
+ * ` ["7",".",".",".","2",".",".",".","6"],
+ * ` [".","6",".",".",".",".","2","8","."],
+ * ` [".",".",".","4","1","9",".",".","5"],
+ * ` [".",".",".",".","8",".",".","7","9"]
+ * ` ]
+ * ` Output: false
+ * ` Explanation: Same as Example 1, except with the 5 in the top left corner being
+ * ` modified to 8. Since there are two 8's in the top left 3x3 sub-box, it is invalid.
+ * ` Note:
+ *
+ * ` A Sudoku board (partially filled) could be valid but is not necessarily solvable.
+ * ` Only the filled cells need to be validated according to the mentioned rules.
+ * ` The given board contain only digits 1-9 and the character '.'.
+ * ` The given board size is always 9x9.
+ * @Version: 1.0
+ */
+public class _36_valid_sudoku {
+ public boolean isValidSudoku(char[][] board) {
+
+ Set set = new HashSet<>();
+ for (int i = 0; i < board.length; i++) {
+ for (int j = 0; j < board.length; j++) {
+ char c = board[i][j];
+ if (c != '.') {
+ if (!set.add(c + "in row" + i) ||
+ !set.add(c + "in column" + j) ||
+ !set.add(c + "in block" + i / 3 + "-" + j/3)
+ ){
+ return false;
+ }
+ }
+ }
+ }
+
+ return true;
+ }
+}
diff --git a/java-note-algorithm/src/main/java/com/leosanqing/leetcode/medium/array/_39_combination_sum.java b/java-note-algorithm/src/main/java/com/leosanqing/leetcode/medium/array/_39_combination_sum.java
new file mode 100644
index 0000000..f8d1d5b
--- /dev/null
+++ b/java-note-algorithm/src/main/java/com/leosanqing/leetcode/medium/array/_39_combination_sum.java
@@ -0,0 +1,73 @@
+package com.leosanqing.leetcode.medium.array;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * @Author: rtliu
+ * @Date: 2020/7/13 下午2:29
+ * @Package: com.leosanqing.leetcode.medium.array
+ * @Description: Given a set of candidate numbers (candidates) (without duplicates) and a target number (target),
+ * find all unique combinations in candidates where the candidate numbers sums to target.
+ * The same repeated number may be chosen from candidates unlimited number of times.
+ *
+ *
+ * 给定一组候选编号(候选)(无重复)和目标编号(target),
+ * 在候选人编号总和为目标的候选人中找到所有唯一组合。
+ * 可以从候选人无限制的次数中选择相同的重复号码。
+ * ` Note:
+ * ` All numbers (including target) will be positive integers.
+ * ` The solution set must not contain duplicate combinations.
+ * ` Example 1:
+ * ` Input: candidates = [2,3,6,7], target = 7,
+ * ` A solution set is: [ [7], [2,2,3] ]
+ * ` Example 2:
+ * ` Input: candidates = [2,3,5], target = 8,
+ * ` A solution set is: [ [2,2,2,2], [2,3,3], [3,5] ]
+ * @Version: 1.0
+ */
+public class _39_combination_sum {
+
+ public static void main(String[] args) {
+ int[] nums = {2, 3, 6, 7};
+
+ combinationSum(nums, 7);
+
+ }
+
+ /**
+ * 这种的做多了,就会发现基本都是一个套路,递归调用
+ *
+ * @param candidates
+ * @param target
+ * @return
+ */
+ public static List> combinationSum(int[] candidates, int target) {
+ List> answer = new ArrayList<>();
+
+ // 先排序
+ Arrays.sort(candidates);
+
+ backtrace(answer, candidates, target, new ArrayList<>(), 0);
+
+ return answer;
+ }
+
+ private static void backtrace(List> answer, int[] candidates, int target, List list, int position) {
+ if (target < 0) {
+ return;
+ }
+
+ if (target == 0) {
+ answer.add(new ArrayList<>(list));
+ return;
+ }
+
+ for (int i = position; i < candidates.length; i++) {
+ list.add(candidates[i]);
+ backtrace(answer, candidates, target - candidates[i], list, i);
+ list.remove(list.size() - 1);
+ }
+ }
+}
diff --git a/java-note-algorithm/src/main/java/com/leosanqing/leetcode/medium/array/_40_combination_sumII.java b/java-note-algorithm/src/main/java/com/leosanqing/leetcode/medium/array/_40_combination_sumII.java
new file mode 100644
index 0000000..30ee10b
--- /dev/null
+++ b/java-note-algorithm/src/main/java/com/leosanqing/leetcode/medium/array/_40_combination_sumII.java
@@ -0,0 +1,72 @@
+package com.leosanqing.leetcode.medium.array;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * @Author: rtliu
+ * @Date: 2020/7/13 下午4:04
+ * @Package: com.leosanqing.leetcode.medium.array
+ * @Description: 1` Given a collection of candidate numbers (candidates) and a target number (target),
+ * 1` find all unique combinations in candidates where the candidate numbers sums to target.
+ * 1` Each number in candidates may only be used once in the combination.
+ * 1` Note:
+ * 1` All numbers (including target) will be positive integers.
+ * 1` The solution set must not contain duplicate combinations.
+ *
+ * 1` Example 1:
+ * 1` Input: candidates = [10,1,2,7,6,1,5], target = 8,
+ * 1` A solution set is: [ [1, 7], [1, 2, 5], [2, 6], [1, 1, 6] ]
+ * 1` Example 2:
+ * 1` Input: candidates = [2,5,2,1,2], target = 5,
+ * 1` A solution set is: [ [1,2,2], [5] ]
+ * @Version: 1.0
+ */
+
+public class _40_combination_sumII {
+
+ public static void main(String[] args) {
+ int[] nums = {10, 1, 2, 7, 6, 1, 5};
+ combinationSum2(nums, 8);
+ }
+
+ public static List> combinationSum2(int[] candidates, int target) {
+
+ Arrays.sort(candidates);
+
+ List> answer = new ArrayList<>();
+
+ backTrace(answer, new ArrayList<>(), candidates, target, 0);
+ return answer;
+ }
+
+ private static void backTrace(List> answer, List list, int[] candidates, int remain,
+ int position) {
+ if (remain < 0) {
+ return;
+ }
+ if (remain == 0) {
+ answer.add(new ArrayList<>(list));
+ return;
+ }
+
+ for (int i = position; i < candidates.length; i++) {
+ // 去除重复 如 [1,1,2,3]. 去掉第2个1 的结果
+ if (i > position && candidates[i] == candidates[i - 1]) {
+ continue;
+ }
+ list.add(candidates[i]);
+ backTrace(answer, list, candidates, remain - candidates[i], i + 1);
+ list.remove(list.size() - 1);
+ }
+ }
+}
diff --git a/java-note-algorithm/src/main/java/com/leosanqing/leetcode/medium/array/_46_permutations.java b/java-note-algorithm/src/main/java/com/leosanqing/leetcode/medium/array/_46_permutations.java
new file mode 100644
index 0000000..de36af7
--- /dev/null
+++ b/java-note-algorithm/src/main/java/com/leosanqing/leetcode/medium/array/_46_permutations.java
@@ -0,0 +1,48 @@
+package com.leosanqing.leetcode.medium.array;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @Author: rtliu
+ * @Date: 2020/7/14 上午9:36
+ * @Package: com.leosanqing.leetcode.medium.array
+ * @Description: 1
+ * ` Given a collection of distinct integers, return all possible permutations.
+ * ` Example:
+ * ` Input: [1,2,3]
+ * ` Output: [ [1,2,3], [1,3,2], [2,1,3], [2,3,1], [3,1,2], [3,2,1] ]
+ * @Version: 1.0
+ */
+public class _46_permutations {
+
+ public static void main(String[] args) {
+ System.out.println(permute(new int[]{1, 2, 3}));
+ }
+
+ public static List> permute(int[] nums) {
+ List> answer = new ArrayList<>();
+
+ backtrace(answer, nums, new ArrayList<>());
+ return answer;
+ }
+
+
+ private static void backtrace(List> answer, int[] nums, List list) {
+ if (list.size() == nums.length) {
+ answer.add(new ArrayList<>(list));
+ return;
+ }
+
+ for (int num : nums) {
+ if (list.contains(num)) {
+ continue;
+ }
+
+ list.add(num);
+ backtrace(answer, nums, list);
+ list.remove(list.size() - 1);
+ }
+ }
+
+}
diff --git a/java-note-algorithm/src/main/java/com/leosanqing/leetcode/medium/array/_47_permutationsII.java b/java-note-algorithm/src/main/java/com/leosanqing/leetcode/medium/array/_47_permutationsII.java
new file mode 100644
index 0000000..3236178
--- /dev/null
+++ b/java-note-algorithm/src/main/java/com/leosanqing/leetcode/medium/array/_47_permutationsII.java
@@ -0,0 +1,67 @@
+package com.leosanqing.leetcode.medium.array;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * @Author: rtliu
+ * @Date: 2020/7/14 上午10:08
+ * @Package: com.leosanqing.leetcode.medium.array
+ * @Description: 1
+ * ` Given a collection of numbers that might contain duplicates,
+ * ` return all possible unique permutations.
+ * ` Example:
+ * ` Input: [1,1,2]
+ * ` Output: [ [1,1,2], [1,2,1], [2,1,1] ]
+ * @Version: 1.0
+ */
+public class _47_permutationsII {
+
+ public static void main(String[] args) {
+ System.out.println(permute(new int[]{1, 1, 3}));
+
+ }
+
+ public static List> permute(int[] nums) {
+ List> answer = new ArrayList<>();
+
+ if (nums == null || nums.length == 0) {
+ return answer;
+ }
+ Arrays.sort(nums);
+ boolean[] used = new boolean[nums.length];
+
+ backTrace(answer, new ArrayList<>(), nums, used);
+ return answer;
+
+ }
+
+ /**
+ * 递归遍历
+ *
+ * @param answer
+ * @param list
+ * @param nums
+ */
+ private static void backTrace(List> answer, List list, int[] nums, boolean[] used) {
+ if (list.size() == nums.length) {
+ answer.add(new ArrayList<>(list));
+ return;
+ }
+ for (int i = 0; i < nums.length; i++) {
+ // 如果有这个数字,就跳过. 并且排除 相邻相同的数字两种情况。之前的排序就为了这个
+ if (used[i] || (i > 0 && nums[i - 1] == nums[i] && !used[i - 1])) {
+ continue;
+ }
+ list.add(nums[i]);
+ used[i] = true;
+ backTrace(answer, list, nums, used);
+ list.remove(list.size() - 1);
+ used[i] = false;
+
+ }
+
+
+ }
+}
diff --git a/java-note-algorithm/src/main/java/com/leosanqing/leetcode/medium/array/_48_rotate_image.java b/java-note-algorithm/src/main/java/com/leosanqing/leetcode/medium/array/_48_rotate_image.java
new file mode 100644
index 0000000..807d56d
--- /dev/null
+++ b/java-note-algorithm/src/main/java/com/leosanqing/leetcode/medium/array/_48_rotate_image.java
@@ -0,0 +1,109 @@
+package com.leosanqing.leetcode.medium.array;
+
+/**
+ * @Author: rtliu
+ * @Date: 2020/7/14 上午10:32
+ * @Package: com.leosanqing.leetcode.medium.array
+ * @Description: 1
+ * `` You are given an n x n 2D matrix representing an image.
+ * `` Rotate the image by 90 degrees (clockwise).
+ * `` Note:
+ * `` You have to rotate the image in-place,
+ * `` which means you have to modify the input 2D matrix directly.
+ * `` DO NOT allocate another 2D matrix and do the rotation.
+ * `` Example 1:
+ * `` Given input matrix =
+ * `` [
+ * `` [1,2,3],
+ * `` [4,5,6],
+ * `` [7,8,9]
+ * `` ],
+ * `` rotate the input matrix in-place such that it becomes:
+ * `` [
+ * `` [7,4,1],
+ * `` [8,5,2],
+ * `` [9,6,3]
+ * `` ]
+ * `` Example 2:
+ * `` Given input matrix =
+ * `` [
+ * `` [ 5, 1, 9,11],
+ * `` [ 2, 4, 8,10],
+ * `` [13, 3, 6, 7],
+ * `` [15,14,12,16]
+ * `` ],
+ * `` rotate the input matrix in-place such that it becomes:
+ * `` [
+ * `` [15,13, 2, 5],
+ * `` [14, 3, 4, 1],
+ * `` [12, 6, 8, 9],
+ * `` [16, 7,10,11]
+ * `` ]
+ * @Version: 1.0
+ */
+public class _48_rotate_image {
+ public static void main(String[] args) {
+
+ }
+
+
+ /**
+ * 分成两步进行旋转
+ *
+ * 1 2 3
+ * 4 5 6
+ * 7 8 9
+ *
+ * 1 4 7
+ * 2 5 8
+ * 3 6 9
+ *
+ * 7 4 1
+ * 8 5 2
+ * 9 6 3
+ *
+ * @param matrix
+ */
+ public static void rotate(int[][] matrix) {
+ int temp;
+
+ for (int i = 0; i < matrix.length; i++) {
+ for (int j = i; j < matrix[0].length; j++) {
+ temp = matrix[i][j];
+ matrix[i][j] = matrix[j][i];
+ matrix[j][i] = temp;
+ }
+ }
+
+ for (int i = 0; i < matrix.length; i++) {
+ for (int j = 0; j < matrix.length / 2; j++) {
+ temp = matrix[i][j];
+ matrix[i][j] = matrix[i][matrix.length - 1 - j];
+ matrix[i][matrix.length - 1 - j] = temp;
+ }
+ }
+ }
+
+
+ public static void rotate1(int[][] matrix) {
+ int temp;
+ for (int i = 0; i < matrix.length; i++) {
+ for (int j = i; j < matrix[0].length; j++) {
+ if (i == j) {
+ continue;
+ }
+ temp = matrix[i][j];
+ matrix[i][j] = matrix[j][i];
+ matrix[j][i] = temp;
+ }
+ }
+
+ for (int i = 0; i < matrix.length; i++) {
+ for (int j = 0; j < matrix[0].length / 2; j++) {
+ temp = matrix[i][j];
+ matrix[i][j] = matrix[i][matrix[0].length - j - 1];
+ matrix[i][matrix[0].length - j - 1] = temp;
+ }
+ }
+ }
+}
diff --git a/java-note-algorithm/src/main/java/com/leosanqing/leetcode/medium/array/_49_group_anagrams.java b/java-note-algorithm/src/main/java/com/leosanqing/leetcode/medium/array/_49_group_anagrams.java
new file mode 100644
index 0000000..ef9489a
--- /dev/null
+++ b/java-note-algorithm/src/main/java/com/leosanqing/leetcode/medium/array/_49_group_anagrams.java
@@ -0,0 +1,54 @@
+package com.leosanqing.leetcode.medium.array;
+
+import java.util.*;
+
+/**
+ * @Author: rtliu
+ * @Date: 2020/7/14 下午2:18
+ * @Package: com.leosanqing.leetcode.medium.array
+ * @Description: 1
+ * ` ` Given an array of strings, group anagrams together.
+ * ` ` 给定一个字符串数组,将字谜分组在一起。
+ * ` ` Example:
+ * ` ` Input: ["eat", "tea", "tan", "ate", "nat", "bat"],
+ * ` ` Output:
+ * ` ` [
+ * ` ` ["ate","eat","tea"],
+ * ` ` ["nat","tan"],
+ * ` ` ["bat"]
+ * ` ` ]
+ * @Version: 1.0
+ */
+public class _49_group_anagrams {
+
+ public static void main(String[] args) {
+ String[] strings = {"eat", "tea", "tan", "ate", "nat", "bat"};
+ System.out.println(groupAnagrams(strings));
+ }
+
+ public static List> groupAnagrams(String[] strs) {
+ List> answer = new ArrayList<>();
+
+ if (strs == null || strs.length == 0) {
+ return answer;
+ }
+
+ Map> map = new HashMap<>();
+
+ for (String str : strs) {
+ char[] chars = new char[26];
+ for (char c : str.toCharArray()) {
+ chars[c - 'a']++;
+ }
+ String s = Arrays.toString(chars);
+
+ List list = map.getOrDefault(s, new ArrayList<>());
+ list.add(str);
+ map.put(s, list);
+
+ }
+ return new ArrayList<>(map.values());
+
+
+ }
+}
diff --git a/java-note-algorithm/src/main/java/com/leosanqing/leetcode/medium/array/_54_spiral_matrix.java b/java-note-algorithm/src/main/java/com/leosanqing/leetcode/medium/array/_54_spiral_matrix.java
new file mode 100644
index 0000000..4042a96
--- /dev/null
+++ b/java-note-algorithm/src/main/java/com/leosanqing/leetcode/medium/array/_54_spiral_matrix.java
@@ -0,0 +1,87 @@
+package com.leosanqing.leetcode.medium.array;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @Author: rtliu
+ * @Date: 2020/7/14 下午2:57
+ * @Package: com.leosanqing.leetcode.medium.array
+ * @Description: 1
+ * ` ` Given a matrix of m x n elements (m rows, n columns),
+ * ` ` return all elements of the matrix in spiral order.
+ * ` ` 给定一个由m x n个元素组成的矩阵(m行n列),
+ * ` ` 以螺旋顺序返回矩阵的所有元素。
+ * ` ` Example 1:
+ * ` ` Input:
+ * ` ` [
+ * ` ` [ 1, 2, 3 ],
+ * ` ` [ 4, 5, 6 ],
+ * ` ` [ 7, 8, 9 ]
+ * ` ` ]
+ * ` ` Output: [1,2,3,6,9,8,7,4,5]
+ * ` ` Example 2:
+ * ` ` Input:
+ * ` ` [
+ * ` ` [1, 2, 3, 4],
+ * ` ` [5, 6, 7, 8],
+ * ` ` [9,10,11,12]
+ * ` ` ]
+ * ` ` Output: [1,2,3,4,8,12,11,10,9,5,6,7]
+ * @Version: 1.0
+ */
+public class _54_spiral_matrix {
+ public static void main(String[] args) {
+
+ int[][] ints = {
+ {1,2,3,4},
+ {5,6,7,8},
+ {9,10,11,12}
+ };
+
+ spiralOrder(ints);
+ }
+
+
+ public static List spiralOrder(int[][] matrix) {
+ List list = new ArrayList<>();
+
+
+ if (matrix == null || matrix.length == 0) {
+ return list;
+ }
+
+ int left = 0, top = 0,
+ right = matrix[0].length - 1, bottom = matrix.length - 1;
+
+
+ while (list.size() < matrix[0].length * matrix.length) {
+ for (int i = left; i <= right; i++) {
+ list.add(matrix[top][i]);
+ }
+ top++;
+
+ for (int i = top; i <= bottom; i++) {
+ list.add(matrix[i][right]);
+ }
+ right--;
+
+ for (int i = right; i >= left; i--) {
+ list.add(matrix[bottom][i]);
+ }
+ bottom--;
+
+ for (int i = bottom; i >= top; i--){
+ list.add(matrix[i][left]);
+ }
+ left++;
+ }
+
+ while(list.size()!= matrix.length * matrix[0].length){
+ list.remove(list.size()-1);
+ }
+ return list;
+ }
+
+
+}
diff --git a/java-note-algorithm/src/main/java/com/leosanqing/leetcode/medium/array/_55_jump_game.java b/java-note-algorithm/src/main/java/com/leosanqing/leetcode/medium/array/_55_jump_game.java
new file mode 100644
index 0000000..a274d72
--- /dev/null
+++ b/java-note-algorithm/src/main/java/com/leosanqing/leetcode/medium/array/_55_jump_game.java
@@ -0,0 +1,66 @@
+package com.leosanqing.leetcode.medium.array;
+
+/**
+ * @Author: rtliu
+ * @Date: 2020/7/14 下午3:32
+ * @Package: com.leosanqing.leetcode.medium.array
+ * @Description: 1
+ * ` ` Given an array of non-negative integers,
+ * ` ` you are initially positioned at the first index of the array.
+ * ` ` Each element in the array represents your maximum jump length at that position.
+ * ` ` Determine if you are able to reach the last index.
+ * ` `
+ * ` ` 给定一个非负整数数组,
+ * ` ` 您最初位于数组的第一个索引。
+ * ` ` 数组中的每个元素代表该位置的最大跳转长度。
+ * ` ` 确定您是否能够达到最后一个索引。
+ * ` ` Example 1:
+ * ` ` Input: nums = [2,3,1,1,4]
+ * ` ` Output: true
+ * ` ` Explanation:
+ * ` ` Jump 1 step from index 0 to 1, then 3 steps to the last index.
+ * ` ` Example 2:
+ * ` ` Input: nums = [3,2,1,0,4]
+ * ` ` Output: false
+ * ` ` Explanation:
+ * ` ` You will always arrive at index 3 no matter what.
+ * ` ` Its maximum jump length is 0, which makes it impossible to reach the last index.
+ * @Version: 1.0
+ */
+public class _55_jump_game {
+ public static void main(String[] args) {
+ System.out.println(canJump(new int[]{3, 2, 1, 1, 4}));
+
+ System.out.println(canJump(new int[]{3, 2, 1, 0, 4}));
+ }
+
+
+ /**
+ * The basic idea is this: at each step, we keep track of the furthest reachable index. The nature of the problem
+ * (eg. maximal jumps where you can hit a range of targets instead of singular jumps where you can only hit one
+ * target) is that for an index to be reachable, each of the previous indices have to be reachable.
+ *
+ * Hence, it suffices that we iterate over each index, and If we ever encounter an index that is not reachable,
+ * we abort and return false. By the end, we will have iterated to the last index. If the loop finishes, then the
+ * last index is reachable.
+ *
+ * ` ` Example:
+ * ` ` Input: (2 -> 4 -> 3) + (5 -> 6 -> 4)
+ * ` ` Output: 7 -> 0 -> 8
+ * ` ` Explanation: 342 + 465 = 807.
+ * @Version: 1.0
+ */
+public class _2_addTwoNumbers {
+ public static void main(String[] args) {
+ ListNode node1 = new ListNode(5);
+ ListNode node2 = new ListNode(2, node1);
+ ListNode node3 = new ListNode(6, node2);
+ ListNode node4 = new ListNode(5);
+ ListNode node5 = new ListNode(1, node4);
+ ListNode node6 = new ListNode(3, node5);
+
+ ListNode listNode1 = addTwoNumbers(node3, node6);
+ }
+
+ public static ListNode addTwoNumbers(ListNode l1, ListNode l2) {
+
+ ListNode cur1 = l1;
+ ListNode cur2 = l2;
+
+ ListNode head = new ListNode();
+ ListNode cur = head;
+
+ int carry = 0;
+ // 定义在这里不需要新建对象
+ int sum;
+
+ while (cur1 != null || cur2 != null) {
+ if (cur1 == null) {
+ cur1 = new ListNode(0);
+ }
+ if (cur2 == null) {
+ cur2 = new ListNode(0);
+ }
+
+ // 计算位数之和
+ sum = carry + cur1.val + cur2.val;
+ // 是否大于0
+ carry = sum / 10;
+ cur.next = new ListNode(sum % 10);
+
+ cur = cur.next;
+ cur1 = cur1.next;
+ cur2 = cur2.next;
+ }
+
+ if (carry != 0) {
+ cur.next = new ListNode(1);
+ }
+ return head.next;
+ }
+}
+
diff --git a/java-note-algorithm/src/main/java/com/leosanqing/leetcode/medium/list/_77_combinations.java b/java-note-algorithm/src/main/java/com/leosanqing/leetcode/medium/list/_77_combinations.java
new file mode 100644
index 0000000..065360e
--- /dev/null
+++ b/java-note-algorithm/src/main/java/com/leosanqing/leetcode/medium/list/_77_combinations.java
@@ -0,0 +1,54 @@
+package com.leosanqing.leetcode.medium.list;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @Author: rtliu
+ * @Date: 2020/7/20 下午7:44
+ * @Package: com.leosanqing.leetcode.medium.list
+ * @Description: 1
+ * ` Given two integers n and k, return all possible combinations of k numbers out of 1 ... n.
+ * ` 给定两个整数n和k,返回1 ... n中k个数字的所有可能组合。
+ * ` Example:
+ * ` Input: n = 4, k = 2
+ * ` Output: [ [2,4], [3,4], [2,3], [1,2], [1,3], [1,4], ]
+ * @Version: 1.0
+ */
+public class _77_combinations {
+ public static void main(String[] args) {
+
+ combine(4, 2);
+ }
+
+ public static List> combine(int n, int k) {
+
+ if (n == 0 || k <= 0) {
+
+ return new ArrayList<>();
+ }
+ List> answer = new ArrayList<>();
+
+ backTrace(answer, new ArrayList<>(), k, n, 1);
+
+ return answer;
+ }
+
+
+ public static void backTrace(List> answer, List list, int k, int n, int position) {
+
+ if (list.size() == k) {
+ answer.add(new ArrayList<>(list));
+ return;
+ }
+
+ for (int i = position; i <= n; i++) {
+ if (list.contains(i)) {
+ continue;
+ }
+ list.add(i);
+ backTrace(answer, list, k, n, i + 1);
+ list.remove(list.size() - 1);
+ }
+ }
+}
diff --git a/java-note-algorithm/src/main/java/com/leosanqing/leetcode/medium/list/_78_subsets.java b/java-note-algorithm/src/main/java/com/leosanqing/leetcode/medium/list/_78_subsets.java
new file mode 100644
index 0000000..0bffeea
--- /dev/null
+++ b/java-note-algorithm/src/main/java/com/leosanqing/leetcode/medium/list/_78_subsets.java
@@ -0,0 +1,53 @@
+package com.leosanqing.leetcode.medium.list;
+
+import com.alibaba.fastjson.JSON;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @Author: rtliu
+ * @Date: 2020/7/20 下午8:08
+ * @Package: com.leosanqing.leetcode.medium.list
+ * @Description: 1
+ * ` Given a set of distinct integers, nums, return all possible subsets (the power set).
+ * ` Note: The solution set must not contain duplicate subsets.
+ * ` Example:
+ * ` Input: nums = [1,2,3]
+ * ` Output: [ [3], [1], [2], [1,2,3], [1,3], [2,3], [1,2], [] ]
+ * @Version: 1.0
+ */
+public class _78_subsets {
+ public static void main(String[] args) {
+ System.out.println(JSON.toJSONString(subsets(new int[]{1, 2, 3})));
+ }
+
+ /**
+ * 这个真的太经典了,回溯的经典题型,你会发现有很多很多这种的题
+ *
+ * @param nums
+ * @return
+ */
+ public static List> subsets(int[] nums) {
+ List> answer = new ArrayList<>();
+
+ for (int i = 0; i <= nums.length; i++) {
+ backtrace(answer, new ArrayList<>(), i, nums, 0);
+ }
+
+ return answer;
+ }
+
+ private static void backtrace(List> answer, List list, int max, int[] nums, int position) {
+ if (list.size() == max) {
+ answer.add(new ArrayList<>(list));
+ return;
+ }
+
+ for (int i = position; i < nums.length; i++) {
+ list.add(nums[i]);
+ backtrace(answer, list, max, nums, i + 1);
+ list.remove(list.size() - 1);
+ }
+ }
+}
diff --git a/java-note-algorithm/src/main/java/com/leosanqing/leetcode/medium/list/_82_remove_duplicates_from_sorted_listII.java b/java-note-algorithm/src/main/java/com/leosanqing/leetcode/medium/list/_82_remove_duplicates_from_sorted_listII.java
new file mode 100644
index 0000000..f5f2e62
--- /dev/null
+++ b/java-note-algorithm/src/main/java/com/leosanqing/leetcode/medium/list/_82_remove_duplicates_from_sorted_listII.java
@@ -0,0 +1,68 @@
+package com.leosanqing.leetcode.medium.list;
+
+/**
+ * @Author: rtliu
+ * @Date: 2020/7/21 下午4:48
+ * @Package: com.leosanqing.leetcode.medium.list
+ * @Description: 1
+ * ` Given a sorted linked list, delete all nodes that have duplicate numbers,
+ * ` leaving only distinct numbers from the original list.
+ * ` Return the linked list sorted as well.
+ * ` Example 1:
+ * ` Input: 1->2->3->3->4->4->5
+ * ` Output: 1->2->5
+ * ` Example 2:
+ * ` Input: 1->1->1->2->3
+ * ` Output: 2->3
+ * @Version: 1.0
+ */
+public class _82_remove_duplicates_from_sorted_listII {
+ public static void main(String[] args) {
+ ListNode node1 = new ListNode(4);
+ ListNode node2 = new ListNode(4, node1);
+ ListNode node3 = new ListNode(3, node2);
+ ListNode node4 = new ListNode(2,node3);
+ ListNode node5 = new ListNode(2, node4);
+ ListNode node6 = new ListNode(2, node5);
+ ListNode node7 = new ListNode(1, node6);
+
+ deleteDuplicates(node7);
+ }
+
+ public static ListNode deleteDuplicates(ListNode head) {
+ if (head == null) {
+ return null;
+ }
+ ListNode fakeNode = new ListNode();
+ fakeNode.next = head;
+
+ ListNode pre = fakeNode;
+ ListNode cur = fakeNode.next;
+ ListNode next = cur.next;
+ while (next != null) {
+ if(next.val != cur.val){
+ pre = cur;
+ cur = next;
+ next = cur.next;
+ continue;
+ }
+ // 一直找到不重复的
+ while(next != null && cur.val == next.val){
+ cur = next;
+ next = next.next;
+ }
+ // 然后把 之前的 pre 节点直接链接到 next节点。这样中间重复的就相当于被删除了
+ if (next != null){
+ pre.next = next;
+ cur = next;
+ next = cur.next;
+ }else{
+ pre.next = next;
+ }
+
+
+ }
+
+ return fakeNode.next;
+ }
+}
diff --git a/java-note-algorithm/src/main/java/com/leosanqing/leetcode/medium/list/_83_remove_duplicates_from_sorted_list.java b/java-note-algorithm/src/main/java/com/leosanqing/leetcode/medium/list/_83_remove_duplicates_from_sorted_list.java
new file mode 100644
index 0000000..e4b1efc
--- /dev/null
+++ b/java-note-algorithm/src/main/java/com/leosanqing/leetcode/medium/list/_83_remove_duplicates_from_sorted_list.java
@@ -0,0 +1,50 @@
+package com.leosanqing.leetcode.medium.list;
+
+/**
+ * @Author: rtliu
+ * @Date: 2020/7/21 下午5:28
+ * @Package: com.leosanqing.leetcode.medium.list
+ * @Description: 1
+ *` Given a sorted linked list, delete all duplicates such that each element appear only once.
+ *` Example 1:
+ *` Input: 1->1->2
+ *` Output: 1->2
+ *` Example 2:
+ *` Input: 1->1->2->3->3
+ *` Output: 1->2->3
+ * @Version: 1.0
+ */
+public class _83_remove_duplicates_from_sorted_list {
+ public static void main(String[] args) {
+ ListNode node1 = new ListNode(1);
+ ListNode node2 = new ListNode(1, node1);
+ ListNode node3 = new ListNode(1, node2);
+ ListNode node4 = new ListNode(1,node3);
+ ListNode node5 = new ListNode(1, node4);
+ ListNode node6 = new ListNode(1, node5);
+ ListNode node7 = new ListNode(1, node6);
+
+ System.out.println(deleteDuplicates(node7).val);
+ }
+
+ public static ListNode deleteDuplicates(ListNode head) {
+ ListNode fakeNode = new ListNode(Integer.MIN_VALUE);
+ fakeNode.next = head;
+
+ ListNode pre = fakeNode;
+ ListNode cur = pre.next;
+
+
+ while (cur != null){
+ if(pre.val == cur.val){
+ cur = cur.next;
+ pre.next = cur;
+ continue;
+ }
+ pre = cur;
+ cur = cur.next;
+ }
+
+ return fakeNode.next;
+ }
+}
diff --git a/java-note-algorithm/src/main/java/com/leosanqing/leetcode/medium/list/_92_reverseLinkedList2.java b/java-note-algorithm/src/main/java/com/leosanqing/leetcode/medium/list/_92_reverseLinkedList2.java
new file mode 100644
index 0000000..c5d337c
--- /dev/null
+++ b/java-note-algorithm/src/main/java/com/leosanqing/leetcode/medium/list/_92_reverseLinkedList2.java
@@ -0,0 +1,54 @@
+package com.leosanqing.leetcode.medium.list;
+
+/**
+ * @Author: rtliu
+ * @Date: 2020/6/1 下午7:01
+ * @Package: com.leosanqing.leetcode.medium
+ * @Description: Reverse a linked list from position m to n. Do it in one-pass.
+ * 对反转给定范围的链表节点进行反转,只遍历一遍
+ *
+ * Note: 1 ≤ m ≤ n ≤ length of list.
+ *
+ * Example:
+ *
+ * Input: 1->2->3->4->5->NULL, m = 2, n = 4
+ * Output: 1->4->3->2->5->NULL
+ * @Version: 1.0
+ */
+public class _92_reverseLinkedList2 {
+
+ public ListNode reverseBetween(ListNode head, int m, int n) {
+ if (head == null) {
+ return null;
+ }
+ // 设置一个虚拟头结点
+ ListNode fakeHead = new ListNode(0);
+ fakeHead.next = head;
+ ListNode cur1 = fakeHead;
+ ListNode pre1 = null;
+
+ // 找到 m 的位置
+ for (int i = 0; i < m; i++) {
+ pre1 = cur1;
+ cur1 = cur1.next;
+ }
+
+ ListNode next;
+ ListNode pre2 = pre1;
+ ListNode cur2 = cur1;
+ for (int i = 0; i <= n - m; i++) {
+ next = cur2.next;
+ cur2.next = pre2;
+ pre2 = cur2;
+ cur2 = next;
+ }
+
+ // 反转完之后,链接 m 之前的节点 和 n 后的节点
+ pre1.next = pre2;
+ cur1.next = cur2;
+
+ return fakeHead.next;
+ }
+
+
+}
diff --git a/java-note-algorithm/src/main/java/com/leosanqing/leetcode/medium/num/_264_uglyNumberII.java b/java-note-algorithm/src/main/java/com/leosanqing/leetcode/medium/num/_264_uglyNumberII.java
new file mode 100644
index 0000000..3c024da
--- /dev/null
+++ b/java-note-algorithm/src/main/java/com/leosanqing/leetcode/medium/num/_264_uglyNumberII.java
@@ -0,0 +1,52 @@
+package com.leosanqing.leetcode.medium.num;
+
+/**
+ * @Author: rtliu
+ * @Date: 2020/6/23 下午4:17
+ * @Package: com.leosanqing.leetcode.medium.num
+ * @Description: Write a program to find the n-th ugly number.
+ * Ugly numbers are positive numbers whose prime factors
+ * only include 2, 3, 5.
+ * @Version: 1.0
+ *
+ *
+ * Example:
+ *
+ * Input: n = 10
+ * Output: 12
+ * Explanation: 1, 2, 3, 4, 5, 6, 8, 9, 10, 12 is the sequence of the first 10 ugly numbers.
+ * Note:
+ *
+ * 1 is typically treated as an ugly number.
+ * n does not exceed 1690.
+ */
+public class _264_uglyNumberII {
+ public int nthUglyNumber(int n) {
+
+ // 创建一个数组,用来存储 uglyNumber
+ int[] ugly = new int[n];
+ ugly[0] = 1;
+
+ int index2 = 0, index3 = 0, index5 = 0;
+ int factor2 = 2, factor3 = 3, factor5 = 5;
+ for (int i = 1; i < n; i++) {
+ int min = Math.min(Math.min(factor2, factor3), factor5);
+ ugly[i] = min;
+ // 如果 这个数字是他的倍数,那就往后走,
+ // 比如 30 是 2 3 5 的共同的 uglyNumber,所以他们都要往后移一个
+ if (factor2 == min) {
+ factor2 = 2 * ugly[++index2];
+ }
+ if (factor3 == min) {
+ factor3 = 3 * ugly[++index3];
+ }
+ if (factor5 == min) {
+ factor5 = 5 * ugly[++index5];
+ }
+ }
+ return ugly[n - 1];
+ }
+
+
+
+}
diff --git a/java-note-algorithm/src/main/java/com/leosanqing/leetcode/medium/string/_131_palindrome_partitioning.java b/java-note-algorithm/src/main/java/com/leosanqing/leetcode/medium/string/_131_palindrome_partitioning.java
new file mode 100644
index 0000000..1b29a54
--- /dev/null
+++ b/java-note-algorithm/src/main/java/com/leosanqing/leetcode/medium/string/_131_palindrome_partitioning.java
@@ -0,0 +1,58 @@
+package com.leosanqing.leetcode.medium.string;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @Author: rtliu
+ * @Date: 2020/8/3 下午5:43
+ * @Package: com.leosanqing.leetcode.medium.string
+ * @Description: 1
+ * ` Given a string s, partition s such that every substring of the partition is a palindrome.
+ * ` Return all possible palindrome partitioning of s.
+ * ` Example:
+ * ` Input: "aab"
+ * ` Output:
+ * ` [
+ * ` ["aa","b"],
+ * ` ["a","a","b"]
+ * ` ]
+ * @Version: 1.0
+ */
+public class _131_palindrome_partitioning {
+ public static void main(String[] args) {
+ partition("aab");
+ }
+ public static List> partition(String s) {
+
+ List> answer = new ArrayList<>();
+ for (int i = 1; i < s.length(); i++) {
+ backTrace(answer,new ArrayList<>(), s, 0, i);
+ }
+ return answer;
+ }
+
+ private static void backTrace(List> answer, List list, String s, int position, int length) {
+ if (position >= s.length()) {
+ answer.add(new ArrayList<>(list));
+ return;
+ }
+
+
+ String substring = s.substring(position, position + length);
+ if (isPalindrome(substring)) {
+ list.add(substring);
+ return;
+ }
+ backTrace(answer, list, s, position + length, length);
+ }
+
+ private static boolean isPalindrome(String s) {
+ for (int i = 0; i < s.length() / 2; i++) {
+ if (s.charAt(i) != s.charAt(s.length() - 1 - i)) {
+ return false;
+ }
+ }
+ return true;
+ }
+}
diff --git a/java-note-algorithm/src/main/java/com/leosanqing/leetcode/medium/string/_139_word_break.java b/java-note-algorithm/src/main/java/com/leosanqing/leetcode/medium/string/_139_word_break.java
new file mode 100644
index 0000000..b16fbac
--- /dev/null
+++ b/java-note-algorithm/src/main/java/com/leosanqing/leetcode/medium/string/_139_word_break.java
@@ -0,0 +1,80 @@
+package com.leosanqing.leetcode.medium.string;
+
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * @Author: rtliu
+ * @Date: 2020/8/4 上午11:38
+ * @Package: com.leosanqing.leetcode.medium.string
+ * @Description: 1
+ * 1 Given a non-empty string s and a dictionary wordDict containing a list of non-empty words,
+ * 1 determine if s can be segmented into a space-separated sequence of one or more dictionary words.
+ * 1 给定一个非空字符串s和一个包含非空单词列表的字典wordDict,
+ * 1 确定是否可以将s分割为一个或多个词典单词的以空格分隔的序列
+ * 1
+ * 1 Note:
+ * 1 The same word in the dictionary may be reused multiple times in the segmentation.
+ * 1 You may assume the dictionary does not contain duplicate words.
+ * 1 Example 1:
+ * 1 Input: s = "leetcode", wordDict = ["leet", "code"]
+ * 1 Output: true
+ * 1 Explanation:
+ * 1 Return true because "leetcode" can be segmented as "leet code".
+ * 1 Example 2:
+ * 1 Input: s = "applepenapple", wordDict = ["apple", "pen"]
+ * 1 Output: true
+ * 1 Explanation:
+ * 1 Return true because "applepenapple" can be segmented as "apple pen apple".
+ * 1 Note that you are allowed to reuse a dictionary word.
+ * 1 Example 3:
+ * 1 Input: s = "catsandog", wordDict = ["cats", "dog", "sand", "and", "cat"]
+ * 1 Output: false
+ * 1
+ * @Version: 1.0
+ */
+public class _139_word_break {
+
+ static Set set;
+
+ public static void main(String[] args) {
+ String s = "leetcode";
+
+ System.out.println(wordBreak(s, Arrays.asList("leet", "code")));
+ }
+
+ public static boolean wordBreak(String s, List wordDict) {
+ set = new HashSet<>(wordDict);
+ return backtrace(s, 0, new HashSet<>());
+
+ }
+
+
+ private static boolean backtrace(String s, int position, Set words) {
+ if (position == s.length()) {
+ return true;
+ }
+
+ // 如果存在,则说明已经尝试过这种方法,就直接返回
+ if (words.contains(position)) {
+ return false;
+ }
+
+ for (int i = position + 1; i <= s.length(); i++) {
+ if (!set.contains(s.substring(position, i))) {
+ continue;
+ }
+
+ if (backtrace(s, i, words)) {
+ return true;
+ }
+
+ words.add(i);
+ }
+
+ words.add(position);
+ return false;
+ }
+}
diff --git a/java-note-algorithm/src/main/java/com/leosanqing/leetcode/medium/string/_22_generate_parentheses.java b/java-note-algorithm/src/main/java/com/leosanqing/leetcode/medium/string/_22_generate_parentheses.java
new file mode 100644
index 0000000..2b746b8
--- /dev/null
+++ b/java-note-algorithm/src/main/java/com/leosanqing/leetcode/medium/string/_22_generate_parentheses.java
@@ -0,0 +1,60 @@
+package com.leosanqing.leetcode.medium.string;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @Author: rtliu
+ * @Date: 2020/7/8 下午3:44
+ * @Package: com.leosanqing.leetcode.medium.string
+ * @Description: ` Given n pairs of parentheses, write a function to generate all combinations of well-formed
+ * parentheses.
+ * `
+ * ` For example,
+ * ` given n = 3, a solution set is:
+ * ` [
+ * ` "((()))",
+ * ` "(()())",
+ * ` "(())()",
+ * ` "()(())",
+ * ` "()()()"
+ * ` ]
+ * @Version: 1.0
+ */
+public class _22_generate_parentheses {
+
+
+ public static void main(String[] args) {
+ System.out.println(generateParenthesis(3));
+ }
+
+ public static List generateParenthesis(int n) {
+ List list = new ArrayList<>();
+
+ backtrace(list, new StringBuilder(), 0, 0, n);
+
+ return list;
+ }
+
+
+ private static void backtrace(List result, StringBuilder sb, int left, int right, int max) {
+ if (left == max && right == max) {
+ result.add(sb.toString());
+ return;
+ }
+
+ if (left <= max) {
+ sb.append("(");
+ backtrace(result, sb, left + 1, right, max);
+ sb.deleteCharAt(sb.length() - 1);
+ }
+
+ // 避免出现 ())这种情况
+ if (right < left) {
+ sb.append(")");
+ backtrace(result, sb, left, right + 1, max);
+ sb.deleteCharAt(sb.length() - 1);
+ }
+
+ }
+}
diff --git a/java-note-algorithm/src/main/java/com/leosanqing/leetcode/medium/string/_31_next_permutation.java b/java-note-algorithm/src/main/java/com/leosanqing/leetcode/medium/string/_31_next_permutation.java
new file mode 100644
index 0000000..ecdabb3
--- /dev/null
+++ b/java-note-algorithm/src/main/java/com/leosanqing/leetcode/medium/string/_31_next_permutation.java
@@ -0,0 +1,70 @@
+package com.leosanqing.leetcode.medium.string;
+
+import com.alibaba.fastjson.JSON;
+
+import java.util.Arrays;
+
+/**
+ * @description: ` 实现获取 下一个排列 的函数,算法需要将给定数字序列重新排列成字典序中下一个更大的排列。
+ * `
+ * ` 如果不存在下一个更大的排列,则将数字重新排列成最小的排列(即升序排列)。
+ * `
+ * ` 必须 原地 修改,只允许使用额外常数空间。
+ * `
+ * ` 示例 1:
+ * `
+ * ` 输入:nums = [1,2,3]
+ * ` 输出:[1,3,2]
+ * ` 示例 2:
+ * `
+ * ` 输入:nums = [3,2,1]
+ * ` 输出:[1,2,3]
+ * ` 示例 3:
+ * `
+ * ` 输入:nums = [1,1,5]
+ * ` 输出:[1,5,1]
+ * ` 示例 4:
+ * `
+ * ` 输入:nums = [1]
+ * ` 输出:[1]
+ * @author: rtliu
+ * @date: 2021/4/8 2:07 下午
+ */
+public class _31_next_permutation {
+ public static void main(String[] args) {
+ nextPermutation(new int[]{1, 3, 2});
+ }
+
+ /**
+ * 1.从右到左找升序数字
+ * 2.找到右边比当前数字大的数字,两个交换位置
+ * 3.右边数字再重新升序排列
+ *
+ * @param nums
+ */
+ public static void nextPermutation(int[] nums) {
+
+ for (int i = nums.length - 1; i > 0; i--) {
+ if (nums[i] < nums[i - 1]) {
+ continue;
+ }
+
+ for (int j = nums.length - 1; j >= i; j--) {
+ if (nums[i - 1] > nums[j]) {
+ continue;
+ }
+
+ // 从后面找比 num 大的数字,交换
+ int temp = nums[i - 1];
+ nums[i - 1] = nums[j];
+ nums[j] = temp;
+
+ Arrays.sort(nums, i, nums.length);
+ return;
+
+ }
+
+ }
+ Arrays.sort(nums);
+ }
+}
diff --git a/java-note-algorithm/src/main/java/com/leosanqing/leetcode/medium/string/_3_longest_substring_without_repeating_characters.java b/java-note-algorithm/src/main/java/com/leosanqing/leetcode/medium/string/_3_longest_substring_without_repeating_characters.java
new file mode 100644
index 0000000..9f0589e
--- /dev/null
+++ b/java-note-algorithm/src/main/java/com/leosanqing/leetcode/medium/string/_3_longest_substring_without_repeating_characters.java
@@ -0,0 +1,66 @@
+package com.leosanqing.leetcode.medium.string;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * @description: Given a string s, find the length of the longest substring without repeating characters.
+ *
+ * 给定字符串s,找到最长子字符串的长度而不重复字符。
+ *
+ * ` Example 1:
+ *
+ * ` Input: s = "abcabcbb"
+ * ` Output: 3
+ * ` Explanation: The answer is "abc", with the length of 3.
+ * ` Example 2:
+ *
+ * ` Input: s = "bbbbb"
+ * ` Output: 1
+ * ` Explanation: The answer is "b", with the length of 1.
+ * ` Example 3:
+ *
+ * ` Input: s = "pwwkew"
+ * ` Output: 3
+ * ` Explanation: The answer is "wke", with the length of 3.
+ * ` Notice that the answer must be a substring, "pwke" is a subsequence and not a substring.
+ * ` Example 4:
+ *
+ * ` Input: s = ""
+ * ` Output: 0
+ *
+ * ` @author: rtliu
+ * ` @date: 2021/4/6 3:41 下午
+ */
+public class _3_longest_substring_without_repeating_characters {
+ public static void main(String[] args) {
+ System.out.println(lengthOfLongestSubstring("abba"));
+ }
+
+ /**
+ * 这个是典型的滑动窗口类的题型
+ *
+ * 我们遇到相同的字符就丢弃之前字符左边的所有字符
+ * @param s
+ * @return
+ */
+ public static int lengthOfLongestSubstring(String s) {
+ Map map = new HashMap<>(s.length() * 2);
+
+ int result = 0;
+ int head = 0;
+
+ for (int i = 0; i < s.length(); i++) {
+ char c = s.charAt(i);
+
+ if (map.containsKey(c) && head < map.get(c)) {
+ head = map.get(c);
+ }
+ // i+1 表示当前字符的实际位置
+ result = Math.max(i + 1 - head, result);
+ map.put(c, i + 1);
+ }
+
+ return result;
+ }
+}
diff --git a/java-note-algorithm/src/main/java/com/leosanqing/leetcode/medium/string/_43_multiply_strings.java b/java-note-algorithm/src/main/java/com/leosanqing/leetcode/medium/string/_43_multiply_strings.java
new file mode 100644
index 0000000..4e191d8
--- /dev/null
+++ b/java-note-algorithm/src/main/java/com/leosanqing/leetcode/medium/string/_43_multiply_strings.java
@@ -0,0 +1,63 @@
+package com.leosanqing.leetcode.medium.string;
+
+/**
+ * @Author: rtliu
+ * @Date: 2020/7/13 下午5:05
+ * @Package: com.leosanqing.leetcode.medium.string
+ * @Description: 1
+ * ` Given two non-negative integers num1 and num2 represented as strings,
+ * ` return the product of num1 and num2, also represented as a string.
+ * `
+ * ` 给定两个表示为字符串的非负整数num1和num2,
+ * ` 返回num1和num2的乘积,也表示为字符串。
+ * ` Example 1:
+ * ` Input: num1 = "2", num2 = "3"
+ * ` Output: "6"
+ * ` Example 2:
+ * ` Input: num1 = "123", num2 = "456"
+ * ` Output: "56088"
+ * @Version: 1.0
+ */
+public class _43_multiply_strings {
+ public static void main(String[] args) {
+
+ System.out.println(multiply("999", "999").equals(String.valueOf(999 * 999)));
+
+ }
+
+ /**
+ * 我们做乘法也是这样做
+ * @param num1
+ * @param num2
+ * @return
+ */
+ public static String multiply(String num1, String num2) {
+
+ int m = num1.length();
+ int n = num2.length();
+
+ int[] result = new int[m + n];
+
+ for (int i = m - 1; i >= 0; i--) {
+ for (int j = n - 1; j >= 0; j--) {
+ int temp = (num1.charAt(i) - '0') * (num2.charAt(j) - '0');
+ int p1 = i + j, p2 = i + j + 1;
+
+ int sum = temp + result[p2];
+
+ result[p1] += sum / 10;
+ result[p2] = sum % 10;
+
+ }
+ }
+
+ StringBuilder stringBuilder = new StringBuilder();
+ for (int i : result) {
+ if (stringBuilder.length() == 0 && i == 0) {
+ continue;
+ }
+ stringBuilder.append(i);
+ }
+ return stringBuilder.length() == 0 ? "0" : stringBuilder.toString();
+ }
+}
diff --git a/java-note-algorithm/src/main/java/com/leosanqing/leetcode/medium/string/_5_longestPalindromicSubstring.java b/java-note-algorithm/src/main/java/com/leosanqing/leetcode/medium/string/_5_longestPalindromicSubstring.java
new file mode 100644
index 0000000..464db5c
--- /dev/null
+++ b/java-note-algorithm/src/main/java/com/leosanqing/leetcode/medium/string/_5_longestPalindromicSubstring.java
@@ -0,0 +1,56 @@
+package com.leosanqing.leetcode.medium.string;
+
+/**
+ * @Author: rtliu
+ * @Date: 2020/7/3 上午11:16
+ * @Package: com.leosanqing.leetcode.medium.string
+ * @Description: ` ` Given a string s, find the longest palindromic substring in s.
+ * ` ` You may assume that the maximum length of s is 1000.
+ * `
+ * ` ` 给定字符串s,找到s中最长的回文子字符串。
+ * ` 您可以假设s的最大长度为1000。
+ * ` ` Example 1:
+ * ` ` Input: "babad"
+ * ` ` Output: "bab"
+ * ` ` Note: "aba" is also a valid answer.
+ * ` ` Example 2:
+ * ` ` Input: "cbbd"
+ * ` ` Output: "bb"
+ * @Version: 1.0
+ */
+public class _5_longestPalindromicSubstring {
+ public static void main(String[] args) {
+ String s = "abasasaiug";
+ System.out.println(longestPalindrome(s));
+ }
+
+ public static String longestPalindrome(String s) {
+ if (s.length() < 2) {
+ return s;
+ }
+ String longStr = "";
+
+ for (int i = 0; i < s.length(); i++) {
+ String s1 = findStr(s, i, i);
+ String s2 = findStr(s, i, i + 1);
+
+ if (s1.length() > longStr.length()) {
+ longStr = s1;
+ }
+ if (s2.length() > longStr.length()) {
+ longStr = s2;
+ }
+ }
+
+ return longStr;
+ }
+
+ private static String findStr(String s, int i, int j) {
+ for (; i >= 0 && j < s.length(); i--, j++) {
+ if (s.charAt(i) != s.charAt(j)) {
+ break;
+ }
+ }
+ return s.substring(i + 1, j);
+ }
+}
diff --git a/java-note-algorithm/src/main/java/com/leosanqing/leetcode/medium/string/_71_simplify_path.java b/java-note-algorithm/src/main/java/com/leosanqing/leetcode/medium/string/_71_simplify_path.java
new file mode 100644
index 0000000..417c455
--- /dev/null
+++ b/java-note-algorithm/src/main/java/com/leosanqing/leetcode/medium/string/_71_simplify_path.java
@@ -0,0 +1,90 @@
+package com.leosanqing.leetcode.medium.string;
+
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Stack;
+
+/**
+ * @Author: rtliu
+ * @Date: 2020/7/20 下午1:56
+ * @Package: com.leosanqing.leetcode.medium.string
+ * @Description: 1
+ * ` Given an absolute path for a file (Unix-style), simplify it.
+ * ` Or in other words, convert it to the canonical path.
+ * ` In a UNIX-style file system, a period .
+ * ` refers to the current directory. Furthermore, a double period .. moves the directory up a level.
+ * `
+ * ` Note that the returned canonical path must always begin with a slash /,
+ * ` and there must be only a single slash / between two directory names.
+ * ` The last directory name (if it exists) must not end with a trailing /.
+ * ` Also, the canonical path must be the shortest string representing the absolute path.
+ * `
+ * ` 给定文件的绝对路径(Unix风格),请简化它。
+ * ` 或者换句话说,将其转换为规范路径。
+ * ` 在UNIX样式的文件系统中,为period。
+ * ` 指当前目录。此外,双倍..将目录上移
+ * ` 请注意,返回的规范路径必须始终以斜杠/开头。
+ * ` 并且两个目录名称之间只能有一个斜杠/。
+ * ` 最后的目录名称(如果存在)不得以/结尾。
+ * ` 同样,规范路径必须是代表绝对路径的最短字符串。
+ * `
+ * ` Example 1:
+ * ` Input: "/home/"
+ * ` Output: "/home"
+ * ` Explanation:
+ * ` Note that there is no trailing slash after the last directory name.
+ * ` Example 2:
+ * ` Input: "/../"
+ * ` Output: "/"
+ * ` Explanation:
+ * ` Going one level up from the root directory is a no-op,
+ * ` as the root level is the highest level you can go.
+ * ` Example 3:
+ * ` Input: "/home//foo/"
+ * ` Output: "/home/foo"
+ * ` Explanation:
+ * ` In the canonical path, multiple consecutive slashes are replaced by a single one.
+ * ` Example 4:
+ * ` Input: "/a/./b/../../c/"
+ * ` Output: "/c"
+ * ` Example 5:
+ * ` Input: "/a/../../b/../c//.//"
+ * ` Output: "/c"
+ * ` Example 6:
+ * ` Input: "/a//b////c/d//././/.."
+ * ` Output: "/a/b/c"
+ * @Version: 1.0
+ */
+public class _71_simplify_path {
+ public static void main(String[] args) {
+ System.out.println(simplifyPath("/a//b////c/d//././/.."));
+ }
+
+ public static String simplifyPath(String path) {
+ if (path == null || "".equals(path)) {
+ return "";
+ }
+ Stack stack = new Stack<>();
+ String[] split = path.split("/");
+ HashSet pathSet = new HashSet<>(Arrays.asList("..", ".", ""));
+ for (String s : split) {
+ if ("..".equals(s) && !stack.isEmpty()) {
+ stack.pop();
+ } else if (!pathSet.contains(s)) {
+ stack.push(s);
+ }
+ }
+
+ if (stack.isEmpty()) {
+ return "/";
+ }
+
+ StringBuilder sb = new StringBuilder();
+ for (String s : stack) {
+ sb.append("/").append(s);
+ }
+ return sb.toString();
+
+ }
+
+}
diff --git a/java-note-algorithm/src/main/java/com/leosanqing/leetcode/medium/string/_91_decode_ways.java b/java-note-algorithm/src/main/java/com/leosanqing/leetcode/medium/string/_91_decode_ways.java
new file mode 100644
index 0000000..fd36509
--- /dev/null
+++ b/java-note-algorithm/src/main/java/com/leosanqing/leetcode/medium/string/_91_decode_ways.java
@@ -0,0 +1,55 @@
+package com.leosanqing.leetcode.medium.string;
+
+/**
+ * @Author: rtliu
+ * @Date: 2020/7/22 下午4:16
+ * @Package: com.leosanqing.leetcode.medium.string
+ * @Description: 1
+ * ` A message containing letters from A-Z is being encoded to numbers using the following mapping:
+ * ` 'A' -> 1 'B' -> 2 ... 'Z' -> 26
+ * ` Given a non-empty string containing only digits, determine the total number of ways to decode it.
+ * ` Example 1:
+ * ` Input: "12"
+ * ` Output: 2
+ * ` Explanation:
+ * ` It could be decoded as "AB" (1 2) or "L" (12).
+ * ` Example 2:
+ * ` Input: "226"
+ * ` Output: 3
+ * ` Explanation:
+ * ` It could be decoded as "BZ" (2 26), "VF" (22 6), or "BBF" (2 2 6).
+ * @Version: 1.0
+ */
+public class _91_decode_ways {
+ public static void main(String[] args) {
+
+ System.out.println(numDecodings("2262"));
+ }
+
+ public static int numDecodings(String s) {
+ int[] dp = new int[s.length() + 1];
+ dp[0] = 1;
+ dp[1] = s.charAt(0) != '0' ? 1 : 0;
+
+ for (int i = 2; i <= s.length(); i++) {
+ int first = Integer.parseInt(s.substring(i - 1, i));
+ int second = Integer.parseInt(s.substring(i - 2, i));
+
+
+ // 如果这位数是 1-9, 那么 他可以就等于之前的位数,按照单个算
+ // 如 2221 我如果只看最后一位1,那么他的可能性肯定只会等于 222的可能性
+ if (first >= 1 && first <= 9) {
+ dp[i] = dp[i - 1];
+ }
+
+ // 如果 我们 两位 两位看,他的可能性就是之前一位的加上 两位的可能性
+ // 如 1211 最后 1 的可能性就是 121 + 12 的可能性
+ if (second >= 10 && second <= 26) {
+ dp[i] += dp[i - 2];
+ }
+ }
+ return dp[s.length()];
+ }
+
+
+}
diff --git a/java-note-algorithm/src/main/java/com/leosanqing/leetcode/medium/string/_93_restore_IP_addresses.java b/java-note-algorithm/src/main/java/com/leosanqing/leetcode/medium/string/_93_restore_IP_addresses.java
new file mode 100644
index 0000000..d4eae09
--- /dev/null
+++ b/java-note-algorithm/src/main/java/com/leosanqing/leetcode/medium/string/_93_restore_IP_addresses.java
@@ -0,0 +1,90 @@
+package com.leosanqing.leetcode.medium.string;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @Author: rtliu
+ * @Date: 2020/7/23 下午4:47
+ * @Package: com.leosanqing.leetcode.medium.string
+ * @Description: 1
+ * ` Given a string containing only digits, restore it by returning all possible valid IP address combinations.
+ * ` A valid IP address consists of exactly four integers (each integer is between 0 and 255) separated by
+ * single points.
+ * ` Example:
+ * ` Input: "25525511135"
+ * ` Output: ["255.255.11.135", "255.255.111.35"]
+ * @Version: 1.0
+ */
+public class _93_restore_IP_addresses {
+
+ public static void main(String[] args) {
+ String s = "25525511135";
+ restoreIpAddresses(s);
+
+ System.out.println(s.substring(0,1));
+ }
+
+ public static List restoreIpAddresses(String s) {
+ if (s.length() < 4 || s.length() > 12) {
+ return new ArrayList<>();
+ }
+
+ List result = new ArrayList<>();
+ doRestore(result, "", s, 0);
+ return result;
+ }
+
+ public static List restoreIpAddresses1(String s) {
+ if (s.length() < 4 || s.length() > 12) {
+ return new ArrayList<>();
+ }
+ List result = new ArrayList<>();
+ for (int a = 1; a <= 3; a++) {
+ for (int b = 1; b <= 3; b++) {
+ for (int c = 1; c <= 3; c++) {
+ for (int d = 1; d <= 3; d++) {
+ if (a + b + c + d == s.length()) {
+ int num1 = Integer.parseInt(s.substring(0, a));
+ int num2 = Integer.parseInt(s.substring(a, a + b));
+ int num3 = Integer.parseInt(s.substring(a + b, a + b + c));
+ int num4 = Integer.parseInt(s.substring(a + b + c));
+
+ if (num1 <= 255 && num2 <= 255 && num3 <= 255 && num4 <= 255) {
+ result.add(num1 + "." + num2 + "." + num3 + "." + num4);
+ }
+ }
+ }
+ }
+ }
+ }
+ return result;
+ }
+
+
+ /**
+ *
+ * @param result
+ * @param path 已经组成的ip地址
+ * @param s 去掉path 后的 剩余的字符 如初始为 2222,path 为 2.2 str 为22
+ * @param k 已经有几段ip地址了 如 运行到 k=2 ,这个时候 path 为 22.22
+ */
+ private static void doRestore(List result, String path, String s, int k) {
+ if (k == 4 || s.isEmpty()) {
+ if (k == 4 && s.isEmpty()) {
+ result.add(path.substring(1));
+ }
+ return;
+ }
+
+ // 如果 s开头为0,只能截取1个字符,不然会出现 22.02 不符合规则
+ for (int i = 1; i <= (s.charAt(0) == '0' ? 1 : 3) && i <= s.length(); i++) {
+ //
+ String part = s.substring(0, i);
+ // 必须小于 255
+ if (Integer.parseInt(part) <= 255) {
+ doRestore(result, path + "." + part, s.substring(i), k + 1);
+ }
+ }
+ }
+}
diff --git a/java-note-algorithm/src/main/java/com/leosanqing/leetcode/medium/struct/_146_LRU_Cache.java b/java-note-algorithm/src/main/java/com/leosanqing/leetcode/medium/struct/_146_LRU_Cache.java
new file mode 100644
index 0000000..c0ad5f0
--- /dev/null
+++ b/java-note-algorithm/src/main/java/com/leosanqing/leetcode/medium/struct/_146_LRU_Cache.java
@@ -0,0 +1,131 @@
+package com.leosanqing.leetcode.medium.struct;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * @description: 运用你所掌握的数据结构,设计和实现一个 LRU (最近最少使用) 缓存机制 。
+ * 实现 LRUCache 类:
+ *