();
- queue.offer(root);
-
- //当前层的节点个数
- int currentLevelCount = 1;
- //下一层的节点个数
- int nextCurrentLevelCount = 0;
- //广度优先遍历到哪一层了
- int level = 0;
-
- while (!queue.isEmpty()) {
- TreeNode node = queue.poll();
- currentLevelCount--;
- if (node.left != null) {
- queue.offer(node.left);
- nextCurrentLevelCount++;
- }
- if (node.right != null) {
- queue.offer(node.right);
- nextCurrentLevelCount++;
- }
- if (currentLevelCount == 0) {
- currentLevelCount = nextCurrentLevelCount;
- nextCurrentLevelCount = 0;
- level++;
- }
- }
- return level;
- }
-
- /**
- * 深度优先搜索的"一根筋"似的检测
- */
- public int maxDepthRecursion(TreeNode root) {
- if (root == null) {
- return 0;
- }
- if (root.left == null) {
- return maxDepthRecursion(root.right) + 1;
- }
- if (root.right == null) {
- return maxDepthRecursion(root.left) + 1;
- }
- return Math.max(maxDepthRecursion(root.left), maxDepthRecursion(root.right)) + 1;
- }
-
- public TreeNode createTree() {
- TreeNode node_3 = new TreeNode();
- node_3.val = 3;
- TreeNode node_9 = new TreeNode();
- node_9.val = 9;
- TreeNode node_20 = new TreeNode();
- node_20.val = 20;
- TreeNode node_15 = new TreeNode();
- node_15.val = 15;
- TreeNode node_7 = new TreeNode();
- node_7.val = 7;
- node_3.left = node_9;
- node_3.right = node_20;
- node_9.left = node_15;
- node_20.right = node_7;
- return node_3;
- }
-
- public static void main(String[] args) {
- MaxDepth maxDepth = new MaxDepth();
- int level = maxDepth.maxDepth(maxDepth.createTree());
- System.out.println("最大层级数为:" + level);
- int level2 = maxDepth.maxDepthRecursion(maxDepth.createTree());
- System.out.println("最大层级数为:" + level2);
- }
-}
diff --git a/src/main/java/ds/MaxProfit.java b/src/main/java/ds/MaxProfit.java
deleted file mode 100644
index 0940a00..0000000
--- a/src/main/java/ds/MaxProfit.java
+++ /dev/null
@@ -1,52 +0,0 @@
-package ds;
-
-/**
- * 给定一个数组,它的第 i 个元素是一支给定股票第 i 天的价格。
- *
- * 设计一个算法来计算你所能获取的最大利润。你可以尽可能地完成更多的交易(多次买卖一支股票)。
- *
- * 注意:你不能同时参与多笔交易(你必须在再次购买前出售掉之前的股票)。
- *
- * 示例 1:
- *
- * 输入: [7,1,5,3,6,4]
- * 输出: 7
- * 解释: 在第 2 天(股票价格 = 1)的时候买入,在第 3 天(股票价格 = 5)的时候卖出, 这笔交易所能获得利润 = 5-1 = 4 。
- * 随后,在第 4 天(股票价格 = 3)的时候买入,在第 5 天(股票价格 = 6)的时候卖出, 这笔交易所能获得利润 = 6-3 = 3 。
- * 示例 2:
- *
- * 输入: [1,2,3,4,5]
- * 输出: 4
- * 解释: 在第 1 天(股票价格 = 1)的时候买入,在第 5 天 (股票价格 = 5)的时候卖出, 这笔交易所能获得利润 = 5-1 = 4 。
- * 注意你不能在第 1 天和第 2 天接连购买股票,之后再将它们卖出。
- * 因为这样属于同时参与了多笔交易,你必须在再次购买前出售掉之前的股票。
- * 示例 3:
- *
- * 输入: [7,6,4,3,1]
- * 输出: 0
- * 解释: 在这种情况下, 没有交易完成, 所以最大利润为 0。
- *
- * @author yangyi 2019年01月27日21:34:41
- */
-public class MaxProfit {
-
- public int maxProfit(int[] prices) {
- int profit = 0;
- for (int i = 0; i < prices.length - 1; i++) { - if (prices[i + 1]> prices[i]) {
- profit += prices[i + 1] - prices[i];
- }
- }
- return profit;
- }
-
- public static void main(String[] args) {
- int[] a = {7, 1, 5, 3, 6, 4};
- int[] b = {1, 2, 3, 4, 5};
- int[] c = {7, 6, 4, 3, 1};
- MaxProfit maxProfit = new MaxProfit();
- System.out.println(maxProfit.maxProfit(a));
- System.out.println(maxProfit.maxProfit(b));
- System.out.println(maxProfit.maxProfit(c));
- }
-}
diff --git a/src/main/java/ds/MaxSubArray.java b/src/main/java/ds/MaxSubArray.java
deleted file mode 100644
index 58140bd..0000000
--- a/src/main/java/ds/MaxSubArray.java
+++ /dev/null
@@ -1,52 +0,0 @@
-package ds;
-
-import java.util.Queue;
-import java.util.concurrent.DelayQueue;
-
-/**
- * 给定一个整数数组 nums ,找到一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。
- *
- * 示例:
- *
- * 输入: [-2,1,-3,4,-1,2,1,-5,4],
- * 输出: 6
- * 解释: 连续子数组 [4,-1,2,1] 的和最大,为 6。
- * 进阶:
- *
- * 如果你已经实现复杂度为 O(n) 的解法,尝试使用更为精妙的分治法求解。
- */
-public class MaxSubArray {
-
- private static final Queue queue = new DelayQueue();
-
- public int maxSubArray(int[] nums) {
- if (nums == null || nums.length == 0) {
- return 0;
- }
- int maxSum = nums[0];
- int sum = 0;
- int numSize = nums.length;
- for (int i = 0; i < numSize; i++) { - sum += nums[i]; - if (sum> maxSum) {
- maxSum = sum;
- }
- if (sum <= 0) { - sum = 0; - } - } - - synchronized (queue){ - - } - return maxSum; - } - - public static void main(String[] args) { - int[] nums = {-2, 1, -3, 4, -1, 2, 1, -5, 4}; - int[] nums_2 = {-1}; - MaxSubArray maxSubArray = new MaxSubArray(); - System.out.println("连续数组的最大和为:" + maxSubArray.maxSubArray(nums)); - System.out.println("连续数组的最大和为:" + maxSubArray.maxSubArray(nums_2)); - } -} diff --git a/src/main/java/ds/MinDepth.java b/src/main/java/ds/MinDepth.java deleted file mode 100644 index 7a5b1de..0000000 --- a/src/main/java/ds/MinDepth.java +++ /dev/null @@ -1,69 +0,0 @@ -package ds; - -/** - * 给定一个二叉树,找出其最小深度。 - *
- * 最小深度是从根节点到最近叶子节点的最短路径上的节点数量。
- *
- * 说明: 叶子节点是指没有子节点的节点。
- *
- * 示例:
- *
- * 给定二叉树 [3,9,20,null,null,15,7],
- *
- * 3
- * / \
- * 9 20
- * / \
- * 15 7
- * 返回它的最小深度 2.
- *
- * @author yangyi 2019年01月28日23:24:57
- */
-public class MinDepth {
-
- public class TreeNode {
- int val;
- TreeNode left;
- TreeNode right;
- }
-
- public int minDepth(TreeNode root) {
- if (root == null) {
- return 0;
- }
- if (root.left == null) {
- return minDepth(root.right) + 1;
- }
- if (root.right == null) {
- return minDepth(root.left) + 1;
- }
- return Math.min(minDepth(root.left), minDepth(root.right)) + 1;
- }
-
-
- public TreeNode createTree() {
- TreeNode node_3 = new TreeNode();
- node_3.val = 3;
- TreeNode node_9 = new TreeNode();
- node_9.val = 9;
- TreeNode node_20 = new TreeNode();
- node_20.val = 20;
- TreeNode node_15 = new TreeNode();
- node_15.val = 15;
- TreeNode node_7 = new TreeNode();
- node_7.val = 7;
- node_3.left = node_9;
- node_3.right = node_20;
- node_20.left = node_15;
- node_20.right = node_7;
- return node_3;
- }
-
- public static void main(String[] args) {
- MinDepth minDepth = new MinDepth();
- TreeNode node = minDepth.createTree();
- int min = minDepth.minDepth(node);
- System.out.println("最小深度为:" + min);
- }
-}
diff --git a/src/main/java/ds/MyQueue.java b/src/main/java/ds/MyQueue.java
deleted file mode 100644
index b9d3270..0000000
--- a/src/main/java/ds/MyQueue.java
+++ /dev/null
@@ -1,110 +0,0 @@
-package ds;
-
-import java.util.Stack;
-
-/**
- * 用两个栈实现一个队列
- *
- * 使用栈实现队列的下列操作:
- *
- * push(x) -- 将一个元素放入队列的尾部。
- * pop() -- 从队列首部移除元素。
- * peek() -- 返回队列首部的元素。
- * empty() -- 返回队列是否为空。
- * 示例:
- *
- * MyQueue queue = new MyQueue();
- *
- * queue.push(1);
- * queue.push(2);
- * queue.peek(); // 返回 1
- * queue.pop(); // 返回 1
- * queue.empty(); // 返回 false
- * 说明:
- *
- * 你只能使用标准的栈操作 -- 也就是只有 push to top, peek/pop from top, size, 和 is empty 操作是合法的。
- * 你所使用的语言也许不支持栈。你可以使用 list 或者 deque(双端队列)来模拟一个栈,只要是标准的栈操作即可。
- * 假设所有操作都是有效的 (例如,一个空的队列不会调用 pop 或者 peek 操作)。
- *
- * @author yangyi 2019年02月11日16:11:01
- */
-public class MyQueue {
-
- private Stack stack1;
- private Stack stack2;
-
- /**
- * 初始化队列
- */
- public MyQueue() {
- stack1 = new Stack();
- stack2 = new Stack();
- }
-
- /**
- * 入队
- */
- public void push(int x) {
- stack1.push(x);
- }
-
- /**
- * 出队
- */
- public int pop() {
- if (stack2.isEmpty()) {
- while (stack1.size()> 0) {
- Integer target = stack1.peek();
- stack2.push(target);
- stack1.pop();
- }
- }
-
- if (stack2.isEmpty()) {
- return 0;
- }
-
- Integer result = stack2.peek();
- stack2.pop();
- return result;
- }
-
- /**
- * 查看队头
- */
- public int peek() {
- if (stack2.isEmpty()) {
- while (stack1.size()> 0) {
- Integer target = stack1.peek();
- stack2.push(target);
- stack1.pop();
- }
- }
-
- if (stack2.isEmpty()) {
- return 0;
- }
-
- return stack2.peek();
- }
-
- /**
- * 返回是否为空
- */
- public boolean empty() {
- return stack1.isEmpty() && stack2.isEmpty();
- }
-
- public static void main(String[] args) {
- MyQueue queue = new MyQueue();
- queue.push(1);
- queue.push(2);
- //返回 1
- System.out.println(queue.peek());
- //返回 1
- System.out.println(queue.pop());
- //返回 false
- System.out.println(queue.empty());
- }
-
-}
diff --git a/src/main/java/ds/MyStack.java b/src/main/java/ds/MyStack.java
deleted file mode 100644
index f61a4fb..0000000
--- a/src/main/java/ds/MyStack.java
+++ /dev/null
@@ -1,106 +0,0 @@
-package ds;
-
-import java.util.ArrayDeque;
-import java.util.Queue;
-
-/**
- * 用两个队列实现一个栈
- *
- *
- * 使用队列实现栈的下列操作:
- *
- * push(x) -- 元素 x 入栈
- * pop() -- 移除栈顶元素
- * top() -- 获取栈顶元素
- * empty() -- 返回栈是否为空
- * 注意:
- *
- * 你只能使用队列的基本操作-- 也就是 push to back, peek/pop from front, size, 和 is empty 这些操作是合法的。
- * 你所使用的语言也许不支持队列。 你可以使用 list 或者 deque(双端队列)来模拟一个队列 , 只要是标准的队列操作即可。
- * 你可以假设所有操作都是有效的(例如, 对一个空的栈不会调用 pop 或者 top 操作)。
- *
- * @author yangyi 2019年02月11日16:56:09
- */
-public class MyStack {
-
- private Queue queue1;
- private Queue queue2;
-
- /**
- * 初始化两个队列
- */
- public MyStack() {
- queue1 = new ArrayDeque();
- queue2 = new ArrayDeque();
- }
-
- /**
- * 进栈
- */
- public void push(int x) {
- //两个队列,哪个不为空进哪个
- if (!queue1.isEmpty()) {
- queue1.offer(x);
- } else {
- queue2.offer(x);
- }
- }
-
- /**
- * 出栈
- */
- public int pop() {
- //最后一个进队的元素留下,其余的换到另一个队列中去
- if (!queue1.isEmpty()) {
- while (queue1.size()> 1) {
- queue2.offer(queue1.poll());
- }
- //最后一个剩在了队列中,出队
- return queue1.poll();
- } else {
- while (queue2.size()> 1) {
- queue1.offer(queue2.poll());
- }
- return queue2.poll();
- }
- }
-
- /**
- * 查询栈顶元素
- */
- public int top() {
- if (!queue1.isEmpty()) {
- while (queue1.size()> 1) {
- queue2.offer(queue1.poll());
- }
- int result = queue1.peek();
- queue1.poll();
- queue2.offer(result);
- return result;
- } else {
- while (queue2.size()> 1) {
- queue1.offer(queue2.poll());
- }
- int result = queue2.peek();
- queue2.poll();
- queue1.offer(result);
- return result;
- }
- }
-
- public boolean empty() {
- return queue1.isEmpty() && queue2.isEmpty();
- }
-
- public static void main(String[] args) {
- MyStack obj = new MyStack();
- obj.push(1);
- obj.push(2);
- int param_2 = obj.pop();
- int param_3 = obj.top();
- boolean param_4 = obj.empty();
- System.out.println(param_2);
- System.out.println(param_3);
- System.out.println(param_4);
- }
-}
diff --git a/src/main/java/ds/TopKFrequent.java b/src/main/java/ds/TopKFrequent.java
deleted file mode 100644
index 2f95916..0000000
--- a/src/main/java/ds/TopKFrequent.java
+++ /dev/null
@@ -1,68 +0,0 @@
-package ds;
-
-import java.util.*;
-
-/**
- * 前K个高频元素
- *
- * 给定一个非空的整数数组,返回其中出现频率前 k 高的元素。
- *
- * 示例 1:
- *
- * 输入: nums = [1,1,1,2,2,3], k = 2
- * 输出: [1,2]
- * 示例 2:
- *
- * 输入: nums = [1], k = 1
- * 输出: [1]
- * 说明:
- *
- * 你可以假设给定的 k 总是合理的,且 1 ≤ k ≤ 数组中不相同的元素的个数。
- * 你的算法的时间复杂度必须优于 O(n log n) , n 是数组的大小。
- *
- * @author yangyi 2019年02月17日23:40:36
- */
-public class TopKFrequent {
-
- public List topKFrequent(int[] nums, int k) {
- Map map = new HashMap();
- for (int i = 0; i < nums.length; i++) { - if (!map.containsKey(nums[i])) { - map.put(nums[i], 1); - } else { - map.put(nums[i], map.get(nums[i]) + 1); - } - } - //按照get出来的元素对应的次数排序 - PriorityQueue priorityQueue = new PriorityQueue(k,
- new Comparator() {
- @Override
- public int compare(Integer o1, Integer o2) {
- return map.get(o1).compareTo(map.get(o2));
- }
- });
- //将元素加入小顶堆
- for (Map.Entry integerIntegerEntry : map.entrySet()) {
- if (priorityQueue.size() < k) { - priorityQueue.offer(integerIntegerEntry.getKey()); - } else if (integerIntegerEntry.getValue()> map.get(priorityQueue.peek())) {
- //比较元素出现的次数,如果次数比小顶堆的堆顶大,则取而代之,自己做堆顶
- priorityQueue.poll();
- priorityQueue.offer(integerIntegerEntry.getKey());
- }
- }
- List list = new ArrayList(k);
- list.addAll(priorityQueue);
- return list;
- }
-
- public static void main(String[] args) {
- int[] a = {1, 1, 1, 2, 2, 3};
- int[] b = {1};
- int[] c = {4, 1, -1, 2, -1, 2, 3};
- TopKFrequent topKFrequent = new TopKFrequent();
- System.out.println(Arrays.toString(topKFrequent.topKFrequent(a, 2).toArray()));
- System.out.println(Arrays.toString(topKFrequent.topKFrequent(b, 1).toArray()));
- System.out.println(Arrays.toString(topKFrequent.topKFrequent(c, 2).toArray()));
- }
-}
diff --git a/src/main/java/ds/ValidParentheses.java b/src/main/java/ds/ValidParentheses.java
deleted file mode 100644
index 0129aea..0000000
--- a/src/main/java/ds/ValidParentheses.java
+++ /dev/null
@@ -1,62 +0,0 @@
-package ds;
-
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Stack;
-
-/**
- * 判断有效的括号
- *
- * @author yangyi 2019年01月22日13:48:19
- */
-public class ValidParentheses {
-
- private Map map;
-
- {
- map = new HashMap();
- map.put(')', '(');
- map.put(']', '[');
- map.put('}', '{');
- }
-
- public boolean isValid(String value) {
- //准备一个映射来保存括号关系,右括号作为key是为了更好的适应map的contain查找方法来查找key对应的value
- Stack characterStack = new Stack();
- for (int i = 0; i < value.length(); i++) { - char target = value.charAt(i); - if (map.containsKey(target)) { - //如果遍历的字符串中的字符是右括号,从栈中弹出一个先前压入栈的左括号和它配对 - char pop; - if (characterStack.isEmpty()) { - pop = '#'; - } else { - pop = characterStack.pop(); - } - //如果从栈中拿出的元素不符合映射表的规则,结论已经有了,一切都该结束了 - if (!(pop == map.get(target))) { - return false; - } - } else { - //如果遍历的字符串中的字符是左括号,放入栈中 - characterStack.push(target); - } - } - return characterStack.isEmpty(); - } - - public static void main(String[] args) { - String one = "()"; - String two = "()[]"; - String three = "([)]"; - String four = "(((([]))"; - String five = "]][["; - - ValidParentheses validParentheses = new ValidParentheses(); - System.out.println(one + (validParentheses.isValid(one) ? "有效" : "无效")); - System.out.println(two + (validParentheses.isValid(two) ? "有效" : "无效")); - System.out.println(three + (validParentheses.isValid(three) ? "有效" : "无效")); - System.out.println(four + (validParentheses.isValid(four) ? "有效" : "无效")); - System.out.println(five + (validParentheses.isValid(five) ? "有效" : "无效")); - } -} diff --git a/src/main/java/ds/array/leetcode1486/Solution.java b/src/main/java/ds/array/leetcode1486/Solution.java new file mode 100644 index 0000000..0cbc32e --- /dev/null +++ b/src/main/java/ds/array/leetcode1486/Solution.java @@ -0,0 +1,25 @@ +package ds.array.leetcode1486; + +/** + * 数组异或操作 + * LeetCode 1486 https://leetcode-cn.com/problems/xor-operation-in-an-array/ + * + * @author yangyi 2021年05月07日14:20:37 + */ +public class Solution { + + public int xorOperation(int n, int start) { + int result = 0; + for (int i = 0; i < n; i++) { + result ^= start + 2 * i; + } + return result; + } + + public static void main(String[] args) { + System.out.println(new Solution().xorOperation(5, 0)); + System.out.println(new Solution().xorOperation(4, 3)); + System.out.println(new Solution().xorOperation(1, 7)); + System.out.println(new Solution().xorOperation(10, 5)); + } +} diff --git a/src/main/java/ds/bfs/leetcode102/Solution.java b/src/main/java/ds/bfs/leetcode102/Solution.java new file mode 100644 index 0000000..2edd2ae --- /dev/null +++ b/src/main/java/ds/bfs/leetcode102/Solution.java @@ -0,0 +1,70 @@ +package ds.bfs.leetcode102; + +import java.util.Arrays; +import java.util.LinkedList; +import java.util.List; +import java.util.Queue; + +/** + * 二叉树的层序遍历 + * LeetCode 102 https://leetcode-cn.com/problems/binary-tree-level-order-traversal/ + * + * @author yangyi 2021年01月26日18:04:53 + */ +public class Solution { + + public class TreeNode { + int val; + TreeNode left; + TreeNode right; + + TreeNode(int x) { + val = x; + } + } + + public List> levelOrder(TreeNode root) {
+ if (root == null) {
+ return new LinkedList();
+ }
+ List> result = new LinkedList();
+ Queue queue = new LinkedList
();
+ queue.offer(root);
+ while (!queue.isEmpty()) {
+ int size = queue.size();
+ List levelResult = new LinkedList();
+ for (int i = 0; i < size; i++) { + TreeNode cur = queue.poll(); + if (cur != null) { + levelResult.add(cur.val); + } + if (cur.left != null) { + queue.offer(cur.left); + } + if (cur.right != null) { + queue.offer(cur.right); + } + } + result.add(levelResult); + } + return result; + } + + private TreeNode createTree() { + TreeNode node_3 = new TreeNode(3); + TreeNode node_9 = new TreeNode(9); + TreeNode node_20 = new TreeNode(20); + TreeNode node_15 = new TreeNode(15); + TreeNode node_7 = new TreeNode(7); + node_3.left = node_9; + node_3.right = node_20; + node_20.left = node_15; + node_20.right = node_7; + return node_3; + } + + public static void main(String[] args) { + Solution solution = new Solution(); + System.out.println(Arrays.toString(solution.levelOrder(solution.createTree()).toArray())); + } +} diff --git a/src/main/java/ds/bfs/leetcode103/Solution.java b/src/main/java/ds/bfs/leetcode103/Solution.java new file mode 100644 index 0000000..0d72cb2 --- /dev/null +++ b/src/main/java/ds/bfs/leetcode103/Solution.java @@ -0,0 +1,79 @@ +package ds.bfs.leetcode103; + +import java.util.LinkedList; +import java.util.List; +import java.util.Queue; + +/** + * 二叉树的锯齿形层序遍历 + * LeetCode 103 https://leetcode-cn.com/problems/binary-tree-zigzag-level-order-traversal/ + * + * @author yangyi 2021年04月30日18:53:44 + */ +public class Solution { + + public static class TreeNode { + int val; + TreeNode left; + TreeNode right; + + TreeNode(int x) { + val = x; + } + } + + public List> zigzagLevelOrder(TreeNode root) {
+ if (root == null) {
+ return new LinkedList();
+ }
+ List> result = new LinkedList();
+ Queue queue = new LinkedList
();
+ queue.offer(root);
+ int level = 0;
+ while (!queue.isEmpty()) {
+ int size = queue.size();
+ LinkedList levelList = new LinkedList();
+ for (int i = 0; i < size; i++) { + TreeNode cur = queue.poll(); + if (cur != null) { + if (level % 2 == 0) { + levelList.addLast(cur.val); + } else { + levelList.addFirst(cur.val); + } + } + if (cur.left != null) { + queue.offer(cur.left); + } + if (cur.right != null) { + queue.offer(cur.right); + } + } + result.add(levelList); + level++; + } + return result; + } + + public static void main(String[] args) { + TreeNode node_3 = new TreeNode(3); + TreeNode node_9 = new TreeNode(9); + TreeNode node_20 = new TreeNode(20); + TreeNode node_15 = new TreeNode(15); + TreeNode node_7 = new TreeNode(7); + + node_3.left = node_9; + node_3.right = node_20; + node_20.left = node_15; + node_20.right = node_7; + + Solution zigzagLevelOrder = new Solution(); + List> result = zigzagLevelOrder.zigzagLevelOrder(node_3);
+ for (List integers : result) {
+ for (Integer integer : integers) {
+ System.out.print(integer + " ");
+ }
+ System.out.println();
+ }
+ }
+}
diff --git a/src/main/java/ds/bfs/leetcode107/Solution.java b/src/main/java/ds/bfs/leetcode107/Solution.java
new file mode 100644
index 0000000..3171073
--- /dev/null
+++ b/src/main/java/ds/bfs/leetcode107/Solution.java
@@ -0,0 +1,81 @@
+package ds.bfs.leetcode107;
+
+import java.util.Arrays;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Queue;
+
+/**
+ * 二叉树的层序遍历 II
+ * LeetCode 107 https://leetcode-cn.com/problems/binary-tree-level-order-traversal-ii/
+ *
+ * @author yangyi 2021年01月26日20:25:22
+ */
+public class Solution {
+
+ public class TreeNode {
+ int val;
+ TreeNode left;
+ TreeNode right;
+
+ TreeNode(int x) {
+ val = x;
+ }
+ }
+
+ public List> levelOrderBottom(TreeNode root) {
+ if (root == null) {
+ return new LinkedList();
+ }
+ List> result = new LinkedList();
+ Queue queue = new LinkedList
();
+ queue.offer(root);
+ while (!queue.isEmpty()) {
+ int size = queue.size();
+ List level = new LinkedList();
+ for (int i = 0; i < size; i++) { + TreeNode cur = queue.poll(); + if (cur != null) { + level.add(cur.val); + } + if (cur.left != null) { + queue.offer(cur.left); + } + if (cur.right != null) { + queue.offer(cur.right); + } + } + result.add(level); + } + return reserveArray(0, result.size() - 1, result); + } + + private List> reserveArray(int start, int end, List> target) {
+ while (start < end) { + List temp = target.get(start);
+ target.set(start, target.get(end));
+ target.set(end, temp);
+ start++;
+ end--;
+ }
+ return target;
+ }
+
+ private TreeNode createTree() {
+ TreeNode node_3 = new TreeNode(3);
+ TreeNode node_9 = new TreeNode(9);
+ TreeNode node_20 = new TreeNode(20);
+ TreeNode node_15 = new TreeNode(15);
+ TreeNode node_7 = new TreeNode(7);
+ node_3.left = node_9;
+ node_3.right = node_20;
+ node_20.left = node_15;
+ node_20.right = node_7;
+ return node_3;
+ }
+
+ public static void main(String[] args) {
+ Solution solution = new Solution();
+ System.out.println(Arrays.toString(solution.levelOrderBottom(solution.createTree()).toArray()));
+ }
+}
diff --git a/src/main/java/ds/bfs/leetcode111/Solution.java b/src/main/java/ds/bfs/leetcode111/Solution.java
new file mode 100644
index 0000000..7973cc2
--- /dev/null
+++ b/src/main/java/ds/bfs/leetcode111/Solution.java
@@ -0,0 +1,76 @@
+package ds.bfs.leetcode111;
+
+import java.util.LinkedList;
+import java.util.Queue;
+
+/**
+ * 二叉树的最小深度
+ * LeetCode 111 https://leetcode-cn.com/problems/minimum-depth-of-binary-tree/
+ *
+ * @author yangyi 2021年01月26日16:18:38
+ */
+public class Solution {
+
+ public class TreeNode {
+ int val;
+ TreeNode left;
+ TreeNode right;
+
+ TreeNode() {
+ }
+
+ TreeNode(int val) {
+ this.val = val;
+ }
+
+ TreeNode(int val, TreeNode left, TreeNode right) {
+ this.val = val;
+ this.left = left;
+ this.right = right;
+ }
+ }
+
+ private TreeNode createTree() {
+ TreeNode node_3 = new TreeNode(3);
+ TreeNode node_9 = new TreeNode(9);
+ TreeNode node_20 = new TreeNode(20);
+ TreeNode node_15 = new TreeNode(15);
+ TreeNode node_7 = new TreeNode(7);
+ node_3.left = node_9;
+ node_3.right = node_20;
+ node_20.left = node_15;
+ node_20.right = node_7;
+ return node_3;
+ }
+
+ public int minDepth(TreeNode root) {
+ if (root == null) {
+ return 0;
+ }
+ Queue treeNodeQueue = new LinkedList
();
+ treeNodeQueue.offer(root);
+ int minDepth = 1;
+ while (!treeNodeQueue.isEmpty()) {
+ int size = treeNodeQueue.size();
+ for (int i = 0; i < size; i++) { + TreeNode cur = treeNodeQueue.poll(); + if (cur.left == null && cur.right == null) { + return minDepth; + } + if (cur.left != null) { + treeNodeQueue.offer(cur.left); + } + if (cur.right != null) { + treeNodeQueue.offer(cur.right); + } + } + minDepth++; + } + return minDepth; + } + + public static void main(String[] args) { + Solution solution = new Solution(); + System.out.println(solution.minDepth(solution.createTree())); + } +} diff --git a/src/main/java/ds/bfs/leetcode117/Solution.java b/src/main/java/ds/bfs/leetcode117/Solution.java new file mode 100644 index 0000000..162e811 --- /dev/null +++ b/src/main/java/ds/bfs/leetcode117/Solution.java @@ -0,0 +1,110 @@ +package ds.bfs.leetcode117; + +import java.util.ArrayDeque; +import java.util.Arrays; +import java.util.LinkedList; +import java.util.List; +import java.util.Queue; + +/** + * 填充每个节点的下一个右侧节点指针II + * LeetCode 117 https://leetcode-cn.com/problems/populating-next-right-pointers-in-each-node-ii/ + * + * @author yangyi 2021年05月03日11:41:19 + */ +public class Solution { + + class Node { + public int val; + public Node left; + public Node right; + public Node next; + + public Node() { + } + + public Node(int _val) { + val = _val; + } + + public Node(int _val, Node _left, Node _right, Node _next) { + val = _val; + left = _left; + right = _right; + next = _next; + } + } + + public Node connect(Node root) { + if (root == null) { + return null; + } + Queue queue = new LinkedList();
+ queue.offer(root);
+ while (!queue.isEmpty()) {
+ int size = queue.size();
+ Node last = null;
+ for (int i = 0; i < size; i++) { + Node cur = queue.poll(); + if (cur.left != null) { + queue.offer(cur.left); + } + if (cur.right != null) { + queue.offer(cur.right); + } + if (i != 0) { + last.next = cur; + } + last = cur; + } + } + return root; + } + + private Node createTree() { + Node node_1 = new Node(1); + Node node_2 = new Node(2); + Node node_3 = new Node(3); + Node node_4 = new Node(4); + Node node_5 = new Node(5); + Node node_7 = new Node(7); + node_1.left = node_2; + node_1.right = node_3; + node_2.left = node_4; + node_2.right = node_5; + node_3.right = node_7; + return node_1; + } + + private List levelOrder(Node root) {
+ if (root == null) {
+ return new LinkedList();
+ }
+ List result = new LinkedList();
+ Queue queue = new ArrayDeque();
+ queue.offer(root);
+ while (!queue.isEmpty()) {
+ int size = queue.size();
+ for (int i = 0; i < size; i++) { + Node cur = queue.poll(); + if (cur != null) { + result.add(cur.val); + } + if (cur.left != null) { + queue.offer(cur.left); + } + if (cur.right != null) { + queue.offer(cur.right); + } + } + } + return result; + } + + public static void main(String[] args) { + Solution solution = new Solution(); + Node root = solution.createTree(); + Node result = solution.connect(root); + System.out.println(Arrays.toString(solution.levelOrder(result).stream().mapToInt(value -> value).toArray()));
+ }
+}
diff --git a/src/main/java/ds/bfs/leetcode199/Solution.java b/src/main/java/ds/bfs/leetcode199/Solution.java
new file mode 100644
index 0000000..6f32bd5
--- /dev/null
+++ b/src/main/java/ds/bfs/leetcode199/Solution.java
@@ -0,0 +1,63 @@
+package ds.bfs.leetcode199;
+
+import java.util.*;
+
+/**
+ * 二叉树的右视图
+ * LeetCode 199 https://leetcode-cn.com/problems/binary-tree-right-side-view/
+ *
+ * @author yangyi 2021年01月26日20:33:04
+ */
+public class Solution {
+
+ public static class TreeNode {
+ int val;
+ TreeNode left;
+ TreeNode right;
+
+ TreeNode(int x) {
+ val = x;
+ }
+ }
+
+ public List rightSideView(TreeNode root) {
+ if (root == null) {
+ return new LinkedList();
+ }
+ Queue queue = new LinkedList
();
+ List result = new LinkedList();
+ queue.offer(root);
+ while (!queue.isEmpty()) {
+ int size = queue.size();
+ for (int i = 0; i < size; i++) { + TreeNode cur = queue.poll(); + if (cur != null && i == size - 1) { + result.add(cur.val); + } + if (cur.left != null) { + queue.offer(cur.left); + } + if (cur.right != null) { + queue.offer(cur.right); + } + } + } + return result; + } + + public static void main(String[] args) { + TreeNode one = new TreeNode(1); + TreeNode two = new TreeNode(2); + TreeNode three = new TreeNode(3); + TreeNode five = new TreeNode(5); + TreeNode four = new TreeNode(4); + + one.left = two; + one.right = three; + two.right = five; + three.right = four; + + Solution solution = new Solution(); + System.out.println(Arrays.toString(solution.rightSideView(one).toArray())); + } +} diff --git a/src/main/java/ds/bfs/leetcode429/Solution.java b/src/main/java/ds/bfs/leetcode429/Solution.java new file mode 100644 index 0000000..984d121 --- /dev/null +++ b/src/main/java/ds/bfs/leetcode429/Solution.java @@ -0,0 +1,56 @@ +package ds.bfs.leetcode429; + +import java.util.LinkedList; +import java.util.List; +import java.util.Queue; + +/** + * N叉树的层序遍历 + * LeetCode 429 https://leetcode-cn.com/problems/n-ary-tree-level-order-traversal/ + * + * @author yangyi 2021年01月27日00:34:06 + */ +public class Solution { + + class Node { + public int val; + public List children;
+
+ public Node() {
+ }
+
+ public Node(int _val) {
+ val = _val;
+ }
+
+ public Node(int _val, List _children) {
+ val = _val;
+ children = _children;
+ }
+ }
+
+ public List> levelOrder(Node root) {
+ if (root == null) {
+ return new LinkedList();
+ }
+ List> result = new LinkedList();
+ Queue queue = new LinkedList();
+ queue.offer(root);
+ while (!queue.isEmpty()) {
+ int size = queue.size();
+ List level = new LinkedList();
+ for (int i = 0; i < size; i++) { + Node node = queue.poll(); + level.add(node.val); + for (Node child : node.children) { + if (child.children != null) { + queue.offer(child); + } + } + } + result.add(level); + } + return result; + } + +} diff --git a/src/main/java/ds/bfs/leetcode637/Solution.java b/src/main/java/ds/bfs/leetcode637/Solution.java new file mode 100644 index 0000000..c9f9a79 --- /dev/null +++ b/src/main/java/ds/bfs/leetcode637/Solution.java @@ -0,0 +1,71 @@ +package ds.bfs.leetcode637; + +import java.util.Arrays; +import java.util.LinkedList; +import java.util.List; +import java.util.Queue; + +/** + * 二叉树的层平均值 + * LeetCode 637 https://leetcode-cn.com/problems/average-of-levels-in-binary-tree/ + * + * @author yangyi 2021年01月26日20:46:52 + */ +public class Solution { + + public class TreeNode { + int val; + TreeNode left; + TreeNode right; + + TreeNode(int x) { + val = x; + } + } + + public List averageOfLevels(TreeNode root) {
+ if (root == null) {
+ return new LinkedList();
+ }
+ Queue queue = new LinkedList
();
+ List result = new LinkedList();
+ queue.offer(root);
+ while (!queue.isEmpty()) {
+ int size = queue.size();
+ double sum = 0;
+ for (int i = 0; i < size; i++) { + TreeNode cur = queue.poll(); + if (cur != null) { + sum += cur.val; + } + if (cur.left != null) { + queue.offer(cur.left); + } + if (cur.right != null) { + queue.offer(cur.right); + } + } + sum /= size; + result.add(sum); + } + return result; + } + + private TreeNode createTree() { + TreeNode node_3 = new TreeNode(3); + TreeNode node_9 = new TreeNode(9); + TreeNode node_20 = new TreeNode(20); + TreeNode node_15 = new TreeNode(15); + TreeNode node_7 = new TreeNode(7); + node_3.left = node_9; + node_3.right = node_20; + node_20.left = node_15; + node_20.right = node_7; + return node_3; + } + + public static void main(String[] args) { + Solution solution = new Solution(); + System.out.println(Arrays.toString(solution.averageOfLevels(solution.createTree()).toArray())); + } +} diff --git a/src/main/java/ds/bfs/targetoffer32/Solution.java b/src/main/java/ds/bfs/targetoffer32/Solution.java new file mode 100644 index 0000000..b18c2d4 --- /dev/null +++ b/src/main/java/ds/bfs/targetoffer32/Solution.java @@ -0,0 +1,67 @@ +package ds.bfs.targetoffer32; + +import java.util.Arrays; +import java.util.LinkedList; +import java.util.List; +import java.util.Queue; + +/** + * 从上到下打印二叉树 + * 剑指 Offer 32 - I. https://leetcode-cn.com/problems/cong-shang-dao-xia-da-yin-er-cha-shu-lcof/ + * + * @author yangyi 2021年04月30日17:43:21 + */ +public class Solution { + + public class TreeNode { + int val; + TreeNode left; + TreeNode right; + + TreeNode(int x) { + val = x; + } + } + + public int[] levelOrder(TreeNode root) { + if (root == null) { + return new int[]{}; + } + Queue queue = new LinkedList
();
+ queue.offer(root);
+ List levelList = new LinkedList
();
+ while (!queue.isEmpty()) {
+ int size = queue.size();
+ for (int i = 0; i < size; i++) { + TreeNode cur = queue.poll(); + if (cur != null) { + levelList.add(cur); + } + if (cur.left != null) { + queue.add(cur.left); + } + if (cur.right != null) { + queue.add(cur.right); + } + } + } + return levelList.stream().mapToInt(value -> value.val).toArray();
+ }
+
+ private TreeNode createTree() {
+ TreeNode node_3 = new TreeNode(3);
+ TreeNode node_9 = new TreeNode(9);
+ TreeNode node_20 = new TreeNode(20);
+ TreeNode node_15 = new TreeNode(15);
+ TreeNode node_7 = new TreeNode(7);
+ node_3.left = node_9;
+ node_3.right = node_20;
+ node_20.left = node_15;
+ node_20.right = node_7;
+ return node_3;
+ }
+
+ public static void main(String[] args) {
+ System.out.println(Arrays.toString(new Solution().levelOrder(new Solution().createTree())));
+ }
+}
diff --git a/src/main/java/ds/bfs/targetoffer321/Solution.java b/src/main/java/ds/bfs/targetoffer321/Solution.java
new file mode 100644
index 0000000..393f722
--- /dev/null
+++ b/src/main/java/ds/bfs/targetoffer321/Solution.java
@@ -0,0 +1,67 @@
+package ds.bfs.targetoffer321;
+
+import java.util.Arrays;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Queue;
+
+/**
+ * 从上到下打印二叉树
+ * 剑指 Offer 32 - I. https://leetcode-cn.com/problems/cong-shang-dao-xia-da-yin-er-cha-shu-lcof/
+ *
+ * @author yangyi 2021年04月30日17:43:21
+ */
+public class Solution {
+
+ public class TreeNode {
+ int val;
+ TreeNode left;
+ TreeNode right;
+
+ TreeNode(int x) {
+ val = x;
+ }
+ }
+
+ public int[] levelOrder(TreeNode root) {
+ if (root == null) {
+ return new int[]{};
+ }
+ Queue queue = new LinkedList
();
+ queue.offer(root);
+ List levelList = new LinkedList
();
+ while (!queue.isEmpty()) {
+ int size = queue.size();
+ for (int i = 0; i < size; i++) { + TreeNode cur = queue.poll(); + if (cur != null) { + levelList.add(cur); + } + if (cur.left != null) { + queue.add(cur.left); + } + if (cur.right != null) { + queue.add(cur.right); + } + } + } + return levelList.stream().mapToInt(value -> value.val).toArray();
+ }
+
+ private TreeNode createTree() {
+ TreeNode node_3 = new TreeNode(3);
+ TreeNode node_9 = new TreeNode(9);
+ TreeNode node_20 = new TreeNode(20);
+ TreeNode node_15 = new TreeNode(15);
+ TreeNode node_7 = new TreeNode(7);
+ node_3.left = node_9;
+ node_3.right = node_20;
+ node_20.left = node_15;
+ node_20.right = node_7;
+ return node_3;
+ }
+
+ public static void main(String[] args) {
+ System.out.println(Arrays.toString(new Solution().levelOrder(new Solution().createTree())));
+ }
+}
diff --git a/src/main/java/ds/bfs/targetoffer322/Solution.java b/src/main/java/ds/bfs/targetoffer322/Solution.java
new file mode 100644
index 0000000..2ee575b
--- /dev/null
+++ b/src/main/java/ds/bfs/targetoffer322/Solution.java
@@ -0,0 +1,69 @@
+package ds.bfs.targetoffer322;
+
+import java.util.Arrays;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Queue;
+
+/**
+ * 从上到下打印二叉树 II
+ * 剑指 Offer 32 - II. https://leetcode-cn.com/problems/cong-shang-dao-xia-da-yin-er-cha-shu-ii-lcof/
+ *
+ * @author yangyi 2021年04月30日18:19:43
+ */
+public class Solution {
+
+ public class TreeNode {
+ int val;
+ TreeNode left;
+ TreeNode right;
+
+ TreeNode(int x) {
+ val = x;
+ }
+ }
+
+ private TreeNode createTree() {
+ TreeNode node_3 = new TreeNode(3);
+ TreeNode node_9 = new TreeNode(9);
+ TreeNode node_20 = new TreeNode(20);
+ TreeNode node_15 = new TreeNode(15);
+ TreeNode node_7 = new TreeNode(7);
+ node_3.left = node_9;
+ node_3.right = node_20;
+ node_20.left = node_15;
+ node_20.right = node_7;
+ return node_3;
+ }
+
+ public List> levelOrder(TreeNode root) {
+ if (root == null) {
+ return new LinkedList();
+ }
+ List> result = new LinkedList();
+ Queue queue = new LinkedList
();
+ queue.offer(root);
+ while (!queue.isEmpty()) {
+ int size = queue.size();
+ List levelList = new LinkedList();
+ for (int i = 0; i < size; i++) { + TreeNode cur = queue.poll(); + if (cur != null) { + levelList.add(cur.val); + } + if (cur.left != null) { + queue.offer(cur.left); + } + if (cur.right != null) { + queue.offer(cur.right); + } + } + result.add(levelList); + } + return result; + } + + public static void main(String[] args) { + System.out.println(Arrays.toString(new Solution().levelOrder(new Solution().createTree()).toArray())); + } +} diff --git a/src/main/java/ds/bfs/targetoffer323/Solution.java b/src/main/java/ds/bfs/targetoffer323/Solution.java new file mode 100644 index 0000000..c4587cd --- /dev/null +++ b/src/main/java/ds/bfs/targetoffer323/Solution.java @@ -0,0 +1,75 @@ +package ds.bfs.targetoffer323; + +import java.util.Arrays; +import java.util.LinkedList; +import java.util.List; +import java.util.Queue; + +/** + * 从上到下打印二叉树 III + * 剑指 Offer 32 - III. https://leetcode-cn.com/problems/cong-shang-dao-xia-da-yin-er-cha-shu-iii-lcof/ + * + * @author yangyi 2021年04月30日18:19:54 + */ +public class Solution { + + public class TreeNode { + int val; + Solution.TreeNode left; + Solution.TreeNode right; + + TreeNode(int x) { + val = x; + } + } + + private Solution.TreeNode createTree() { + Solution.TreeNode node_3 = new Solution.TreeNode(3); + Solution.TreeNode node_9 = new Solution.TreeNode(9); + Solution.TreeNode node_20 = new Solution.TreeNode(20); + Solution.TreeNode node_15 = new Solution.TreeNode(15); + Solution.TreeNode node_7 = new Solution.TreeNode(7); + node_3.left = node_9; + node_3.right = node_20; + node_20.left = node_15; + node_20.right = node_7; + return node_3; + } + + public List> levelOrder(Solution.TreeNode root) {
+ if (root == null) {
+ return new LinkedList();
+ }
+ List> result = new LinkedList();
+ Queue queue = new LinkedList
();
+ queue.offer(root);
+ int level = 0;
+ while (!queue.isEmpty()) {
+ int size = queue.size();
+ LinkedList levelList = new LinkedList();
+ for (int i = 0; i < size; i++) { + TreeNode cur = queue.poll(); + if (cur != null) { + if (level % 2 == 0) { + levelList.addLast(cur.val); + } else { + levelList.addFirst(cur.val); + } + } + if (cur.left != null) { + queue.offer(cur.left); + } + if (cur.right != null) { + queue.offer(cur.right); + } + } + result.add(levelList); + level++; + } + return result; + } + + public static void main(String[] args) { + System.out.println(Arrays.toString(new Solution().levelOrder(new Solution().createTree()).toArray())); + } +} diff --git a/src/main/java/ds/binary/BSEndEquals.java b/src/main/java/ds/binary/BSEndEquals.java index 63957f2..c0dc1ad 100644 --- a/src/main/java/ds/binary/BSEndEquals.java +++ b/src/main/java/ds/binary/BSEndEquals.java @@ -1,6 +1,6 @@ package ds.binary; -import ds.InsertSort; +import ds.sort.InsertSort; /** * 查找最后一个值等于给定值的元素 diff --git a/src/main/java/ds/binary/BSEndLess.java b/src/main/java/ds/binary/BSEndLess.java index 94f8b9e..dd4458d 100644 --- a/src/main/java/ds/binary/BSEndLess.java +++ b/src/main/java/ds/binary/BSEndLess.java @@ -1,6 +1,6 @@ package ds.binary; -import ds.InsertSort; +import ds.sort.InsertSort; /** * 查找最后一个小于等于给定值的元素 diff --git a/src/main/java/ds/binary/BSFirstEquals.java b/src/main/java/ds/binary/BSFirstEquals.java index 80fd95c..60fe300 100644 --- a/src/main/java/ds/binary/BSFirstEquals.java +++ b/src/main/java/ds/binary/BSFirstEquals.java @@ -1,6 +1,6 @@ package ds.binary; -import ds.InsertSort; +import ds.sort.InsertSort; /** * 二分查找变种:查找第一个值等于给定值的元素 diff --git a/src/main/java/ds/binary/BSFirstMore.java b/src/main/java/ds/binary/BSFirstMore.java index b806f88..0003d7d 100644 --- a/src/main/java/ds/binary/BSFirstMore.java +++ b/src/main/java/ds/binary/BSFirstMore.java @@ -1,6 +1,6 @@ package ds.binary; -import ds.InsertSort; +import ds.sort.InsertSort; /** * 查找第一个大于等于给定值的元素 diff --git a/src/main/java/ds/binary/BinarySearch.java b/src/main/java/ds/binary/BinarySearch.java index 4586870..845fd3f 100644 --- a/src/main/java/ds/binary/BinarySearch.java +++ b/src/main/java/ds/binary/BinarySearch.java @@ -1,6 +1,6 @@ package ds.binary; -import ds.InsertSort; +import ds.sort.InsertSort; /** * 二分查找(递归和非递归) diff --git a/src/main/java/ds/binary/MySqrt.java b/src/main/java/ds/binary/MySqrt.java deleted file mode 100644 index a41512a..0000000 --- a/src/main/java/ds/binary/MySqrt.java +++ /dev/null @@ -1,53 +0,0 @@ -package ds.binary; - -/** - * 实现 int sqrt(int x) 函数。 - *
- * 计算并返回 x 的平方根,其中 x 是非负整数。
- *
- * 由于返回类型是整数,结果只保留整数的部分,小数部分将被舍去。
- *
- * 示例 1:
- *
- * 输入: 4
- * 输出: 2
- * 示例 2:
- *
- * 输入: 8
- * 输出: 2
- * 说明: 8 的平方根是 2.82842...,
- * 由于返回类型是整数,小数部分将被舍去。
- *
- * @author yangyi 2019年01月29日22:12:30
- */
-public class MySqrt {
-
- public int mySqrt(int x) {
- if (x == 0 || x == 1) {
- return x;
- }
- int start = 0;
- int end = x;
- int result = 0;
- while (start <= end) { - int m = start + ((end - start)>> 1);
- if (m < x / m) { - start = m + 1; - //因为了开平方根取整数,有可能真正的结果比实际的算术结果小,所以要及时记录且返回 - result = m; - } else if (m> x / m) {
- end = m - 1;
- } else {
- return m;
- }
- }
- return result;
- }
-
- public static void main(String[] args) {
- MySqrt mySqrt = new MySqrt();
- int x = 8;
- System.out.println(x + "的二次根号为:" + mySqrt.mySqrt(x));
- }
-
-}
diff --git a/src/main/java/ds/binary/leetcode153/Solution.java b/src/main/java/ds/binary/leetcode153/Solution.java
new file mode 100644
index 0000000..2651106
--- /dev/null
+++ b/src/main/java/ds/binary/leetcode153/Solution.java
@@ -0,0 +1,32 @@
+package ds.binary.leetcode153;
+
+/**
+ * 寻找旋转排序数组中的最小值
+ * LeetCode 153. https://leetcode.cn/problems/find-minimum-in-rotated-sorted-array/
+ *
+ * @author yangyi 2022年07月12日18:29:48
+ */
+public class Solution {
+
+ public int findMin(int[] nums) {
+ int start = 0, end = nums.length - 1;
+ while (start < end) { + int middle = start + (end - start) / 2; + if (nums[middle] < nums[end]) { + end = middle; + } else if (nums[middle]> nums[end]) {
+ start = middle + 1;
+ }
+ }
+ if (start == end) {
+ return nums[start];
+ }
+ return -1;
+ }
+
+ public static void main(String[] args) {
+ System.out.println(new Solution().findMin(new int[]{3, 4, 5, 1, 2}));
+ System.out.println(new Solution().findMin(new int[]{4, 5, 6, 7, 0, 1, 2}));
+ System.out.println(new Solution().findMin(new int[]{11, 13, 15, 17}));
+ }
+}
diff --git a/src/main/java/ds/binary/leetcode162/Solution.java b/src/main/java/ds/binary/leetcode162/Solution.java
new file mode 100644
index 0000000..7db5835
--- /dev/null
+++ b/src/main/java/ds/binary/leetcode162/Solution.java
@@ -0,0 +1,35 @@
+package ds.binary.leetcode162;
+
+/**
+ * 寻找峰值
+ * 山脉数组的峰顶索引
+ * 山峰数组的顶部
+ * LeetCode 162. https://leetcode.cn/problems/find-peak-element/
+ * LeetCode 852. https://leetcode.cn/problems/peak-index-in-a-mountain-array/
+ * 剑指 Offer II 069. https://leetcode.cn/problems/B1IidL/
+ *
+ * @author yangyi 2022年07月12日17:59:02
+ */
+public class Solution {
+
+ public int findPeakElement(int[] nums) {
+ int start = 0, end = nums.length - 1;
+ while (start < end) { + int middle = start + (end - start) / 2; + if (nums[middle]> nums[middle + 1]) {
+ end = middle;
+ } else {
+ start = middle + 1;
+ }
+ }
+ if (start == end) {
+ return start;
+ }
+ return -1;
+ }
+
+ public static void main(String[] args) {
+ System.out.println(new Solution().findPeakElement(new int[]{1, 2, 3, 1}));
+ System.out.println(new Solution().findPeakElement(new int[]{1, 2, 1, 3, 5, 6, 4}));
+ }
+}
diff --git a/src/main/java/ds/binary/leetcode278/Solution.java b/src/main/java/ds/binary/leetcode278/Solution.java
new file mode 100644
index 0000000..4f6b2f6
--- /dev/null
+++ b/src/main/java/ds/binary/leetcode278/Solution.java
@@ -0,0 +1,43 @@
+package ds.binary.leetcode278;
+
+/**
+ * 第一个错误的版本
+ * LeetCode 278. https://leetcode.cn/problems/first-bad-version/
+ *
+ * @author yangyi 2022年07月12日17:33:15
+ */
+public class Solution {
+
+ public int firstBadVersion(int n) {
+ int start = 0, end = n;
+ while (start < end) { + int middle = start + (end - start) / 2; + if (isBadVersion(middle)) { + end = middle; + } else { + start = middle + 1; + } + } + if (start == end && isBadVersion(start)) { + return start; + } + return -1; + } + + private boolean isBadVersion(int version) { + if (version == 3) { + return false; + } else if (version == 5) { + return true; + } else if (version == 4) { + return true; + } else { + return false; + } + } + + public static void main(String[] args) { + Solution solution = new Solution(); + System.out.println(solution.firstBadVersion(5)); + } +} diff --git a/src/main/java/ds/binary/leetcode33/Solution.java b/src/main/java/ds/binary/leetcode33/Solution.java new file mode 100644 index 0000000..2a3b497 --- /dev/null +++ b/src/main/java/ds/binary/leetcode33/Solution.java @@ -0,0 +1,47 @@ +package ds.binary.leetcode33; + +/** + * 搜索旋转排序数组 + * LeetCode 33. https://leetcode.cn/problems/search-in-rotated-sorted-array/ + * + * @author yangyi 2022年07月12日15:29:12 + */ +public class Solution { + + public int search(int[] nums, int target) { + int start = 0, end = nums.length - 1; + if (end == 0) { + return nums[end] == target ? end : -1; + } + while (start <= end) { + int middle = start + (end - start) / 2; + if (nums[middle] == target) { + return middle; + } + if (nums[start] <= nums[middle]) { + if (nums[start] <= target && target < nums[middle]) { + end = middle - 1; + } else { + start = middle + 1; + } + } else if (nums[start]> nums[middle]) {
+ if (nums[middle] < target && target <= nums[end]) { + start = middle + 1; + } else { + end = middle - 1; + } + } + } + return -1; + } + + public static void main(String[] args) { + System.out.println(new Solution().search(new int[]{4, 5, 6, 7, 0, 1, 2}, 0)); + System.out.println(new Solution().search(new int[]{4, 5, 6, 7, 0, 1, 2}, 3)); + System.out.println(new Solution().search(new int[]{1}, 0)); + System.out.println(new Solution().search(new int[]{1}, 1)); + System.out.println(new Solution().search(new int[]{1, 3}, 2)); + System.out.println(new Solution().search(new int[]{3, 1}, 0)); + System.out.println(new Solution().search(new int[]{5, 1, 3}, 3)); + } +} diff --git a/src/main/java/ds/binary/leetcode34/Solution.java b/src/main/java/ds/binary/leetcode34/Solution.java new file mode 100644 index 0000000..a72bfd0 --- /dev/null +++ b/src/main/java/ds/binary/leetcode34/Solution.java @@ -0,0 +1,51 @@ +package ds.binary.leetcode34; + +import java.util.Arrays; + +/** + * 在排序数组中查找元素的第一个和最后一个位置 + * LeetCode 34. https://leetcode.cn/problems/find-first-and-last-position-of-element-in-sorted-array/ + * + * @author yangyi 2022年07月12日18:50:04 + */ +public class Solution { + + public int[] searchRange(int[] nums, int target) { + if (nums == null || nums.length == 0) { + return new int[]{-1, -1}; + } + int left = 0, right = nums.length - 1; + while (left + 1 < right) { + int mid = left + (right - left) / 2; + if (nums[mid] == target) { + if (nums[left] == nums[right]) { + return new int[]{left, right}; + } else if (nums[left] != target) { + left++; + } else if (nums[right] != target) { + right--; + } + } else if (nums[mid] < target) { + left = mid; + } else { + right = mid; + } + } + if (nums[left] == target && nums[right] == target) { + return new int[]{left, right}; + } + if (nums[right] == target) { + return new int[]{right, right}; + } + if (nums[left] == target) { + return new int[]{left, left}; + } + return new int[]{-1, -1}; + } + + public static void main(String[] args) { + System.out.println(Arrays.toString(new Solution().searchRange(new int[]{5, 7, 7, 8, 8, 10}, 8))); + System.out.println(Arrays.toString(new Solution().searchRange(new int[]{5, 7, 7, 8, 8, 10}, 6))); + System.out.println(Arrays.toString(new Solution().searchRange(new int[]{}, 0))); + } +} diff --git a/src/main/java/ds/binary/leetcode374/Solution.java b/src/main/java/ds/binary/leetcode374/Solution.java new file mode 100644 index 0000000..b84cbe4 --- /dev/null +++ b/src/main/java/ds/binary/leetcode374/Solution.java @@ -0,0 +1,51 @@ +package ds.binary.leetcode374; + +/** + * 猜数字大小 + * LeetCode 374. https://leetcode.cn/problems/guess-number-higher-or-lower/ + * + * @author yangyi 2022年07月12日15:04:14 + */ +public class Solution { + + private final int pick; + + public Solution(int pick) { + this.pick = pick; + } + + public int guessNumber(int num) { + int start = 0, end = num; + while (start <= end) { + int middle = start + (end - start) / 2; + if (guess(middle) == 1) { + start = middle + 1; + } else if (guess(middle) == -1) { + end = middle - 1; + } else { + return middle; + } + } + return -1; + } + + /** + * Forward declaration of guess API. + * + * @param num your guess + * @return -1 if num is lower than the guess number + * 1 if num is higher than the guess number + * otherwise return 0 + * int guess(int num); + */ + private int guess(int num) { + return Integer.compare(pick, num); + } + + public static void main(String[] args) { + System.out.println(new Solution(6).guessNumber(10)); + System.out.println(new Solution(1).guessNumber(1)); + System.out.println(new Solution(1).guessNumber(2)); + System.out.println(new Solution(2).guessNumber(2)); + } +} diff --git a/src/main/java/ds/binary/leetcode69/Solution.java b/src/main/java/ds/binary/leetcode69/Solution.java new file mode 100644 index 0000000..b5253ec --- /dev/null +++ b/src/main/java/ds/binary/leetcode69/Solution.java @@ -0,0 +1,33 @@ +package ds.binary.leetcode69; + +/** + * x的平方根 + * LeetCode 69. https://leetcode.cn/problems/sqrtx/ + * + * @author yangyi 2022年07月12日14:16:11 + */ +public class Solution { + + public int mySqrt(int x) { + if (x == 0 || x == 1) { + return x; + } + int start = 0, end = x; + while (start <= end) { + int middle = start + (end - start) / 2; + if (middle < x / middle) { + start = middle + 1; + } else if (middle> x / middle) {
+ end = middle - 1;
+ } else {
+ return middle;
+ }
+ }
+ return end;
+ }
+
+ public static void main(String[] args) {
+ System.out.println(new Solution().mySqrt(4));
+ System.out.println(new Solution().mySqrt(8));
+ }
+}
diff --git a/src/main/java/ds/binary/leetcode704/Solution.java b/src/main/java/ds/binary/leetcode704/Solution.java
new file mode 100644
index 0000000..2222d2d
--- /dev/null
+++ b/src/main/java/ds/binary/leetcode704/Solution.java
@@ -0,0 +1,31 @@
+package ds.binary.leetcode704;
+
+/**
+ * 二分查找
+ * 二分查找的3个模板 https://assets.leetcode-cn.com/aliyun-lc-upload/uploads/2020/07/29/template_diagram.png
+ * LeetCode 704. https://leetcode.cn/problems/binary-search/
+ *
+ * @author yangyi 2022年07月12日12:11:28
+ */
+public class Solution {
+
+ public int search(int[] nums, int target) {
+ int start = 0, end = nums.length - 1;
+ while (start <= end) { + int middle = start + (end - start) / 2; + if (nums[middle] < target) { + start = middle + 1; + } else if (nums[middle]> target) {
+ end = middle - 1;
+ } else {
+ return middle;
+ }
+ }
+ return -1;
+ }
+
+ public static void main(String[] args) {
+ System.out.println(new Solution().search(new int[]{-1, 0, 3, 5, 9, 12}, 9));
+ System.out.println(new Solution().search(new int[]{-1, 0, 3, 5, 9, 12}, 2));
+ }
+}
diff --git a/src/main/java/ds/binary/targetofferII06/Solution.java b/src/main/java/ds/binary/targetofferII06/Solution.java
new file mode 100644
index 0000000..9871be3
--- /dev/null
+++ b/src/main/java/ds/binary/targetofferII06/Solution.java
@@ -0,0 +1,32 @@
+package ds.binary.targetofferII06;
+
+import java.util.Arrays;
+
+/**
+ * 排序数组中两个数字之和
+ * 剑指 Offer II 006 https://leetcode.cn/problems/kLl5u1/
+ *
+ * @author yangyi 2022年07月11日22:55:07
+ */
+public class Solution {
+
+ public int[] twoSum(int[] numbers, int target) {
+ int start = 0, end = numbers.length - 1;
+ while (start < end) { + if (numbers[start] + numbers[end] < target) { + start++; + } else if (numbers[start] + numbers[end]> target) {
+ end--;
+ } else {
+ return new int[]{start, end};
+ }
+ }
+ return new int[]{-1, -1};
+ }
+
+ public static void main(String[] args) {
+ System.out.println(Arrays.toString(new Solution().twoSum(new int[]{1, 2, 4, 6, 10}, 8)));
+ System.out.println(Arrays.toString(new Solution().twoSum(new int[]{2, 3, 4}, 6)));
+ System.out.println(Arrays.toString(new Solution().twoSum(new int[]{-1, 0}, -1)));
+ }
+}
diff --git a/src/main/java/ds/binary/targetofferII068/Solution.java b/src/main/java/ds/binary/targetofferII068/Solution.java
new file mode 100644
index 0000000..e9e7ec3
--- /dev/null
+++ b/src/main/java/ds/binary/targetofferII068/Solution.java
@@ -0,0 +1,32 @@
+package ds.binary.targetofferII068;
+
+/**
+ * 查找插入位置
+ * 剑指 Offer II 068. https://leetcode.cn/problems/N6YdxV/
+ *
+ * @author yangyi 2021年01月15日16:35:55
+ */
+public class Solution {
+
+ public int searchInsert(int[] nums, int target) {
+ int start = 0, end = nums.length - 1;
+ while (start <= end) { + int middle = start + (end - start) / 2; + if (nums[middle] < target) { + start = middle + 1; + } else if (nums[middle]> target) {
+ end = middle - 1;
+ } else {
+ return middle;
+ }
+ }
+ return end + 1;
+ }
+
+ public static void main(String[] args) {
+ System.out.println(new Solution().searchInsert(new int[]{1, 3, 5, 6}, 5));
+ System.out.println(new Solution().searchInsert(new int[]{1, 3, 5, 6}, 2));
+ System.out.println(new Solution().searchInsert(new int[]{1, 3, 5, 6}, 7));
+ System.out.println(new Solution().searchInsert(new int[]{1, 3, 5, 6}, 0));
+ }
+}
diff --git a/src/main/java/ds/bit/SingleNumber.java b/src/main/java/ds/bit/leetcode136/Solution.java
similarity index 53%
rename from src/main/java/ds/bit/SingleNumber.java
rename to src/main/java/ds/bit/leetcode136/Solution.java
index ff3ca99..124c6fa 100644
--- a/src/main/java/ds/bit/SingleNumber.java
+++ b/src/main/java/ds/bit/leetcode136/Solution.java
@@ -1,28 +1,15 @@
-package ds.bit;
+package ds.bit.leetcode136;
import java.util.Arrays;
/**
* 只出现一次的数字
- *
- * 给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现两次。找出那个只出现了一次的元素。
- *
- * 说明:
- *
- * 你的算法应该具有线性时间复杂度。 你可以不使用额外空间来实现吗?
- *
- * 示例 1:
- *
- * 输入: [2,2,1]
- * 输出: 1
- * 示例 2:
- *
- * 输入: [4,1,2,1,2]
- * 输出: 4
*
- * @author yangyi 2019年02月09日16:32:02
+ * LeetCode 136 https://leetcode-cn.com/problems/single-number/
+ *
+ * @author yangyi 2022年02月07日16:23:46
*/
-public class SingleNumber {
+public class Solution {
/**
* 异或的特性:
@@ -43,9 +30,9 @@ public int singleNumber(int[] nums) {
public static void main(String[] args) {
int[] a = {2, 2, 1};
int[] b = {4, 1, 2, 1, 2};
- SingleNumber singleNumber = new SingleNumber();
- int res = singleNumber.singleNumber(a);
- int res2 = singleNumber.singleNumber(b);
+ Solution solution = new Solution();
+ int res = solution.singleNumber(a);
+ int res2 = solution.singleNumber(b);
System.out.println(Arrays.toString(a) + "中只出现一次的数字为:" + res);
System.out.println(Arrays.toString(b) + "中只出现一次的数字为:" + res2);
}
diff --git a/src/main/java/ds/bst/BSTreeLowestCommonAncestor.java b/src/main/java/ds/bst/BSTreeLowestCommonAncestor.java
deleted file mode 100644
index 8ab34ae..0000000
--- a/src/main/java/ds/bst/BSTreeLowestCommonAncestor.java
+++ /dev/null
@@ -1,73 +0,0 @@
-package ds.bst;
-
-/**
- * 二叉搜索树的最近公共祖先
- *
- *
- * 给定一个二叉搜索树, 找到该树中两个指定节点的最近公共祖先。
- *
- * 百度百科中最近公共祖先的定义为:"对于有根树 T 的两个结点 p、q,最近公共祖先表示为一个结点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大(一个节点也可以是它自己的祖先)。"
- *
- * 例如,给定如下二叉搜索树: root = [6,2,8,0,4,7,9,null,null,3,5]
- *
- *
- *
- *
- *
- * 示例 1:
- *
- * 输入: root = [6,2,8,0,4,7,9,null,null,3,5], p = 2, q = 8
- * 输出: 6
- * 解释: 节点 2 和节点 8 的最近公共祖先是 6。
- * 示例 2:
- *
- * 输入: root = [6,2,8,0,4,7,9,null,null,3,5], p = 2, q = 4
- * 输出: 2
- * 解释: 节点 2 和节点 4 的最近公共祖先是 2, 因为根据定义最近公共祖先节点可以为节点本身。
- *
- *
- * 说明:
- *
- * 所有节点的值都是唯一的。
- * p、q 为不同节点且均存在于给定的二叉搜索树中。
- *
- *
- * @author yangyi 2019年01月25日19:15:29
- */
-public class BSTreeLowestCommonAncestor {
-
- public BinarySearchTree.TreeNode lowestCommonAncestor(BinarySearchTree.TreeNode root, BinarySearchTree.TreeNode p, BinarySearchTree.TreeNode q) {
- if (p.value < root.value && q.value < root.value) { - return lowestCommonAncestor( - root.left, - new BinarySearchTree.TreeNode(p.value), - new BinarySearchTree.TreeNode(q.value)); - } else if (p.value> root.value && q.value> root.value) {
- return lowestCommonAncestor(
- root.right,
- new BinarySearchTree.TreeNode(p.value),
- new BinarySearchTree.TreeNode(q.value));
- } else {
- return root;
- }
- }
-
- private BinarySearchTree.TreeNode createTree() {
- BinarySearchTree binarySearchTree = new BinarySearchTree();
- BinarySearchTree.TreeNode node = null;
- int[] array = {6, 2, 8, 0, 4, 7, 9, 0, 0, 3, 5};
- for (int i : array) {
- node = binarySearchTree.insert(i);
- }
- return node;
- }
-
- public static void main(String[] args) {
- BSTreeLowestCommonAncestor bsTreeLowestCommonAncestor = new BSTreeLowestCommonAncestor();
- BinarySearchTree.TreeNode resultNode = bsTreeLowestCommonAncestor.lowestCommonAncestor(
- bsTreeLowestCommonAncestor.createTree(),
- new BinarySearchTree.TreeNode(2),
- new BinarySearchTree.TreeNode(8));
- System.out.println("输出结果为:" + resultNode.value);
- }
-}
diff --git a/src/main/java/ds/bst/RightSideView.java b/src/main/java/ds/bst/RightSideView.java
deleted file mode 100644
index 23ba0cb..0000000
--- a/src/main/java/ds/bst/RightSideView.java
+++ /dev/null
@@ -1,82 +0,0 @@
-package ds.bst;
-
-import java.util.ArrayDeque;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Queue;
-
-/**
- * 给定一棵二叉树,想象自己站在它的右侧,按照从顶部到底部的顺序,返回从右侧所能看到的节点值。
- *
- * 示例:
- *
- * 输入: [1,2,3,null,5,null,4]
- * 输出: [1, 3, 4]
- * 解释:
- *
- * 1 <--- - * / \ - * 2 3 <--- - * \ \ - * 5 4 <--- - */ -public class RightSideView { - - public static class TreeNode { - int val; - TreeNode left; - TreeNode right; - - TreeNode(int x) { - val = x; - } - } - - public List rightSideView(TreeNode root) {
- List result = new ArrayList();
- if (root == null) {
- return result;
- }
- Queue queue = new ArrayDeque
();
- queue.offer(root);
- while (!queue.isEmpty()) {
- int size = queue.size();
- int index = 0;
- for (int i = 0; i < size; i++) { - TreeNode current = queue.poll(); - if (current != null) { - if (index == size - 1) { - result.add(current.val); - } - if (current.left != null) { - queue.offer(current.left); - } - if (current.right != null) { - queue.offer(current.right); - } - } - index++; - } - } - return result; - } - - public static void main(String[] args) { - TreeNode one = new TreeNode(1); - TreeNode two = new TreeNode(2); - TreeNode three = new TreeNode(3); - TreeNode five = new TreeNode(5); - TreeNode four = new TreeNode(4); - - one.left = two; - one.right = three; - two.right = five; - three.right = four; - - RightSideView rightSideView = new RightSideView(); - List integers = rightSideView.rightSideView(one);
- for (Integer integer : integers) {
- System.out.println(integer);
- }
- }
-}
diff --git a/src/main/java/ds/bst/TreeLowestCommonAncestor.java b/src/main/java/ds/bst/TreeLowestCommonAncestor.java
deleted file mode 100644
index 9521335..0000000
--- a/src/main/java/ds/bst/TreeLowestCommonAncestor.java
+++ /dev/null
@@ -1,57 +0,0 @@
-package ds.bst;
-
-/**
- * 二叉树的最近公共祖先
- *
- * 此方法通用于 {@link BSTreeLowestCommonAncestor} 因为{@link BSTreeLowestCommonAncestor}类中的二叉搜索树也是普通二叉树的一种
- *
- * @author yangyi 2019年01月25日18:29:39
- */
-public class TreeLowestCommonAncestor {
-
- /**
- * 非平衡二叉查找树的寻找
- */
- public BinarySearchTree.TreeNode lowestCommonAncestor(
- BinarySearchTree.TreeNode root,
- BinarySearchTree.TreeNode p,
- BinarySearchTree.TreeNode q) {
- if (root == null) {
- return null;
- }
- if (root.value == p.value) {
- return p;
- }
- if (root.value == q.value) {
- return q;
- }
- BinarySearchTree.TreeNode left = lowestCommonAncestor(root.left, p, q);
- BinarySearchTree.TreeNode right = lowestCommonAncestor(root.right, p, q);
- if (left == null) {
- return right;
- } else if (right == null) {
- return left;
- }
- return root;
- }
-
- private BinarySearchTree.TreeNode createTree() {
- BinarySearchTree binarySearchTree = new BinarySearchTree();
- BinarySearchTree.TreeNode node = null;
- int[] array = {6, 2, 8, 0, 4, 7, 9, 0, 0, 3, 5};
- for (int i : array) {
- node = binarySearchTree.insert(i);
- }
- return node;
- }
-
- public static void main(String[] args) {
- TreeLowestCommonAncestor treeLowestCommonAncestor = new TreeLowestCommonAncestor();
- BinarySearchTree.TreeNode resultNode = treeLowestCommonAncestor.lowestCommonAncestor(
- treeLowestCommonAncestor.createTree(),
- new BinarySearchTree.TreeNode(2),
- new BinarySearchTree.TreeNode(8));
- System.out.println("输出结果为:" + resultNode.value);
- }
-
-}
diff --git a/src/main/java/ds/bst/ValidBST.java b/src/main/java/ds/bst/ValidBST.java
deleted file mode 100644
index 4d947f8..0000000
--- a/src/main/java/ds/bst/ValidBST.java
+++ /dev/null
@@ -1,118 +0,0 @@
-package ds.bst;
-
-import java.util.Arrays;
-
-/**
- * 给定一个二叉树,判断其是否是一个有效的二叉搜索树。
- *
- * 假设一个二叉搜索树具有如下特征:
- *
- * 节点的左子树只包含小于当前节点的数。
- * 节点的右子树只包含大于当前节点的数。
- * 所有左子树和右子树自身必须也是二叉搜索树。
- * 示例 1:
- *
- * 输入:
- * 2
- * / \
- * 1 3
- * 输出: true
- * 示例 2:
- *
- * 输入:
- * 5
- * / \
- * 1 4
- * / \
- * 3 6
- * 输出: false
- * 解释: 输入为: [5,1,4,null,null,3,6]。
- * 根节点的值为 5 ,但是其右子节点值为 4 。
- *
- * @author yangyi 2019年01月25日19:54:47
- */
-public class ValidBST {
-
- private int[] array = {5, 1, 4, 0, 0, 3, 6};
- private int[] arrayBST = {1, 2, 3, 5, 6, 9, 10};
-
- /**
- * 保存前继节点的指针
- */
- private BinarySearchTree.TreeNode pre;
-
- /**
- * 方法1:
- * 1. 中序遍历这个树,看最终的结果是否是有序的。
- * 2. 判断有序与否,注意不用排序,只需要判断当前节点是否比前继节点大即可。
- */
- public boolean isValidBST(BinarySearchTree.TreeNode root) {
- pre = null;
- return inPrint(root);
- }
-
- private boolean inPrint(BinarySearchTree.TreeNode root) {
- //为null时约定为是一个二叉查找树
- if (root == null) {
- return true;
- }
- //开始前序遍历
- if (!inPrint(root.left)) {
- return false;
- }
- //关键就是在于这行判断,如果前继节点不为null且后继节点不大于前继节点,则说明此时已经无序了
- if (pre != null && pre.value>= root.value) {
- return false;
- }
- //判断完之后更新前继节点继续判断
- pre = root;
- return inPrint(root.right);
- }
-
- /**
- * 方法2:
- * 1. 遍历左子树,找到左子树中的最大值。
- * 2. 遍历右子树,找到右子树中的最小值。
- * 3. 左边的max < root < 右边的min。 - * 4. 继续递归直到满足3中的条件为止。 - */ - public boolean isValidBSTRecursion(BinarySearchTree.TreeNode root, int min, int max) { - //为null时约定为是一个二叉查找树 - if (root == null) { - return true; - } - //小于min和大于max,均非法 - if (min != Integer.MIN_VALUE && root.value <= min) { - return false; - } - if (max != Integer.MAX_VALUE && root.value>= max) {
- return false;
- }
- return isValidBSTRecursion(root.left, min, root.value)
- && isValidBSTRecursion(root.right, root.value, max);
- }
-
- private BinarySearchTree.TreeNode createTree(int[] array) {
- BinarySearchTree binarySearchTree = new BinarySearchTree();
- BinarySearchTree.TreeNode node = null;
- for (int i : array) {
- node = binarySearchTree.insert(i);
- }
- return node;
- }
-
- public static void main(String[] args) {
- ValidBST validBST = new ValidBST();
- System.out.println("方法一验证:");
- System.out.println(Arrays.toString(validBST.array)
- + (validBST.isValidBST(validBST.createTree(validBST.array)) ? "是一个二叉搜索树" : "不是一个二叉搜索树"));
- System.out.println(Arrays.toString(validBST.arrayBST)
- + (validBST.isValidBST(validBST.createTree(validBST.arrayBST)) ? "是一个二叉搜索树" : "不是一个二叉搜索树"));
- System.out.println("方法二验证:");
- System.out.println(Arrays.toString(validBST.array)
- + (validBST.isValidBSTRecursion(validBST.createTree(validBST.array), Integer.MIN_VALUE, Integer.MAX_VALUE) ? "是一个二叉搜索树" : "不是一个二叉搜索树"));
- System.out.println(Arrays.toString(validBST.arrayBST)
- + (validBST.isValidBSTRecursion(validBST.createTree(validBST.arrayBST), Integer.MIN_VALUE, Integer.MAX_VALUE) ? "是一个二叉搜索树" : "不是一个二叉搜索树"));
-
- }
-}
diff --git a/src/main/java/ds/bst/ZigzagLevelOrder.java b/src/main/java/ds/bst/ZigzagLevelOrder.java
deleted file mode 100644
index 1c5ab20..0000000
--- a/src/main/java/ds/bst/ZigzagLevelOrder.java
+++ /dev/null
@@ -1,100 +0,0 @@
-package ds.bst;
-
-import java.util.ArrayDeque;
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * 给定一个二叉树,返回其节点值的锯齿形层次遍历。(即先从左往右,再从右往左进行下一层遍历,以此类推,层与层之间交替进行)。
- *
- * 例如:
- * 给定二叉树 [3,9,20,null,null,15,7],
- *
- * 3
- * / \
- * 9 20
- * / \
- * 15 7
- * 返回锯齿形层次遍历如下:
- *
- * [
- * [3],
- * [20,9],
- * [15,7]
- * ]
- */
-public class ZigzagLevelOrder {
-
- public static class TreeNode {
- int val;
- TreeNode left;
- TreeNode right;
-
- TreeNode(int x) {
- val = x;
- }
- }
-
- public List> zigzagLevelOrder(TreeNode root) {
- List> result = new ArrayList();
- if (root == null) {
- return result;
- }
- ArrayDeque queue = new ArrayDeque
();
- queue.offer(root);
- int level = 0;
- while (!queue.isEmpty()) {
- int size = queue.size();
- List integerList = new ArrayList();
- if (level % 2 == 0) {
- for (int i = 0; i < size; i++) { - TreeNode current = queue.pollFirst(); - integerList.add(current.val); - if(current.left != null){ - queue.offerLast(current.left); - } - if(current.right != null){ - queue.offerLast(current.right); - } - } - } else { - for (int i = 0; i < size; i++) { - TreeNode current = queue.pollLast(); - integerList.add(current.val); - if(current.right != null){ - queue.offerFirst(current.right); - } - if(current.left != null){ - queue.offerFirst(current.left); - } - } - } - result.add(integerList); - level++; - } - return result; - } - - public static void main(String[] args) { - TreeNode node_3 = new TreeNode(3); - TreeNode node_9 = new TreeNode(9); - TreeNode node_20 = new TreeNode(20); - TreeNode node_15 = new TreeNode(15); - TreeNode node_7 = new TreeNode(7); - - node_3.left = node_9; - node_3.right = node_20; - node_20.left = node_15; - node_20.right = node_7; - - ZigzagLevelOrder zigzagLevelOrder = new ZigzagLevelOrder(); - List> result = zigzagLevelOrder.zigzagLevelOrder(node_3);
- for (List integers : result) {
- for (Integer integer : integers) {
- System.out.print(integer + " ");
- }
- System.out.println();
- }
- }
-
-}
diff --git a/src/main/java/ds/bst/BinarySearchTree.java b/src/main/java/ds/bst/base/BinarySearchTree.java
similarity index 99%
rename from src/main/java/ds/bst/BinarySearchTree.java
rename to src/main/java/ds/bst/base/BinarySearchTree.java
index 57de066..8a357da 100644
--- a/src/main/java/ds/bst/BinarySearchTree.java
+++ b/src/main/java/ds/bst/base/BinarySearchTree.java
@@ -1,4 +1,4 @@
-package ds.bst;
+package ds.bst.base;
/**
* 二叉查找树的插入、遍历、查找、删除
diff --git a/src/main/java/ds/bst/leetcode108/Solution.java b/src/main/java/ds/bst/leetcode108/Solution.java
new file mode 100644
index 0000000..543aae8
--- /dev/null
+++ b/src/main/java/ds/bst/leetcode108/Solution.java
@@ -0,0 +1,82 @@
+package ds.bst.leetcode108;
+
+import java.util.ArrayDeque;
+import java.util.Arrays;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Queue;
+
+/**
+ * 将有序数组转换为二叉搜索树
+ * LeetCode 108 https://leetcode-cn.com/problems/convert-sorted-array-to-binary-search-tree/
+ *
+ * @author yangyi 2021年05月02日01:38:39
+ */
+public class Solution {
+
+ public class TreeNode {
+ int val;
+ TreeNode left;
+ TreeNode right;
+
+ TreeNode() {
+ }
+
+ TreeNode(int val) {
+ this.val = val;
+ }
+
+ TreeNode(int val, TreeNode left, TreeNode right) {
+ this.val = val;
+ this.left = left;
+ this.right = right;
+ }
+ }
+
+ public TreeNode sortedArrayToBST(int[] nums) {
+ if (nums == null) {
+ return null;
+ }
+ return bst(nums, 0, nums.length - 1);
+ }
+
+ private TreeNode bst(int[] nums, int start, int end) {
+ if (start> end) {
+ return null;
+ }
+ int mid = start + (end - start) / 2;
+ TreeNode cur = new TreeNode(nums[mid]);
+ cur.left = bst(nums, start, mid - 1);
+ cur.right = bst(nums, mid + 1, end);
+ return cur;
+ }
+
+ private List levelOrder(TreeNode root) {
+ if (root == null) {
+ return new LinkedList
();
+ }
+ List result = new LinkedList
();
+ Queue queue = new ArrayDeque
();
+ queue.offer(root);
+ while (!queue.isEmpty()) {
+ for (int i = 0; i < queue.size(); i++) { + TreeNode cur = queue.poll(); + if (cur != null) { + result.add(cur); + } + if (cur.left != null) { + queue.offer(cur.left); + } + if (cur.right != null) { + queue.offer(cur.right); + } + } + } + return result; + } + + public static void main(String[] args) { + List result = new Solution().levelOrder(new Solution().sortedArrayToBST(new int[]{-10, -3, 0, 5, 9}));
+ System.out.println(Arrays.toString(result.stream().mapToInt(value -> value.val).toArray()));
+ }
+}
diff --git a/src/main/java/ds/bst/leetcode109/Solution.java b/src/main/java/ds/bst/leetcode109/Solution.java
new file mode 100644
index 0000000..11041e6
--- /dev/null
+++ b/src/main/java/ds/bst/leetcode109/Solution.java
@@ -0,0 +1,130 @@
+package ds.bst.leetcode109;
+
+import java.util.ArrayDeque;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Queue;
+
+/**
+ * 有序链表转换二叉搜索树
+ * LeetCode 109 https://leetcode-cn.com/problems/convert-sorted-list-to-binary-search-tree/
+ *
+ * @author yangyi 2022年04月22日11:49:00
+ */
+public class Solution {
+
+ public static class ListNode {
+ int val;
+ ListNode next;
+
+ ListNode() {
+ }
+
+ ListNode(int val) {
+ this.val = val;
+ }
+
+ ListNode(int val, ListNode next) {
+ this.val = val;
+ this.next = next;
+ }
+ }
+
+ public class TreeNode {
+ int val;
+ TreeNode left;
+ TreeNode right;
+
+ TreeNode() {
+ }
+
+ TreeNode(int val) {
+ this.val = val;
+ }
+
+ TreeNode(int val, TreeNode left, TreeNode right) {
+ this.val = val;
+ this.left = left;
+ this.right = right;
+ }
+ }
+
+ public TreeNode sortedListToBST(ListNode head) {
+ return buildTree(head, null);
+ }
+
+ private TreeNode buildTree(ListNode start, ListNode end) {
+ if (start == end) {
+ return null;
+ }
+ ListNode mNode = getLinkMiddle(start, end);
+ TreeNode root = new TreeNode(mNode.val);
+ root.left = buildTree(start, mNode);
+ root.right = buildTree(mNode.next, end);
+ return root;
+ }
+
+ private ListNode getLinkMiddle(ListNode start, ListNode end) {
+ ListNode fast = start;
+ ListNode slow = start;
+ while (fast != end && fast.next != end) {
+ fast = fast.next.next;
+ slow = slow.next;
+ }
+ return slow;
+ }
+
+ private List
> levelOrder(TreeNode root) {
+ if (root == null) {
+ return new LinkedList();
+ }
+ List> result = new LinkedList();
+ Queue queue = new ArrayDeque
();
+ queue.offer(root);
+ while (!queue.isEmpty()) {
+ int size = queue.size();
+ List level = new LinkedList
();
+ for (int i = 0; i < size; i++) { + TreeNode cur = queue.poll(); + if (cur != null) { + level.add(cur); + } + if (cur.left != null) { + queue.offer(cur.left); + } + if (cur.right != null) { + queue.offer(cur.right); + } + } + result.add(level); + } + return result; + } + + private ListNode createListNode() { + ListNode val_10 = new ListNode(-10); + ListNode val_3 = new ListNode(-3); + ListNode val_0 = new ListNode(0); + ListNode val_5 = new ListNode(5); + ListNode val_9 = new ListNode(9); + val_10.next = val_3; + val_3.next = val_0; + val_0.next = val_5; + val_5.next = val_9; + return val_10; + } + + public static void main(String[] args) { + Solution solution = new Solution(); + ListNode link = solution.createListNode(); + TreeNode tree = solution.sortedListToBST(link); + List> result = solution.levelOrder(tree);
+ for (List treeNodes : result) {
+ for (TreeNode treeNode : treeNodes) {
+ System.out.print(treeNode.val + " ");
+ }
+ System.out.println();
+ }
+ }
+
+}
diff --git a/src/main/java/ds/bst/KthSmallestInBST.java b/src/main/java/ds/bst/leetcode230/Solution.java
similarity index 86%
rename from src/main/java/ds/bst/KthSmallestInBST.java
rename to src/main/java/ds/bst/leetcode230/Solution.java
index db8a2ab..a61f98f 100644
--- a/src/main/java/ds/bst/KthSmallestInBST.java
+++ b/src/main/java/ds/bst/leetcode230/Solution.java
@@ -1,4 +1,4 @@
-package ds.bst;
+package ds.bst.leetcode230;
/**
* 二叉搜索树中第K小的元素
@@ -6,7 +6,7 @@
*
* @author yangyi 2019年02月10日10:34:52
*/
-public class KthSmallestInBST {
+public class Solution {
public class TreeNode {
int val;
@@ -76,12 +76,12 @@ private void inOrder(TreeNode root) {
}
public static void main(String[] args) {
- KthSmallestInBST kthSmallestInBST = new KthSmallestInBST();
- TreeNode root = kthSmallestInBST.createTreeNode();
+ Solution solution = new Solution();
+ TreeNode root = solution.createTreeNode();
System.out.println("中序遍历构造出来的第一棵树: ");
- kthSmallestInBST.inOrder(root);
+ solution.inOrder(root);
System.out.println();
System.out.println("搜索此树的第1个最小的元素: ");
- System.out.println(kthSmallestInBST.kthSmallest(root, 1));
+ System.out.println(solution.kthSmallest(root, 1));
}
}
diff --git a/src/main/java/ds/bst/leetcode235/Solution.java b/src/main/java/ds/bst/leetcode235/Solution.java
new file mode 100644
index 0000000..431755f
--- /dev/null
+++ b/src/main/java/ds/bst/leetcode235/Solution.java
@@ -0,0 +1,67 @@
+package ds.bst.leetcode235;
+
+/**
+ * 二叉搜索树的最近公共祖先
+ * LeetCode 235 https://leetcode-cn.com/problems/lowest-common-ancestor-of-a-binary-search-tree/submissions/
+ * 剑指 Offer 68 - I https://leetcode-cn.com/problems/er-cha-sou-suo-shu-de-zui-jin-gong-gong-zu-xian-lcof/
+ *
+ * @author yangyi 2019年01月25日19:15:29
+ */
+public class Solution {
+
+ public static 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, + new TreeNode(p.val), + new TreeNode(q.val)); + } else if (p.val> root.val && q.val> root.val) {
+ return lowestCommonAncestor(
+ root.right,
+ new TreeNode(p.val),
+ new TreeNode(q.val));
+ } else {
+ return root;
+ }
+ }
+
+ private TreeNode createTree() {
+ TreeNode node_6 = new TreeNode(6);
+ TreeNode node_2 = new TreeNode(2);
+ TreeNode node_8 = new TreeNode(8);
+ TreeNode node_0 = new TreeNode(0);
+ TreeNode node_4 = new TreeNode(4);
+ TreeNode node_7 = new TreeNode(7);
+ TreeNode node_9 = new TreeNode(9);
+ TreeNode node_3 = new TreeNode(3);
+ TreeNode node_5 = new TreeNode(5);
+ node_6.left = node_2;
+ node_6.right = node_8;
+ node_2.left = node_0;
+ node_2.right = node_4;
+ node_4.left = node_3;
+ node_4.right = node_5;
+ node_8.left = node_7;
+ node_8.right = node_9;
+ return node_6;
+ }
+
+ public static void main(String[] args) {
+ Solution solution = new Solution();
+ TreeNode resultNode = solution.lowestCommonAncestor(
+ solution.createTree(),
+ new TreeNode(2),
+ new TreeNode(8));
+ System.out.println("输出结果为:" + resultNode.val);
+ }
+}
diff --git a/src/main/java/ds/bst/BstDelete.java b/src/main/java/ds/bst/leetcode450/Solution.java
similarity index 87%
rename from src/main/java/ds/bst/BstDelete.java
rename to src/main/java/ds/bst/leetcode450/Solution.java
index 89433e6..e195596 100644
--- a/src/main/java/ds/bst/BstDelete.java
+++ b/src/main/java/ds/bst/leetcode450/Solution.java
@@ -1,4 +1,4 @@
-package ds.bst;
+package ds.bst.leetcode450;
/**
* 删除二叉搜索树中的节点
@@ -6,7 +6,7 @@
*
* @author yangyi 2020年12月05日16:11:25
*/
-public class BstDelete {
+public class Solution {
public class TreeNode {
int val;
@@ -62,7 +62,11 @@ public TreeNode deleteNode(TreeNode root, int key) {
if (root == null) {
return null;
}
- if (root.val == key) {
+ if (root.val> key) {
+ root.left = deleteNode(root.left, key);
+ } else if (root.val < key) { + root.right = deleteNode(root.right, key); + } else if (root.val == key) { if (root.left == null) { return root.right; } @@ -74,10 +78,6 @@ public TreeNode deleteNode(TreeNode root, int key) { root.val = min.val; //删除右子树中找出来的最小值 root.right = deleteNode(root.right, min.val); - } else if (key < root.val) { - root.left = deleteNode(root.left, key); - } else { - root.right = deleteNode(root.right, key); } return root; } @@ -93,15 +93,15 @@ private TreeNode getMin(TreeNode root) { } public static void main(String[] args) { - BstDelete bstDelete = new BstDelete(); + Solution solution = new Solution(); System.out.println("构建一棵树"); - TreeNode root = bstDelete.createTree(); + TreeNode root = solution.createTree(); System.out.println("中序遍历构建好的树: "); - bstDelete.inOrder(root); + solution.inOrder(root); System.out.println(); System.out.println("删除树中值为3的节点: "); - TreeNode result = bstDelete.deleteNode(root, 3); + TreeNode result = solution.deleteNode(root, 3); System.out.println("中序遍历删除对应的3节点之后剩余的树: "); - bstDelete.inOrder(result); + solution.inOrder(result); } } diff --git a/src/main/java/ds/bst/leetcode501/Solution.java b/src/main/java/ds/bst/leetcode501/Solution.java new file mode 100644 index 0000000..58723d6 --- /dev/null +++ b/src/main/java/ds/bst/leetcode501/Solution.java @@ -0,0 +1,78 @@ +package ds.bst.leetcode501; + +import java.util.Arrays; +import java.util.LinkedList; +import java.util.List; + +/** + * 二叉搜索树中的众数 + * LeetCode 501 https://leetcode-cn.com/problems/find-mode-in-binary-search-tree/ + * + * @author yangyi 2021年02月13日21:57:18 + */ +public class Solution { + + public class TreeNode { + int val; + TreeNode left; + TreeNode right; + + TreeNode(int x) { + val = x; + } + } + + private List
result = new LinkedList();
+ private TreeNode pre;
+ private int count = 0;
+ private int maxCount = 0;
+
+ public int[] findMode(TreeNode root) {
+ if (root == null) {
+ return new int[]{};
+ }
+ search(root);
+ // int[] res = new int[result.size()];
+// for (int i = 0; i < result.size(); i++) { +// res[i] = result.get(i); +// } + return result.stream().mapToInt(value -> value).toArray();
+ }
+
+ private void search(TreeNode cur) {
+ if (cur == null) {
+ return;
+ }
+ search(cur.left);
+ if (pre == null) {
+ count = 1;
+ } else if (pre != null && pre.val == cur.val) {
+ count++;
+ } else {
+ count = 1;
+ }
+ pre = cur;
+ if (count == maxCount) {
+ result.add(cur.val);
+ }
+ if (count> maxCount) {
+ result.clear();
+ maxCount = count;
+ result.add(cur.val);
+ }
+ search(cur.right);
+ }
+
+ private TreeNode createTree() {
+ TreeNode node_1 = new TreeNode(1);
+ TreeNode node_2 = new TreeNode(2);
+ TreeNode node_22 = new TreeNode(2);
+ node_1.right = node_2;
+ node_2.left = node_22;
+ return node_1;
+ }
+
+ public static void main(String[] args) {
+ System.out.println(Arrays.toString(new Solution().findMode(new Solution().createTree())));
+ }
+}
diff --git a/src/main/java/ds/bst/leetcode530/Solution.java b/src/main/java/ds/bst/leetcode530/Solution.java
new file mode 100644
index 0000000..f7c4862
--- /dev/null
+++ b/src/main/java/ds/bst/leetcode530/Solution.java
@@ -0,0 +1,87 @@
+package ds.bst.leetcode530;
+
+import java.util.LinkedList;
+import java.util.List;
+
+/**
+ * 二叉搜索树的最小绝对差
+ * LeetCode 530 https://leetcode-cn.com/problems/minimum-absolute-difference-in-bst/
+ *
+ * @author yangyi 2021年02月13日15:58:20
+ */
+public class Solution {
+
+ public class TreeNode {
+ int val;
+ TreeNode left;
+ TreeNode right;
+
+ TreeNode(int x) {
+ val = x;
+ }
+ }
+
+ private List result = new LinkedList();
+
+ /**
+ * 1. 用额外的数组空间接收二叉搜索树中序遍历的结果
+ * 2. 因为此时的数组已经是有序的,再查找数组中的最小绝对差即可
+ */
+ public int getMinimumDifference(TreeNode root) {
+ inOrder(root);
+ if (result.size() <= 1) { + return 0; + } + int min = Integer.MAX_VALUE; + for (int i = 1; i < result.size(); i++) { + min = Math.min(min, result.get(i) - result.get(i - 1)); + } + return min; + } + + private void inOrder(TreeNode root) { + if (root == null) { + return; + } + inOrder(root.left); + result.add(root.val); + inOrder(root.right); + } + + private TreeNode pre; + private int res = Integer.MAX_VALUE; + + /** + * 递归内部记录当前节点和前一个节点,不借助额外的数组空间,在递归内部计算最小绝对差 + */ + public int getMinimumDifference2(TreeNode root) { + recursive(root); + return res; + } + + private void recursive(TreeNode cur) { + if (cur == null) { + return; + } + recursive(cur.left); + if (pre != null) { + res = Math.min(res, cur.val - pre.val); + } + pre = cur; + recursive(cur.right); + } + + private TreeNode createTree() { + TreeNode node_1 = new TreeNode(1); + TreeNode node_3 = new TreeNode(3); + TreeNode node_2 = new TreeNode(2); + node_1.right = node_3; + node_3.left = node_2; + return node_1; + } + + public static void main(String[] args) { + System.out.println(new Solution().getMinimumDifference(new Solution().createTree())); + System.out.println(new Solution().getMinimumDifference2(new Solution().createTree())); + } +} diff --git a/src/main/java/ds/bst/BstToGst.java b/src/main/java/ds/bst/leetcode538/Solution.java similarity index 95% rename from src/main/java/ds/bst/BstToGst.java rename to src/main/java/ds/bst/leetcode538/Solution.java index ecb1a25..4c3d3bd 100644 --- a/src/main/java/ds/bst/BstToGst.java +++ b/src/main/java/ds/bst/leetcode538/Solution.java @@ -1,4 +1,4 @@ -package ds.bst; +package ds.bst.leetcode538; /** * 把二叉搜索树转换为累加树 @@ -7,7 +7,7 @@ * * @author yangyi 2020年12月02日09:08:55 */ -public class BstToGst { +public class Solution { public class TreeNode { int val; @@ -76,7 +76,7 @@ private void inOrder(TreeNode root) { } public static void main(String[] args) { - BstToGst bstToGst = new BstToGst(); + Solution bstToGst = new Solution(); TreeNode root = bstToGst.createTree(); System.out.println("中序遍历构造出来的二叉树: "); bstToGst.inOrder(root); diff --git a/src/main/java/ds/bst/BstSearch.java b/src/main/java/ds/bst/leetcode700/Solution.java similarity index 78% rename from src/main/java/ds/bst/BstSearch.java rename to src/main/java/ds/bst/leetcode700/Solution.java index 17335ed..039a1f2 100644 --- a/src/main/java/ds/bst/BstSearch.java +++ b/src/main/java/ds/bst/leetcode700/Solution.java @@ -1,4 +1,4 @@ -package ds.bst; +package ds.bst.leetcode700; /** * 二叉搜索树中的搜索 @@ -6,7 +6,7 @@ * * @author yangyi 2020年12月03日00:50:09 */ -public class BstSearch { +public class Solution { public class TreeNode { int val; @@ -47,6 +47,9 @@ private void inOrder(TreeNode root) { inOrder(root.right); } + /** + * 递归方式实现 + */ public TreeNode searchBST(TreeNode root, int val) { if (root == null) { return null; @@ -60,8 +63,24 @@ public TreeNode searchBST(TreeNode root, int val) { } } + /** + * 迭代方式实现 + */ + public TreeNode searchBST2(TreeNode root, int val) { + while (root != null) { + if (val < root.val) { + root = root.left; + } else if (val> root.val) {
+ root = root.right;
+ } else {
+ return root;
+ }
+ }
+ return null;
+ }
+
public static void main(String[] args) {
- BstSearch bstSearch = new BstSearch();
+ Solution bstSearch = new Solution();
System.out.println("创建一颗BST: ");
TreeNode root = bstSearch.createTree();
System.out.println("中序遍历构建好的BST: ");
diff --git a/src/main/java/ds/bst/BstInsert.java b/src/main/java/ds/bst/leetcode701/Solution.java
similarity index 95%
rename from src/main/java/ds/bst/BstInsert.java
rename to src/main/java/ds/bst/leetcode701/Solution.java
index e4cd00a..9bd73f2 100644
--- a/src/main/java/ds/bst/BstInsert.java
+++ b/src/main/java/ds/bst/leetcode701/Solution.java
@@ -1,4 +1,4 @@
-package ds.bst;
+package ds.bst.leetcode701;
/**
* 二叉搜索树中的插入操作
@@ -6,7 +6,7 @@
*
* @author yangyi 2020年12月03日10:47:33
*/
-public class BstInsert {
+public class Solution {
public class TreeNode {
int val;
@@ -69,7 +69,7 @@ public TreeNode insertIntoBST(TreeNode root, int val) {
}
public static void main(String[] args) {
- BstInsert bstInsert = new BstInsert();
+ Solution bstInsert = new Solution();
System.out.println("创建一颗BST---");
TreeNode root = bstInsert.createTree();
System.out.println("中序遍历创建好的BST");
diff --git a/src/main/java/ds/bst/leetcode783/Solution.java b/src/main/java/ds/bst/leetcode783/Solution.java
new file mode 100644
index 0000000..aa5d8e7
--- /dev/null
+++ b/src/main/java/ds/bst/leetcode783/Solution.java
@@ -0,0 +1,89 @@
+package ds.bst.leetcode783;
+
+import java.util.LinkedList;
+
+/**
+ * 二叉搜索树节点最小距离
+ * LeetCode 783 https://leetcode-cn.com/problems/minimum-distance-between-bst-nodes/
+ *
+ * @author yangyi 2022年04月19日16:20:47
+ */
+public class Solution {
+
+ public class TreeNode {
+ int val;
+ TreeNode left;
+ TreeNode right;
+
+ TreeNode() {
+ }
+
+ TreeNode(int val) {
+ this.val = val;
+ }
+
+ TreeNode(int val, TreeNode left, TreeNode right) {
+ this.val = val;
+ this.left = left;
+ this.right = right;
+ }
+ }
+
+ public LinkedList result = new LinkedList();
+
+ private void inOrder(TreeNode root) {
+ if (root == null) {
+ return;
+ }
+ inOrder(root.left);
+ result.add(root.val);
+ inOrder(root.right);
+ }
+
+ public int minDiffInBST(TreeNode root) {
+ inOrder(root);
+ if (result.size() <= 1) { + return 0; + } + int min = Integer.MAX_VALUE; + for (int i = 1; i < result.size(); i++) { + min = Math.min(min, Math.abs(result.get(i) - result.get(i - 1))); + } + return min; + } + + private TreeNode createTree(){ + TreeNode node_4 = new TreeNode(4); + TreeNode node_2 = new TreeNode(2); + TreeNode node_6 = new TreeNode(6); + TreeNode node_1 = new TreeNode(1); + TreeNode node_3 = new TreeNode(3); + node_4.left = node_2; + node_4.right = node_6; + node_2.left = node_1; + node_2.right = node_3; + return node_4; + } + + private TreeNode createTree2(){ + TreeNode node_1 = new TreeNode(1); + TreeNode node_0 = new TreeNode(0); + TreeNode node_48 = new TreeNode(48); + TreeNode node_12 = new TreeNode(12); + TreeNode node_49 = new TreeNode(49); + node_1.left = node_0; + node_1.right = node_48; + node_48.left = node_12; + node_48.right = node_49; + return node_1; + } + + public static void main(String[] args) { + Solution solution = new Solution(); + TreeNode tree = solution.createTree(); + TreeNode tree2 = solution.createTree2(); + System.out.println(solution.minDiffInBST(tree)); + System.out.println(solution.minDiffInBST(tree2)); + } + +} diff --git a/src/main/java/ds/bst/leetcode98/Solution.java b/src/main/java/ds/bst/leetcode98/Solution.java new file mode 100644 index 0000000..462b1c5 --- /dev/null +++ b/src/main/java/ds/bst/leetcode98/Solution.java @@ -0,0 +1,114 @@ +package ds.bst.leetcode98; + +import java.util.ArrayList; +import java.util.List; + +/** + * 验证二叉搜索树 + * LeetCode 98 https://leetcode-cn.com/problems/validate-binary-search-tree/ + * + * @author yangyi 2021年02月12日21:48:49 + */ +public class Solution { + + public class TreeNode { + int val; + TreeNode left; + TreeNode right; + + TreeNode() { + } + + TreeNode(int val) { + this.val = val; + } + + TreeNode(int val, TreeNode left, TreeNode right) { + this.val = val; + this.left = left; + this.right = right; + } + } + + private List result = new ArrayList();
+
+ /**
+ * 方法1:
+ * 1. 中序遍历这个树,看最终的结果是否是有序的。
+ * 2. 判断有序与否,注意不用排序,只需要判断当前节点是否比前继节点大即可。
+ */
+ public boolean isValidBST(TreeNode root) {
+ inOrder(root);
+ for (int i = 1; i < result.size(); i++) { + if (result.get(i) <= result.get(i - 1)) { + return false; + } + } + return true; + } + + private void inOrder(TreeNode root) { + if (root == null) { + return; + } + inOrder(root.left); + result.add(root.val); + inOrder(root.right); + } + + /** + * 方法2中记录前一个节点 + */ + private TreeNode pre; + + /** + * 方法2: + * 1. 递归形式参数和返回值,形式参数: 树本身。返回值: 是否为二叉查找树 + * 2. 终止条件: 当树为空时,当做二叉查找树处理。 前一个节点不为空且现在的节点小于前一个节点时,违反了二叉查找树的规则 + * 3. 单层递归逻辑: 采用中序遍历,左跟右,判断左子树是否为二叉查找树,判断右子树是否为二叉查找树,最终两者都是则整棵树为二叉查找树 + */ + public boolean isValidBST2(TreeNode root) { + if (root == null) { + return true; + } + boolean left = isValidBST2(root.left); + if (pre != null && pre.val>= root.val) {
+ return false;
+ }
+ pre = root;
+ boolean right = isValidBST2(root.right);
+ return left && right;
+ }
+
+ private TreeNode createTree1() {
+ TreeNode node_2 = new TreeNode(2);
+ TreeNode node_1 = new TreeNode(1);
+ TreeNode node_3 = new TreeNode(3);
+ node_2.left = node_1;
+ node_2.right = node_3;
+ return node_2;
+ }
+
+ private TreeNode createTree2() {
+ TreeNode node_5 = new TreeNode(5);
+ TreeNode node_1 = new TreeNode(1);
+ TreeNode node_4 = new TreeNode(4);
+ TreeNode node_3 = new TreeNode(3);
+ TreeNode node_6 = new TreeNode(6);
+ node_5.left = node_1;
+ node_5.right = node_4;
+ node_4.left = node_3;
+ node_4.right = node_6;
+ return node_5;
+ }
+
+ public static void main(String[] args) {
+ Solution solution = new Solution();
+ System.out.println("方法一验证:");
+ System.out.println(solution.isValidBST(solution.createTree1()));
+ System.out.println(solution.isValidBST(solution.createTree2()));
+ System.out.println("方法二验证:");
+ System.out.println(solution.isValidBST2(solution.createTree1()));
+ System.out.println(solution.isValidBST2(solution.createTree2()));
+ }
+}
diff --git a/src/main/java/ds/bst/targetoffer36/Solution.java b/src/main/java/ds/bst/targetoffer36/Solution.java
new file mode 100644
index 0000000..bb0981e
--- /dev/null
+++ b/src/main/java/ds/bst/targetoffer36/Solution.java
@@ -0,0 +1,62 @@
+package ds.bst.targetoffer36;
+
+/**
+ * 二叉搜索树与双向链表
+ * 剑指 Offer 36. https://leetcode-cn.com/problems/er-cha-sou-suo-shu-yu-shuang-xiang-lian-biao-lcof/
+ * 426. 将二叉搜索树转化为排序的双向链表
+ *
+ * @author yangyi 2021年05月01日00:41:51
+ */
+public class Solution {
+
+ class Node {
+ public int val;
+ public Node left;
+ public Node right;
+
+ public Node() {
+ }
+
+ public Node(int _val) {
+ val = _val;
+ }
+
+ public Node(int _val, Node _left, Node _right) {
+ val = _val;
+ left = _left;
+ right = _right;
+ }
+ }
+
+ private Node pre = null, head = null;
+
+ public Node treeToDoublyList(Node root) {
+ if (root == null) {
+ return null;
+ }
+ inOrder(root);
+ head.left = pre;
+ pre.right = head;
+ return head;
+ }
+
+ private void inOrder(Node cur) {
+ if (cur == null) {
+ return;
+ }
+ inOrder(cur.left);
+ if (pre == null) {
+ head = cur;
+ } else {
+ pre.right = cur;
+ }
+ cur.left = pre;
+ pre = cur;
+ inOrder(cur.right);
+ }
+
+ public static void main(String[] args) {
+
+ }
+
+}
diff --git a/src/main/java/ds/design/LRUCache.java b/src/main/java/ds/design/leetcode146/LRUCache.java
similarity index 88%
rename from src/main/java/ds/design/LRUCache.java
rename to src/main/java/ds/design/leetcode146/LRUCache.java
index 059530d..a428bb5 100644
--- a/src/main/java/ds/design/LRUCache.java
+++ b/src/main/java/ds/design/leetcode146/LRUCache.java
@@ -1,12 +1,13 @@
-package ds.design;
+package ds.design.leetcode146;
import java.util.LinkedHashMap;
import java.util.Map;
/**
- * 最近最少使用缓存
+ * LRU缓存机制
+ * 146 LeetCode https://leetcode-cn.com/problems/lru-cache/
*
- * @author yangyi 2019年01月31日10:17:12
+ * @author yangyi 2021年03月01日23:49:28
*/
public class LRUCache {
diff --git a/src/main/java/ds/design/RandomizedSet.java b/src/main/java/ds/design/leetcode380/RandomizedSet.java
similarity index 98%
rename from src/main/java/ds/design/RandomizedSet.java
rename to src/main/java/ds/design/leetcode380/RandomizedSet.java
index 7694d6c..8d6c4d0 100644
--- a/src/main/java/ds/design/RandomizedSet.java
+++ b/src/main/java/ds/design/leetcode380/RandomizedSet.java
@@ -1,4 +1,4 @@
-package ds.design;
+package ds.design.leetcode380;
import java.util.*;
diff --git a/src/main/java/ds/dp/ClimbStairs.java b/src/main/java/ds/dp/ClimbStairs.java
deleted file mode 100644
index 69a11d3..0000000
--- a/src/main/java/ds/dp/ClimbStairs.java
+++ /dev/null
@@ -1,68 +0,0 @@
-package ds.dp;
-
-/**
- * 爬楼梯
- *
- * 假设你正在爬楼梯。需要 n 阶你才能到达楼顶。
- *
- * 每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢?
- *
- * 注意:给定 n 是一个正整数。
- *
- * 示例 1:
- *
- * 输入: 2
- * 输出: 2
- * 解释: 有两种方法可以爬到楼顶。
- * 1. 1 阶 + 1 阶
- * 2. 2 阶
- * 示例 2:
- *
- * 输入: 3
- * 输出: 3
- * 解释: 有三种方法可以爬到楼顶。
- * 1. 1 阶 + 1 阶 + 1 阶
- * 2. 1 阶 + 2 阶
- * 3. 2 阶 + 1 阶
- *
- * @author yangyi 2019年01月31日23:18:22
- */
-public class ClimbStairs {
-
- public int climbStairs(int n) {
- if (n == 0 || n == 1 || n == 2) {
- return n;
- }
- int all = 0;
- int oneStep = 2;
- int twoStep = 1;
- for (int i = 2; i <= n; i++) { - all = oneStep + twoStep; - twoStep = oneStep; - oneStep = all; - } - return all; - } - - public int climbStairs2(int n) { - if (n == 0 || n == 1 || n == 2) { - return n; - } - int[] res = new int[n + 1]; - res[0] = 1; - res[1] = 1; - for (int i = 2; i <= n; i++) { - res[i] = res[i - 1] + res[i - 2]; - } - return res[n]; - } - - public static void main(String[] args) { - ClimbStairs climbStairs = new ClimbStairs(); - int input2 = 2; - int input3 = 3; - System.out.println("输入" + input2 + "的结果为:" + climbStairs.climbStairs(input2)); - System.out.println("输入" + input3 + "的结果为:" + climbStairs.climbStairs2(input3)); - } - -} diff --git a/src/main/java/ds/dp/leetcode118/Solution.java b/src/main/java/ds/dp/leetcode118/Solution.java new file mode 100644 index 0000000..4a503aa --- /dev/null +++ b/src/main/java/ds/dp/leetcode118/Solution.java @@ -0,0 +1,34 @@ +package ds.dp.leetcode118; + +import java.util.ArrayList; +import java.util.List; + +/** + * 杨辉三角 + * LeetCode 118 https://leetcode-cn.com/problems/pascals-triangle/ + * + * @author yangyi 2021年05月02日00:56:26 + */ +public class Solution { + + public List> generate(int numRows) {
+ List> result = new ArrayList();
+ for (int i = 0; i < numRows; i++) { + List level = new ArrayList();
+ for (int j = 0; j <= i; j++) { + if (j == 0 || j == i) { + level.add(1); + } else { + int num = result.get(i-1).get(j) + result.get(i-1).get(j-1); + level.add(num); + } + } + result.add(level); + } + return result; + } + + public static void main(String[] args) { + System.out.println(new Solution().generate(5).toString()); + } +} diff --git a/src/main/java/ds/dp/leetcode119/Solution.java b/src/main/java/ds/dp/leetcode119/Solution.java new file mode 100644 index 0000000..19da96f --- /dev/null +++ b/src/main/java/ds/dp/leetcode119/Solution.java @@ -0,0 +1,34 @@ +package ds.dp.leetcode119; + +import java.util.ArrayList; +import java.util.List; + +/** + * 杨辉三角 II + * LeetCode 119 https://leetcode-cn.com/problems/pascals-triangle-ii/ + * + * @author yangyi 2021年05月02日01:17:50 + */ +public class Solution { + + public List getRow(int rowIndex) {
+ List pre = new ArrayList();
+ for (int i = 0; i <= rowIndex; i++) { + List cur = new ArrayList();
+ for (int j = 0; j <= i; j++) { + if (j == 0 || j == i) { + cur.add(1); + } else { + int num = pre.get(j-1) + pre.get(j); + cur.add(num); + } + } + pre = cur; + } + return pre; + } + + public static void main(String[] args) { + System.out.println(new Solution().getRow(3).toString()); + } +} diff --git a/src/main/java/ds/dp/leetcode198/Solution.java b/src/main/java/ds/dp/leetcode198/Solution.java new file mode 100644 index 0000000..0c693c1 --- /dev/null +++ b/src/main/java/ds/dp/leetcode198/Solution.java @@ -0,0 +1,31 @@ +package ds.dp.leetcode198; + +/** + * 打家劫舍 + * LeetCode 198 https://leetcode-cn.com/problems/house-robber/ + * + * @author yangyi 2021年03月10日12:06:01 + */ +public class Solution { + + public int rob(int[] nums) { + if (nums.length == 0) { + return 0; + } + if (nums.length == 1) { + return nums[0]; + } + int[] dp = new int[nums.length + 1]; + 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]; + } + + public static void main(String[] args) { + System.out.println(new Solution().rob(new int[]{1, 2, 3, 1})); + System.out.println(new Solution().rob(new int[]{2, 7, 9, 3, 1})); + } +} diff --git a/src/main/java/ds/dp/leetcode213/Solution.java b/src/main/java/ds/dp/leetcode213/Solution.java new file mode 100644 index 0000000..27d571f --- /dev/null +++ b/src/main/java/ds/dp/leetcode213/Solution.java @@ -0,0 +1,49 @@ +package ds.dp.leetcode213; + +/** + * 打家劫舍II + * LeetCode 213 https://leetcode-cn.com/problems/house-robber-ii/ + * + * @author yangyi 2021年03月10日12:21:09 + */ +public class Solution { + + public int rob(int[] nums) { + if (nums.length == 0) { + return 0; + } + if (nums.length == 1) { + return nums[0]; + } + int result1 = robRange(nums, 0, nums.length - 2); + int result2 = robRange(nums, 1, nums.length - 1); + return Math.max(result1, result2); + } + + public int robRange(int[] nums, int start, int end) { + if (nums.length == 0) { + return 0; + } + if (nums.length == 1) { + return nums[0]; + } + if (start == end) { + return nums[start]; + } + int[] dp = new int[nums.length]; + dp[start] = nums[start]; + dp[start + 1] = Math.max(nums[start], nums[start + 1]); + for (int i = start + 2; i <= end; i++) { + dp[i] = Math.max(dp[i - 2] + nums[i], dp[i - 1]); + } + return dp[end]; + } + + public static void main(String[] args) { + System.out.println(new Solution().rob(new int[]{2, 3, 2})); + System.out.println(new Solution().rob(new int[]{1, 2, 3, 1})); + System.out.println(new Solution().rob(new int[]{0})); + System.out.println(new Solution().rob(new int[]{0, 0})); + System.out.println(new Solution().rob(new int[]{1, 2, 3, 4, 5, 1, 2, 3, 4, 5})); + } +} diff --git a/src/main/java/ds/dp/leetcode337/Solution.java b/src/main/java/ds/dp/leetcode337/Solution.java new file mode 100644 index 0000000..c309fa3 --- /dev/null +++ b/src/main/java/ds/dp/leetcode337/Solution.java @@ -0,0 +1,76 @@ +package ds.dp.leetcode337; + +/** + * 打家劫舍 III + * LeetCode 337 https://leetcode-cn.com/problems/house-robber-iii/ + * + * @author yangyi 2021年03月10日15:48:45 + */ +public class Solution { + + public class TreeNode { + int val; + TreeNode left; + TreeNode right; + + TreeNode(int x) { + val = x; + } + } + + public int rob(TreeNode root) { + int[] dp = robTree(root); + return Math.max(dp[0], dp[1]); + } + + /** + * dp数组中 + * 0表示不打算偷的当前节点,dp[0]代表不打算偷当前节点时的最大值 + * 1表示打算偷的当前按节点,dp[1]代表打算偷当前节点时的最大值 + */ + private int[] robTree(TreeNode root) { + if (root == null) { + return new int[]{0, 0}; + } + int[] left = robTree(root.left); + int[] right = robTree(root.right); + //准备偷当前的节点, + int take = root.val + left[0] + right[0]; + //不准备偷当前的节点 + int noTake = Math.max(left[0], left[1]) + Math.max(right[0], right[1]); + return new int[]{noTake, take}; + } + + private TreeNode createTree() { + TreeNode node_3 = new TreeNode(3); + TreeNode node_2 = new TreeNode(2); + TreeNode node_33 = new TreeNode(3); + TreeNode node_333 = new TreeNode(3); + TreeNode node_1 = new TreeNode(1); + node_3.left = node_2; + node_3.right = node_33; + node_2.right = node_333; + node_33.right = node_1; + return node_3; + } + + private TreeNode createTree2() { + TreeNode node_3 = new TreeNode(3); + TreeNode node_4 = new TreeNode(4); + TreeNode node_5 = new TreeNode(5); + TreeNode node_1 = new TreeNode(1); + TreeNode node_33 = new TreeNode(3); + TreeNode node_11 = new TreeNode(1); + node_3.left = node_4; + node_3.right = node_5; + node_4.left = node_1; + node_4.right = node_33; + node_5.right = node_11; + return node_3; + } + + public static void main(String[] args) { + System.out.println(new Solution().rob(new Solution().createTree())); + System.out.println(new Solution().rob(new Solution().createTree2())); + } +} diff --git a/src/main/java/ds/dp/leetcode343/Solution.java b/src/main/java/ds/dp/leetcode343/Solution.java new file mode 100644 index 0000000..ead646e --- /dev/null +++ b/src/main/java/ds/dp/leetcode343/Solution.java @@ -0,0 +1,31 @@ +package ds.dp.leetcode343; + +/** + * 整数拆分 + * LeetCode 343 https://leetcode-cn.com/problems/integer-break/ + * + * @author yangyi 2021年03月10日10:45:09 + */ +public class Solution { + + /** + * 解释: + * 定义: 当前正整数i,对应的最大乘积为dp[i] + * j和i-j正好为针对正整数i的拆分,因为两者相加正好为i + */ + public int integerBreak(int n) { + int[] dp = new int[n + 1]; + dp[2] = 1; + for (int i = 3; i <= n; i++) { + for (int j = 1; j <= i - 1; j++) { + dp[i] = Math.max(dp[i], Math.max(j * (i - j), j * dp[i - j])); + } + } + return dp[n]; + } + + public static void main(String[] args) { + System.out.println(new Solution().integerBreak(2)); + System.out.println(new Solution().integerBreak(10)); + } +} diff --git a/src/main/java/ds/dp/leetcode509/Solution.java b/src/main/java/ds/dp/leetcode509/Solution.java new file mode 100644 index 0000000..3f98e4d --- /dev/null +++ b/src/main/java/ds/dp/leetcode509/Solution.java @@ -0,0 +1,28 @@ +package ds.dp.leetcode509; + +/** + * 斐波那契数 + * LeetCode 509 https://leetcode-cn.com/problems/fibonacci-number/ + * + * @author yangyi 2021年03月08日16:45:49 + */ +public class Solution { + public int fib(int n) { + if (n <= 1) { + return n; + } + int[] dp = new int[2]; + dp[0] = 0; + dp[1] = 1; + for (int i = 2; i <= n; i++) { + int sum = dp[0] + dp[1]; + dp[0] = dp[1]; + dp[1] = sum; + } + return dp[1]; + } + + public static void main(String[] args) { + System.out.println(new Solution().fib(10)); + } +} diff --git a/src/main/java/ds/dp/leetcode60/Solution.java b/src/main/java/ds/dp/leetcode60/Solution.java new file mode 100644 index 0000000..e0d1767 --- /dev/null +++ b/src/main/java/ds/dp/leetcode60/Solution.java @@ -0,0 +1,33 @@ +package ds.dp.leetcode60; + +/** + * 不同路径 + * LeetCode 60 https://leetcode-cn.com/problems/unique-paths/ + * + * @author yangyi 2021年03月08日18:40:34 + */ +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 j = 0; j < n; j++) { + dp[0][j] = 1; + } + for (int i = 1; i < m; i++) { + for (int j = 1; j < n; j++) { + dp[i][j] = dp[i][j - 1] + dp[i - 1][j]; + } + } + return dp[m - 1][n - 1]; + } + + public static void main(String[] args) { + System.out.println(new Solution().uniquePaths(3, 7)); + System.out.println(new Solution().uniquePaths(3, 2)); + System.out.println(new Solution().uniquePaths(7, 3)); + System.out.println(new Solution().uniquePaths(3, 3)); + } +} diff --git a/src/main/java/ds/dp/leetcode63/Solution.java b/src/main/java/ds/dp/leetcode63/Solution.java new file mode 100644 index 0000000..5faa39a --- /dev/null +++ b/src/main/java/ds/dp/leetcode63/Solution.java @@ -0,0 +1,38 @@ +package ds.dp.leetcode63; + +/** + * 不同路径 II + * LeetCode 63 https://leetcode-cn.com/problems/unique-paths-ii/ + * + * @author yangyi 2021年03月08日22:04:16 + */ +public class Solution { + + public int uniquePathsWithObstacles(int[][] obstacleGrid) { + int m = obstacleGrid.length; + int n = obstacleGrid[0].length; + int[][] dp = new int[m][n]; + for (int i = 0; i < m && obstacleGrid[i][0] == 0; i++) { + dp[i][0] = 1; + } + for (int j = 0; j < n && obstacleGrid[0][j] == 0; j++) { + dp[0][j] = 1; + } + for (int i = 1; i < m; i++) { + for (int j = 1; j < n; j++) { + if (obstacleGrid[i][j] == 1) { + continue; + } + dp[i][j] = dp[i][j - 1] + dp[i - 1][j]; + } + } + return dp[m - 1][n - 1]; + } + + public static void main(String[] args) { + int[][] a1 = {{0, 0, 0}, {0, 1, 0}, {0, 0, 0}}; + int[][] a2 = {{0, 1}, {0, 0}}; + System.out.println(new Solution().uniquePathsWithObstacles(a1)); + System.out.println(new Solution().uniquePathsWithObstacles(a2)); + } +} diff --git a/src/main/java/ds/dp/leetcode70/Solution.java b/src/main/java/ds/dp/leetcode70/Solution.java new file mode 100644 index 0000000..d069140 --- /dev/null +++ b/src/main/java/ds/dp/leetcode70/Solution.java @@ -0,0 +1,53 @@ +package ds.dp.leetcode70; + +/** + * 爬楼梯 + * LeetCode 70 https://leetcode-cn.com/problems/climbing-stairs/ + * + * @author yangyi 2021年03月08日17:09:06 + */ +public class Solution { + + /** + * 提前准备好一个dp的数组来装所有结果,空间复杂度为O(n) + */ + public int climbStairs(int n) { + if (n <= 1) { + 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]; + } + + /** + * 只记录其中的3个数,最后输出最后一个计算得到的结果,空间复杂度为O(1) + */ + public int climbStairs2(int n) { + if (n <= 1) { + return n; + } + int[] dp = new int[3]; + dp[1] = 1; + dp[2] = 2; + for (int i = 3; i <= n; i++) { + int sum = dp[1] + dp[2]; + dp[1] = dp[2]; + dp[2] = sum; + } + return dp[2]; + } + + public static void main(String[] args) { + Solution climbStairs = new Solution(); + int input2 = 2; + int input3 = 3; + System.out.println("输入" + input2 + "的结果为:" + climbStairs.climbStairs(input2)); + System.out.println("输入" + input3 + "的结果为:" + climbStairs.climbStairs2(input3)); + } + +} diff --git a/src/main/java/ds/dp/leetcode746/Solution.java b/src/main/java/ds/dp/leetcode746/Solution.java new file mode 100644 index 0000000..6d2ce94 --- /dev/null +++ b/src/main/java/ds/dp/leetcode746/Solution.java @@ -0,0 +1,28 @@ +package ds.dp.leetcode746; + +/** + * 使用最小花费爬楼梯 + * LeetCode 746 https://leetcode-cn.com/problems/min-cost-climbing-stairs/ + * + * @author yangyi 2021年03月08日17:48:17 + */ +public class Solution { + + public int minCostClimbingStairs(int[] cost) { + int[] dp = new int[cost.length]; + dp[0] = cost[0]; + dp[1] = cost[1]; + for (int i = 2; i < cost.length; i++) { + //地推公式: 每次走一步或者每次都两步中的最小花费 + 当前这一步的花费 + dp[i] = Math.min(dp[i - 1], dp[i - 2]) + cost[i]; + } + //最后登顶的一步不用花费,直接从倒数第一步和倒数第二步中选取花费最小的值 + return Math.min(dp[cost.length - 1], dp[cost.length - 2]); + } + + public static void main(String[] args) { + System.out.println(new Solution().minCostClimbingStairs(new int[]{10, 15, 20})); + System.out.println(new Solution().minCostClimbingStairs(new int[]{1, 100, 1, 1, 1, 100, 1, 1, 100, 1})); + } + +} diff --git a/src/main/java/ds/dp/leetcode96/Solution.java b/src/main/java/ds/dp/leetcode96/Solution.java new file mode 100644 index 0000000..ce0f792 --- /dev/null +++ b/src/main/java/ds/dp/leetcode96/Solution.java @@ -0,0 +1,25 @@ +package ds.dp.leetcode96; + +/** + * 不同的二叉搜索树 + * LeetCode 96 https://leetcode-cn.com/problems/unique-binary-search-trees/ + * + * @author yangyi 2021年03月08日22:38:36 + */ +public class Solution { + + public int numTrees(int n) { + int[] dp = new int[n + 1]; + dp[0] = 1; + for (int i = 1; i <= n; i++) { + for (int j = 1; j <= i; j++) { + dp[i] += dp[j - 1] * dp[i - j]; + } + } + return dp[n]; + } + + public static void main(String[] args) { + System.out.println(new Solution().numTrees(3)); + } +} diff --git a/src/main/java/ds/greedy/leetcode122/Solution.java b/src/main/java/ds/greedy/leetcode122/Solution.java new file mode 100644 index 0000000..4205343 --- /dev/null +++ b/src/main/java/ds/greedy/leetcode122/Solution.java @@ -0,0 +1,24 @@ +package ds.greedy.leetcode122; + +/** + * 买卖股票的最佳时机 II + * LeetCode 122 https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock-ii/ + * + * @author yangyi 2021年02月22日15:21:00 + */ +public class Solution { + + public int maxProfit(int[] prices) { + int max = 0; + for (int i = 1; i < prices.length; i++) { + max += Math.max(prices[i] - prices[i - 1], 0); + } + return max; + } + + public static void main(String[] args) { + System.out.println(new Solution().maxProfit(new int[]{7, 1, 5, 3, 6, 4})); + System.out.println(new Solution().maxProfit(new int[]{1, 2, 3, 4, 5})); + System.out.println(new Solution().maxProfit(new int[]{7, 6, 4, 3, 1})); + } +} diff --git a/src/main/java/ds/greedy/leetcode376/Solution.java b/src/main/java/ds/greedy/leetcode376/Solution.java new file mode 100644 index 0000000..e391705 --- /dev/null +++ b/src/main/java/ds/greedy/leetcode376/Solution.java @@ -0,0 +1,44 @@ +package ds.greedy.leetcode376; + +/** + * 摆动序列 + * LeetCode 376 https://leetcode-cn.com/problems/wiggle-subsequence/ + * + * @author yangyi 2021年02月22日12:38:34 + */ +public class Solution { + + /** + * 统计上坡时的峰和下坡时的谷 + * cur为斜率,不是上坡就是下坡,不可能等于0 + * pre为前后两个数的差值,可能等于0 + */ + public int wiggleMaxLength(int[] nums) { + if (nums == null) { + return 0; + } + if (nums.length <= 0) { + return nums.length; + } + int pre = 0; + int cur = 0; + int result = 1; + for (int i = 1; i < nums.length; i++) { + cur = nums[i] - nums[i - 1]; + if ((cur> 0 && pre <= 0) || (cur < 0 && pre>= 0)) {
+ result++;
+ pre = cur;
+ }
+ }
+ return result;
+ }
+
+ public static void main(String[] args) {
+ System.out.println(new Solution().wiggleMaxLength(
+ new int[]{1, 7, 4, 9, 2, 5}));
+ System.out.println(new Solution().wiggleMaxLength(
+ new int[]{1, 17, 5, 10, 13, 15, 10, 5, 16, 8}));
+ System.out.println(new Solution().wiggleMaxLength(
+ new int[]{1, 2, 3, 4, 5, 6, 7, 8, 9}));
+ }
+}
diff --git a/src/main/java/ds/greedy/leetcode455/Solution.java b/src/main/java/ds/greedy/leetcode455/Solution.java
new file mode 100644
index 0000000..5fabe8d
--- /dev/null
+++ b/src/main/java/ds/greedy/leetcode455/Solution.java
@@ -0,0 +1,31 @@
+package ds.greedy.leetcode455;
+
+import java.util.Arrays;
+
+/**
+ * 分发饼干
+ * 455 https://leetcode-cn.com/problems/assign-cookies/
+ *
+ * @author yangyi 2021年02月22日09:02:42
+ */
+public class Solution {
+
+ public int findContentChildren(int[] g, int[] s) {
+ Arrays.sort(g);
+ Arrays.sort(s);
+ int index = s.length - 1;
+ int result = 0;
+ for (int i = g.length - 1; i>= 0; i--) {
+ if (index>= 0 && s[index]>= g[i]) {
+ result++;
+ index--;
+ }
+ }
+ return result;
+ }
+
+ public static void main(String[] args) {
+ System.out.println(new Solution().findContentChildren(new int[]{1, 2, 3}, new int[]{1, 1}));
+ System.out.println(new Solution().findContentChildren(new int[]{1, 2}, new int[]{1, 2, 3}));
+ }
+}
diff --git a/src/main/java/ds/greedy/leetcode53/Solution.java b/src/main/java/ds/greedy/leetcode53/Solution.java
new file mode 100644
index 0000000..cad8549
--- /dev/null
+++ b/src/main/java/ds/greedy/leetcode53/Solution.java
@@ -0,0 +1,34 @@
+package ds.greedy.leetcode53;
+
+/**
+ * 最大子序和
+ * LeetCode 53 https://leetcode-cn.com/problems/maximum-subarray/
+ *
+ * @author yangyi 2021年02月22日14:37:28
+ */
+public class Solution {
+
+ public int maxSubArray(int[] nums) {
+ int max = Integer.MIN_VALUE;
+ int result = 0;
+ for (int i = 0; i < nums.length; i++) { + result += nums[i]; + if (result> max) {
+ max = result;
+ }
+ if (result <= 0) { + result = 0; + } + } + return max; + } + + public static void main(String[] args) { + System.out.println( + new Solution().maxSubArray(new int[]{-2, 1, -3, 4, -1, 2, 1, -5, 4})); + System.out.println(new Solution().maxSubArray(new int[]{1})); + System.out.println(new Solution().maxSubArray(new int[]{0})); + System.out.println(new Solution().maxSubArray(new int[]{-1})); + System.out.println(new Solution().maxSubArray(new int[]{-100000})); + } +} diff --git a/src/main/java/ds/greedy/leetcode55/Solution.java b/src/main/java/ds/greedy/leetcode55/Solution.java new file mode 100644 index 0000000..9d9c6bc --- /dev/null +++ b/src/main/java/ds/greedy/leetcode55/Solution.java @@ -0,0 +1,31 @@ +package ds.greedy.leetcode55; + +/** + * 跳跃游戏 + * LeetCode 55 https://leetcode-cn.com/problems/jump-game/ + * + * @author yangyi 2021年02月27日23:40:48 + */ +public class Solution { + + public boolean canJump(int[] nums) { + if (nums.length == 1) { + return true; + } + int cover = 0; + for (int i = 0; i <= cover; i++) { + cover = Math.max(cover, i + nums[i]); + if (cover>= nums.length - 1) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public static void main(String[] args) {
+ System.out.println(new Solution().canJump(new int[]{2, 3, 1, 1, 4}));
+ System.out.println(new Solution().canJump(new int[]{3, 2, 1, 0, 4}));
+ System.out.println(new Solution().canJump(new int[]{2, 0, 0}));
+ }
+
+}
diff --git a/src/main/java/ds/hashmap/leetcode1/Solution.java b/src/main/java/ds/hashmap/leetcode1/Solution.java
index aef38d6..359331f 100644
--- a/src/main/java/ds/hashmap/leetcode1/Solution.java
+++ b/src/main/java/ds/hashmap/leetcode1/Solution.java
@@ -1,6 +1,6 @@
package ds.hashmap.leetcode1;
-import ds.InsertSort;
+import ds.sort.InsertSort;
import java.util.Arrays;
import java.util.HashMap;
diff --git a/src/main/java/ds/hashmap/leetcode560/Solution.java b/src/main/java/ds/hashmap/leetcode560/Solution.java
new file mode 100644
index 0000000..f4c8997
--- /dev/null
+++ b/src/main/java/ds/hashmap/leetcode560/Solution.java
@@ -0,0 +1,33 @@
+package ds.hashmap.leetcode560;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * 和为 K 的子数组
+ * LeetCode 560 https://leetcode-cn.com/problems/subarray-sum-equals-k/
+ * 剑指 Offer II 010 https://leetcode-cn.com/problems/QTMn0o/
+ *
+ * @author yangyi 2022年02月25日15:23:05
+ */
+public class Solution {
+ public int subarraySum(int[] nums, int k) {
+ Map sumToCount = new HashMap();
+ sumToCount.put(0, 1);
+ int sums = 0;
+ int count = 0;
+ for (int i = 0; i < nums.length; i++) { + sums += nums[i]; + //哈希表的键是前i个数字之和,值为每个和出现的次数 + //sums - k为前i个数字之和 + count += sumToCount.getOrDefault(sums - k, 0); + sumToCount.put(sums, sumToCount.getOrDefault(sums, 0) + 1); + } + return count; + } + + public static void main(String[] args) { + System.out.println(new Solution().subarraySum(new int[]{1, 2, 3}, 3)); + System.out.println(new Solution().subarraySum(new int[]{1, 1, 1}, 2)); + } +} diff --git a/src/main/java/ds/hashmap/targetofferII011/Solution.java b/src/main/java/ds/hashmap/targetofferII011/Solution.java new file mode 100644 index 0000000..13bf0b6 --- /dev/null +++ b/src/main/java/ds/hashmap/targetofferII011/Solution.java @@ -0,0 +1,35 @@ +package ds.hashmap.targetofferII011; + +import java.util.HashMap; +import java.util.Map; + +/** + * 0和1个数相同的子数组 + * 剑指Offer II 011 https://leetcode-cn.com/problems/A1NYOS/ + * + * @author yangyi 2022年02月25日16:01:52 + */ +public class Solution { + + public int findMaxLength(int[] nums) { + Map sumsToIndex = new HashMap();
+ sumsToIndex.put(0, -1);
+ int sums = 0;
+ int maxLength = 0;
+ for (int i = 0; i < nums.length; i++) { + sums += nums[i] == 0 ? -1 : 1; + //哈希表的键是从第1个数字开始累加到当前扫描到的数字之和,而值是当前扫描的数字的下标 + if (sumsToIndex.containsKey(sums)) { + maxLength = Math.max(maxLength, i - sumsToIndex.getOrDefault(sums, 0)); + } else { + sumsToIndex.put(sums, i); + } + } + return maxLength; + } + + public static void main(String[] args) { + System.out.println(new Solution().findMaxLength(new int[]{0, 1})); + System.out.println(new Solution().findMaxLength(new int[]{0, 1, 0})); + } +} diff --git a/src/main/java/ds/hashmap/targetofferII012/Solution.java b/src/main/java/ds/hashmap/targetofferII012/Solution.java new file mode 100644 index 0000000..a495d3a --- /dev/null +++ b/src/main/java/ds/hashmap/targetofferII012/Solution.java @@ -0,0 +1,32 @@ +package ds.hashmap.targetofferII012; + +/** + * 左右两边子数组的和相等 + * 剑指 Offer II 012 https://leetcode-cn.com/problems/tvdfij/ + * + * @author yangyi 2022年02月25日16:27:59 + */ +public class Solution { + + public int pivotIndex(int[] nums) { + int total = 0; + for (int num : nums) { + total += num; + } + //前i-1个数字之和 + int sum = 0; + for (int i = 0; i < nums.length; i++) { + sum += nums[i]; + if (sum - nums[i] == total - sum) { + return i; + } + } + return -1; + } + + public static void main(String[] args) { + System.out.println(new Solution().pivotIndex(new int[]{1, 7, 3, 6, 5, 6})); + System.out.println(new Solution().pivotIndex(new int[]{1, 2, 3})); + System.out.println(new Solution().pivotIndex(new int[]{2, 1, -1})); + } +} diff --git a/src/main/java/ds/hashmap/targetofferII013/NumMatrix.java b/src/main/java/ds/hashmap/targetofferII013/NumMatrix.java new file mode 100644 index 0000000..204c768 --- /dev/null +++ b/src/main/java/ds/hashmap/targetofferII013/NumMatrix.java @@ -0,0 +1,47 @@ +package ds.hashmap.targetofferII013; + +/** + * 二维子矩阵的和 + * 剑指 Offer II 013 https://leetcode-cn.com/problems/O4NDxx/ + * + * @author yangyi 2022年02月25日17:04:09 + */ +public class NumMatrix { + + private int[][] sums; + + public NumMatrix(int[][] matrix) { + if (matrix.length == 0 || matrix[0].length == 0) { + return; + } + sums = new int[matrix.length + 1][matrix[0].length + 1]; + for (int i = 0; i < matrix.length; i++) { + int rowSums = 0; + for (int j = 0; j < matrix[0].length; j++) { + //rowSums为最后一行的和 + //此处为二维矩阵的求和方式 + rowSums += matrix[i][j]; + sums[i + 1][j + 1] = sums[i][j + 1] + rowSums; + } + } + } + + public int sumRegion(int row1, int col1, int row2, int col2) { + //此处为二维矩阵的特定范围中的矩阵的求和方式 + return sums[row2 + 1][col2 + 1] - sums[row2 + 1][col1] - sums[row1][col2 + 1] + sums[row1][col1]; + } + + public static void main(String[] args) { + int[][] matrix = { + {3, 0, 1, 4, 2}, + {5, 6, 3, 2, 1}, + {1, 2, 0, 1, 5}, + {4, 1, 0, 1, 7}, + {1, 0, 3, 0, 5}}; + NumMatrix numMatrix = new NumMatrix(matrix); + System.out.println(numMatrix.sumRegion(2, 1, 4, 3)); + System.out.println(numMatrix.sumRegion(1, 1, 2, 2)); + System.out.println(numMatrix.sumRegion(1, 2, 2, 4)); + } + +} diff --git a/src/main/java/ds/heap/leetcode347/Solution.java b/src/main/java/ds/heap/leetcode347/Solution.java new file mode 100644 index 0000000..7dd7b6b --- /dev/null +++ b/src/main/java/ds/heap/leetcode347/Solution.java @@ -0,0 +1,44 @@ +package ds.heap.leetcode347; + +import java.util.*; + +/** + * 前 K 个高频元素 + * LeetCode 347 https://leetcode-cn.com/problems/top-k-frequent-elements/ + * + * @author yangyi 2007月12日16:00:48git + */ +public class Solution { + + public int[] topKFrequent(int[] nums, int k) { + Map map = new LinkedHashMap();
+ for (int i = 0; i < nums.length; i++) { + if (map.containsKey(nums[i])) { + map.put(nums[i], map.getOrDefault(nums[i], -1) + 1); + } else { + map.put(nums[i], 1); + } + } + PriorityQueue priorityQueue = new PriorityQueue(
+ k, Comparator.comparing(o -> map.getOrDefault(o, -1)));
+ for (Map.Entry kv : map.entrySet()) {
+ if (priorityQueue.size() < k) { + priorityQueue.offer(kv.getKey()); + } else if (kv.getValue()> map.getOrDefault(priorityQueue.peek(), -1)) {
+ priorityQueue.poll();
+ priorityQueue.offer(kv.getKey());
+ }
+ }
+ return priorityQueue.stream().mapToInt(value -> value).toArray();
+ }
+
+ public static void main(String[] args) {
+ int[] a = {1, 1, 1, 2, 2, 3};
+ int[] b = {1};
+ int[] c = {4, 1, -1, 2, -1, 2, 3};
+ Solution solution = new Solution();
+ System.out.println(Arrays.toString(solution.topKFrequent(a, 2)));
+ System.out.println(Arrays.toString(solution.topKFrequent(b, 1)));
+ System.out.println(Arrays.toString(solution.topKFrequent(c, 2)));
+ }
+}
diff --git a/src/main/java/ds/pointer/leetcode11/Solution.java b/src/main/java/ds/pointer/leetcode11/Solution.java
new file mode 100644
index 0000000..a609946
--- /dev/null
+++ b/src/main/java/ds/pointer/leetcode11/Solution.java
@@ -0,0 +1,30 @@
+package ds.pointer.leetcode11;
+
+/**
+ * 盛最多水的容器
+ * LeetCode 11 https://leetcode-cn.com/problems/container-with-most-water/
+ *
+ * @author yangyi 2022年05月05日22:47:18
+ */
+public class Solution {
+
+ public int maxArea(int[] height) {
+ int result = 0, start = 0, end = height.length - 1;
+ while (start < end) { + int area = Math.min(height[start], height[end]) * (end - start); + result = Math.max(result, area); + //矮的边向内移动,因为整体的盛水面积是由矮的边所决定的 + if (height[start] < height[end]) { + start++; + } else { + end--; + } + } + return result; + } + + public static void main(String[] args) { + System.out.println(new Solution().maxArea(new int[]{1, 8, 6, 2, 5, 4, 8, 3, 7})); + System.out.println(new Solution().maxArea(new int[]{1, 1})); + } +} diff --git a/src/main/java/ds/pointer/leetcode141/Solution.java b/src/main/java/ds/pointer/leetcode141/Solution.java index 08e4edc..4cf529d 100644 --- a/src/main/java/ds/pointer/leetcode141/Solution.java +++ b/src/main/java/ds/pointer/leetcode141/Solution.java @@ -7,7 +7,7 @@ * 环形链表 * LeetCode 141 https://leetcode-cn.com/problems/linked-list-cycle/ * - * @author yangyi 2020年12月10日22:35:31 + * @author yangyi 2022年04月24日15:07:52 */ public class Solution { @@ -85,14 +85,16 @@ private boolean hasCycleSet(ListNode head) { public boolean hasCycle(ListNode head) { ListNode fast = head; ListNode slow = head; - while (fast != null && fast.next != null) { + while (true) { + if (fast == null || fast.next == null) { + return false; + } fast = fast.next.next; slow = slow.next; - if (fast == slow) { + if (slow == fast) { return true; } } - return false; } public static void main(String[] args) { diff --git a/src/main/java/ds/pointer/leetcode15/Solution.java b/src/main/java/ds/pointer/leetcode15/Solution.java index 6365916..0117fcb 100644 --- a/src/main/java/ds/pointer/leetcode15/Solution.java +++ b/src/main/java/ds/pointer/leetcode15/Solution.java @@ -22,28 +22,28 @@ public List> threeSum(int[] nums) {
if (i> 0 && nums[i] == nums[i - 1]) {
continue;
}
- int left = i + 1;
- int right = nums.length - 1;
- while (left < right) { - int threeSum = nums[i] + nums[left] + nums[right]; - if (threeSum < 0) { - left++; - } else if (threeSum> 0) {
- right--;
+ int start = i + 1;
+ int end = nums.length - 1;
+ while (start < end) { + int sum = nums[i] + nums[start] + nums[end]; + if (sum < 0) { + start++; + } else if (sum> 0) {
+ end--;
} else {
- LinkedList res = new LinkedList();
- res.add(nums[i]);
- res.add(nums[left]);
- res.add(nums[right]);
- result.add(res);
- while (left < right && nums[left] == nums[left + 1]) { - left++; + List num = new LinkedList();
+ num.add(nums[i]);
+ num.add(nums[start]);
+ num.add(nums[end]);
+ result.add(num);
+ while (start < end && nums[start] == nums[start + 1]) { + start++; } - while (left < right && nums[right] == nums[right - 1]) { - right--; + while (start < end && nums[end] == nums[end - 1]) { + end--; } - right--; - left++; + start++; + end--; } } } diff --git a/src/main/java/ds/pointer/leetcode167/Solution.java b/src/main/java/ds/pointer/leetcode167/Solution.java index 5b5f459..a648952 100644 --- a/src/main/java/ds/pointer/leetcode167/Solution.java +++ b/src/main/java/ds/pointer/leetcode167/Solution.java @@ -6,7 +6,7 @@ * 两数之和 II - 输入有序数组 * LeetCode 167 https://leetcode-cn.com/problems/two-sum-ii-input-array-is-sorted/ * - * @author yangyi 2020年12月14日11:52:36 + * @author yangyi 2022年04月24日18:47:00 */ public class Solution { @@ -15,12 +15,12 @@ public int[] twoSum(int[] numbers, int target) { int end = numbers.length - 1; while (start < end) { int sum = numbers[start] + numbers[end]; - if (sum == target) { - return new int[]{start + 1, end + 1}; - } else if (sum < target) { + if (sum < target) { start++; } else if (sum> target) {
end--;
+ } else if (sum == target) {
+ return new int[]{start + 1, end + 1};
}
}
return new int[]{-1, -1};
@@ -28,7 +28,7 @@ public int[] twoSum(int[] numbers, int target) {
public static void main(String[] args) {
int[] a = {2, 7, 11, 15};
- Solution twoSumII = new Solution();
- System.out.println(Arrays.toString(a) + "数组中和为9对应的数的索引为:" + Arrays.toString(twoSumII.twoSum(a, 9)));
+ Solution twoSum2 = new Solution();
+ System.out.println(Arrays.toString(a) + "数组中和为9对应的数的索引为:" + Arrays.toString(twoSum2.twoSum(a, 9)));
}
}
diff --git a/src/main/java/ds/pointer/leetcode18/Solution.java b/src/main/java/ds/pointer/leetcode18/Solution.java
index bd590b9..27d35bf 100644
--- a/src/main/java/ds/pointer/leetcode18/Solution.java
+++ b/src/main/java/ds/pointer/leetcode18/Solution.java
@@ -15,7 +15,7 @@ public class Solution {
public List> fourSum(int[] nums, int target) {
Arrays.sort(nums);
- List> result = new ArrayList();
+ List> result = new LinkedList();
for (int i = 0; i < nums.length; i++) { if (i> 0 && nums[i] == nums[i - 1]) {
continue;
@@ -24,24 +24,29 @@ public List> fourSum(int[] nums, int target) {
if (j> i + 1 && nums[j] == nums[j - 1]) {
continue;
}
- int left = j + 1;
- int right = nums.length - 1;
- while (left < right) { - int fourSum = nums[i] + nums[j] + nums[left] + nums[right]; + int start = j + 1; + int end = nums.length - 1; + while (start < end) { + int fourSum = nums[i] + nums[j] + nums[start] + nums[end]; if (fourSum < target) { - left++; + start++; } else if (fourSum> target) {
- right--;
+ end--;
} else {
- result.add(new LinkedList(Arrays.asList(nums[i], nums[j], nums[left], nums[right])));
- while (left < right && nums[left] == nums[left + 1]) { - left++; + List four = new LinkedList();
+ four.add(nums[i]);
+ four.add(nums[j]);
+ four.add(nums[start]);
+ four.add(nums[end]);
+ result.add(four);
+ while (start < end && nums[start] == nums[start + 1]) { + start++; } - while (left < right && nums[right] == nums[right - 1]) { - right--; + while (start < end && nums[end] == nums[end - 1]) { + end--; } - left++; - right--; + start++; + end--; } } } diff --git a/src/main/java/ds/pointer/leetcode287/Solution.java b/src/main/java/ds/pointer/leetcode287/Solution.java index 8d3c0df..a0b44e1 100644 --- a/src/main/java/ds/pointer/leetcode287/Solution.java +++ b/src/main/java/ds/pointer/leetcode287/Solution.java @@ -9,8 +9,7 @@ public class Solution { public int findDuplicate(int[] nums) { - int slow = 0; - int fast = 0; + int slow = 0, fast = 0; slow = nums[slow]; fast = nums[nums[fast]]; while (slow != fast) { diff --git a/src/main/java/ds/pointer/leetcode42/Solution.java b/src/main/java/ds/pointer/leetcode42/Solution.java new file mode 100644 index 0000000..1a1f419 --- /dev/null +++ b/src/main/java/ds/pointer/leetcode42/Solution.java @@ -0,0 +1,35 @@ +package ds.pointer.leetcode42; + +/** + * 接雨水 + * LeetCode 42 https://leetcode-cn.com/problems/trapping-rain-water/ + * + * @author yangyi 2022年05月05日23:31:02 + */ +public class Solution { + + /** + * 左右指针两边高度的最大值中的较小的那个 - 当前高度 = 当前接水量 + */ + public int trap(int[] height) { + int result = 0, start = 0, end = height.length - 1; + int startMax = 0, endMax = 0; + while (start < end) { + startMax = Math.max(startMax, height[start]); + endMax = Math.max(endMax, height[end]); + if (height[start] < height[end]) { + result += Math.min(startMax, endMax) - height[start]; + start++; + } else { + result += Math.min(startMax, endMax) - height[end]; + end--; + } + } + return result; + } + + public static void main(String[] args) { + System.out.println(new Solution().trap(new int[]{0, 1, 0, 2, 1, 0, 1, 3, 2, 1, 2, 1})); + System.out.println(new Solution().trap(new int[]{4, 2, 0, 3, 2, 5})); + } +} diff --git a/src/main/java/ds/pointer/leetcode80/Solution.java b/src/main/java/ds/pointer/leetcode80/Solution.java new file mode 100644 index 0000000..c20c450 --- /dev/null +++ b/src/main/java/ds/pointer/leetcode80/Solution.java @@ -0,0 +1,33 @@ +package ds.pointer.leetcode80; + +/** + * 删除有序数组中的重复项 II + * LeetCode 80 https://leetcode-cn.com/problems/remove-duplicates-from-sorted-array-ii/ + * + * @author yangyi 2022年05月06日00:23:37 + */ +public class Solution { + + /** + * 起始位置相当于一个最多出现几次的【游标卡尺】 + */ + public int removeDuplicates(int[] nums) { + if (nums.length <= 2) { + return nums.length; + } + int fast = 2, slow = 2; + while (fast < nums.length) { + if (nums[slow - 2] != nums[fast]) { + nums[slow] = nums[fast]; + slow++; + } + fast++; + } + return slow; + } + + public static void main(String[] args) { + System.out.println(new Solution().removeDuplicates(new int[]{1, 1, 1, 2, 2, 3})); + System.out.println(new Solution().removeDuplicates(new int[]{0, 0, 1, 1, 1, 1, 2, 3, 3})); + } +} diff --git a/src/main/java/ds/pointer/leetcode876/Solution.java b/src/main/java/ds/pointer/leetcode876/Solution.java index 9f1183a..b7814fe 100644 --- a/src/main/java/ds/pointer/leetcode876/Solution.java +++ b/src/main/java/ds/pointer/leetcode876/Solution.java @@ -4,7 +4,7 @@ * 链表的中间节点 * LeetCode 876 https://leetcode-cn.com/problems/middle-of-the-linked-list/ * - * @author yangyi 2020年12月11日00:06:32 + * @author yangyi 2022年04月24日17:33:20 */ public class Solution { @@ -54,7 +54,10 @@ private ListNode createLink2() { public ListNode middleNode(ListNode head) { ListNode fast = head; ListNode slow = head; - while (fast != null && fast.next != null) { + while (true) { + if (fast == null || fast.next == null) { + break; + } fast = fast.next.next; slow = slow.next; } diff --git a/src/main/java/ds/pointer/leetcode905/Solution.java b/src/main/java/ds/pointer/leetcode905/Solution.java index fd44d70..d902d20 100644 --- a/src/main/java/ds/pointer/leetcode905/Solution.java +++ b/src/main/java/ds/pointer/leetcode905/Solution.java @@ -6,33 +6,30 @@ * 按奇偶排序数组 * LeetCode 905 https://leetcode-cn.com/problems/sort-array-by-parity/ * - * @author yangyi 2020年12月15日14:12:15 + * @author yangyi 2022年04月24日19:17:01 */ public class Solution { - public int[] sortArrayByParity(int[] A) { - if (A == null) { - return new int[]{}; - } - if (A.length == 0) { - return A; + public int[] sortArrayByParity(int[] nums) { + if (nums == null || nums.length == 0) { + return new int[]{0}; } int start = 0; - int end = A.length - 1; + int end = nums.length - 1; while (start < end) { - if (A[start] % 2 == 0) { + if (nums[start] % 2 == 0) { start++; continue; } - if (A[end] % 2 != 0) { + if (nums[end] % 2 != 0) { end--; continue; } - int temp = A[start]; - A[start] = A[end]; - A[end] = temp; + int temp = nums[start]; + nums[start] = nums[end]; + nums[end] = temp; } - return A; + return nums; } public static void main(String[] args) { diff --git a/src/main/java/ds/pointer/targetoffer05/Solution.java b/src/main/java/ds/pointer/targetoffer05/Solution.java new file mode 100644 index 0000000..499bab8 --- /dev/null +++ b/src/main/java/ds/pointer/targetoffer05/Solution.java @@ -0,0 +1,47 @@ +package ds.pointer.targetoffer05; + +import java.util.Arrays; + +/** + * 替换空格 + * 剑指offer 05 https://leetcode-cn.com/problems/ti-huan-kong-ge-lcof/ + * + * @author yangyi 2021年01月19日17:21:34 + */ +public class Solution { + + public String replaceSpace(String s) { + int spaceCount = 0; + char[] chars = s.toCharArray(); + for (char c : chars) { + if (c == ' ') { + spaceCount++; + } + } + char[] newChars = Arrays.copyOf(chars, chars.length + spaceCount * 2); + for (int oldIndex = chars.length - 1, newIndex = newChars.length - 1; oldIndex < newIndex; oldIndex--, newIndex--) { + if (newChars[oldIndex] != ' ') { + newChars[newIndex] = newChars[oldIndex]; + } else { + newChars[newIndex--] = '0'; + newChars[newIndex--] = '2'; + newChars[newIndex] = '%'; + } + } + return new String(newChars); + } + + public static void main(String[] args) { + String string = "we are Chinese"; + String string1 = " "; + String string2 = ""; + String string3 = " "; + String string4 = " we are Chinese "; + Solution replaceBlankInString = new Solution(); + System.out.println(replaceBlankInString.replaceSpace(string)); + System.out.println(replaceBlankInString.replaceSpace(string1)); + System.out.println(replaceBlankInString.replaceSpace(string2)); + System.out.println(replaceBlankInString.replaceSpace(string3)); + System.out.println(replaceBlankInString.replaceSpace(string4)); + } +} diff --git a/src/main/java/ds/pointer/targetoffer22/Solution.java b/src/main/java/ds/pointer/targetoffer22/Solution.java index 5c933df..221e4c9 100644 --- a/src/main/java/ds/pointer/targetoffer22/Solution.java +++ b/src/main/java/ds/pointer/targetoffer22/Solution.java @@ -4,7 +4,7 @@ * 链表中倒数第k个节点 * LeetCode 剑指offer 22 https://leetcode-cn.com/problems/lian-biao-zhong-dao-shu-di-kge-jie-dian-lcof/ * - * @author yangyi 2020年12月11日00:26:01 + * @author yangyi 2022年04月24日17:50:02 */ public class Solution { @@ -36,10 +36,14 @@ private ListNode createLink() { public ListNode getKthFromEnd(ListNode head, int k) { ListNode fast = head; ListNode slow = head; - while (k--> 0) {
+ while (k != 0) {
fast = fast.next;
+ k--;
}
- while (fast != null) {
+ while (true) {
+ if (fast == null) {
+ break;
+ }
fast = fast.next;
slow = slow.next;
}
diff --git a/src/main/java/ds/pointer/targetofferII014/Solution.java b/src/main/java/ds/pointer/targetofferII014/Solution.java
new file mode 100644
index 0000000..c09c411
--- /dev/null
+++ b/src/main/java/ds/pointer/targetofferII014/Solution.java
@@ -0,0 +1,56 @@
+package ds.pointer.targetofferII014;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * 字符串中的变位词
+ * 剑指 Offer II 014 https://leetcode-cn.com/problems/MPnaiL/
+ *
+ * @author yangyi 2022年02月25日17:53:03
+ */
+public class Solution {
+
+ public boolean checkInclusion(String s1, String s2) {
+ if (s2.length() < s1.length()) { + return false; + } + Map charToNums = new HashMap();
+ for (int i = 0; i < s1.length(); i++) { + charToNums.put(s1.charAt(i), charToNums.getOrDefault(s1.charAt(i), 0) + 1); + charToNums.put(s2.charAt(i), charToNums.getOrDefault(s2.charAt(i), 0) - 1); + } + if (allZero(charToNums)) { + return true; + } + //第2个for循环中的下标i相当于第2个指针,指向子字符串的最后一个字符。第1个指针指向下标为i-s1.length()的位置。 + // 两个指针之间的子字符串的长度一直是字符串s1的长度 + for (int i = s1.length(); i < s2.length(); i++) { + if (charToNums.containsKey(s2.charAt(i))) { + charToNums.put(s2.charAt(i), charToNums.getOrDefault(s2.charAt(i), 0) - 1); + } + if (charToNums.containsKey(s2.charAt(i - s1.length()))) { + charToNums.put(s2.charAt(i - s1.length()), charToNums.getOrDefault(s2.charAt(i - s1.length()), 0) + 1); + } + if (allZero(charToNums)) { + return true; + } + } + return false; + } + + private boolean allZero(Map charToNums) {
+ for (Map.Entry kv : charToNums.entrySet()) {
+ if (kv.getValue() != 0) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ public static void main(String[] args) {
+ System.out.println(new Solution().checkInclusion("ab", "eidbaooo"));
+ System.out.println(new Solution().checkInclusion("ab", "eidboaoo"));
+ System.out.println(new Solution().checkInclusion("ab", "a"));
+ }
+}
diff --git a/src/main/java/ds/pointer/targetofferII015/Solution.java b/src/main/java/ds/pointer/targetofferII015/Solution.java
new file mode 100644
index 0000000..0d1acb4
--- /dev/null
+++ b/src/main/java/ds/pointer/targetofferII015/Solution.java
@@ -0,0 +1,53 @@
+package ds.pointer.targetofferII015;
+
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 字符串中的所有变位词
+ * 剑指 Offer II 015 https://leetcode-cn.com/problems/VabMRr/
+ *
+ * @author yangyi 2022年02月25日19:06:17
+ */
+public class Solution {
+
+ public List findAnagrams(String s, String p) {
+ if (s.length() < p.length()) { + return new LinkedList();
+ }
+ List result = new LinkedList();
+ Map charToNums = new HashMap();
+ for (int i = 0; i < p.length(); i++) { + charToNums.put(p.charAt(i), charToNums.getOrDefault(p.charAt(i), 0) + 1); + charToNums.put(s.charAt(i), charToNums.getOrDefault(s.charAt(i), 0) - 1); + } + if (allZero(charToNums)) { + result.add(0); + } + for (int i = p.length(); i < s.length(); i++) { + charToNums.put(s.charAt(i), charToNums.getOrDefault(s.charAt(i), 0) - 1); + charToNums.put(s.charAt(i - p.length()), charToNums.getOrDefault(s.charAt(i - p.length()), 0) + 1); + if (allZero(charToNums)) { + result.add(i - p.length() + 1); + } + } + return result; + } + + private boolean allZero(Map charToNums) {
+ for (Map.Entry characterIntegerEntry : charToNums.entrySet()) {
+ if (characterIntegerEntry.getValue() != 0) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ public static void main(String[] args) {
+ System.out.println(Arrays.toString(new Solution().findAnagrams("cbaebabacd", "abc").toArray()));
+ System.out.println(Arrays.toString(new Solution().findAnagrams("abab", "ab").toArray()));
+ }
+}
diff --git a/src/main/java/ds/queue/leetcode225/MyStack.java b/src/main/java/ds/queue/leetcode225/MyStack.java
new file mode 100644
index 0000000..f310afd
--- /dev/null
+++ b/src/main/java/ds/queue/leetcode225/MyStack.java
@@ -0,0 +1,66 @@
+package ds.queue.leetcode225;
+
+import java.util.ArrayDeque;
+import java.util.Deque;
+
+/**
+ * 用队列实现栈
+ * LeetCode 225 https://leetcode-cn.com/problems/implement-stack-using-queues/
+ *
+ * @author yangyi 2021年07月09日18:32:47
+ */
+public class MyStack {
+
+ private Deque deque;
+
+ /**
+ * Initialize your data structure here.
+ */
+ public MyStack() {
+ deque = new ArrayDeque();
+ }
+
+ /**
+ * Push element x onto stack.
+ */
+ public void push(int x) {
+ deque.offer(x);
+ }
+
+ /**
+ * Removes the element on top of the stack and returns that element.
+ */
+ public int pop() {
+ for (int i = 0; i < deque.size() - 1; i++) { + int first = deque.pollFirst(); + deque.offerLast(first); + } + return deque.pollFirst(); + } + + /** + * Get the top element. + */ + public int top() { + return deque.peekLast(); + } + + /** + * Returns whether the stack is empty. + */ + public boolean empty() { + return deque.isEmpty(); + } + + public static void main(String[] args) { + MyStack myStack = new MyStack(); + myStack.push(1); + myStack.push(2); + // 返回 2 + System.out.println(myStack.top()); + // 返回 2 + System.out.println(myStack.pop()); + // 返回 False + System.out.println(myStack.empty()); + } +} diff --git a/src/main/java/ds/reverse/InvertTree.java b/src/main/java/ds/reverse/leetcode226/Solution.java similarity index 62% rename from src/main/java/ds/reverse/InvertTree.java rename to src/main/java/ds/reverse/leetcode226/Solution.java index 6267d11..0df8d32 100644 --- a/src/main/java/ds/reverse/InvertTree.java +++ b/src/main/java/ds/reverse/leetcode226/Solution.java @@ -1,31 +1,16 @@ -package ds.reverse; +package ds.reverse.leetcode226; import java.util.ArrayDeque; import java.util.Queue; +import java.util.Stack; /** - * 反转一颗二叉树 - *
- * 示例:
- *
- * 输入:
- *
- * 4
- * / \
- * 2 7
- * / \ / \
- * 1 3 6 9
- * 输出:
- *
- * 4
- * / \
- * 7 2
- * / \ / \
- * 9 6 3 1
+ * 翻转二叉树
+ * LeetCode 226 https://leetcode-cn.com/problems/invert-binary-tree/
*
* @author yangyi 2019年02月10日16:57:38
*/
-public class InvertTree {
+public class Solution {
public static class TreeNode {
int val;
@@ -37,6 +22,9 @@ public static class TreeNode {
}
}
+ /**
+ * 递归方式遍历反转
+ */
public TreeNode invertTree(TreeNode root) {
if (root == null) {
return null;
@@ -51,12 +39,15 @@ public TreeNode invertTree(TreeNode root) {
return root;
}
- public TreeNode invertTreeByQueue(TreeNode tree) {
- if (tree == null) {
+ /**
+ * 层序遍历方式反转
+ */
+ public TreeNode invertTreeByQueue(TreeNode root) {
+ if (root == null) {
return null;
}
Queue
queue = new ArrayDeque
();
- queue.offer(tree);
+ queue.offer(root);
while (!queue.isEmpty()) {
TreeNode node = queue.poll();
TreeNode temp = node.left;
@@ -69,7 +60,34 @@ public TreeNode invertTreeByQueue(TreeNode tree) {
queue.offer(node.right);
}
}
- return tree;
+ return root;
+ }
+
+ /**
+ * 深度优先遍历的方式反转
+ */
+ private TreeNode invertTreeByStack(TreeNode root) {
+ if (root == null) {
+ return null;
+ }
+ Stack stack = new Stack
();
+ stack.push(root);
+ while (!stack.isEmpty()) {
+ int size = stack.size();
+ for (int i = 0; i < size; i++) { + TreeNode cur = stack.pop(); + TreeNode temp = cur.left; + cur.left = cur.right; + cur.right = temp; + if (cur.right != null) { + stack.push(cur.right); + } + if (cur.left != null) { + stack.push(cur.left); + } + } + } + return root; } public TreeNode createTree() { @@ -99,7 +117,7 @@ public void inOrder(TreeNode node) { } public static void main(String[] args) { - InvertTree invertTree = new InvertTree(); + Solution invertTree = new Solution(); TreeNode node = invertTree.createTree(); System.out.println("先中序遍历打印一遍反转前的结果:"); invertTree.inOrder(node); @@ -111,6 +129,10 @@ public static void main(String[] args) { System.out.println("再中序遍历打印一遍反转后的结果:"); TreeNode newNode2 = invertTree.invertTreeByQueue(node); invertTree.inOrder(newNode2); + System.out.println(); + System.out.println("再中序遍历打印一遍反转后的结果:"); + TreeNode newNode3= invertTree.invertTreeByStack(node); + invertTree.inOrder(newNode3); } } diff --git a/src/main/java/ds/reverse/ReverseString.java b/src/main/java/ds/reverse/leetcode344/Solution.java similarity index 56% rename from src/main/java/ds/reverse/ReverseString.java rename to src/main/java/ds/reverse/leetcode344/Solution.java index 36400ab..9ca8236 100644 --- a/src/main/java/ds/reverse/ReverseString.java +++ b/src/main/java/ds/reverse/leetcode344/Solution.java @@ -1,30 +1,14 @@ -package ds.reverse; +package ds.reverse.leetcode344; import java.util.Arrays; /** * 反转字符串 - *
- * 编写一个函数,其作用是将输入的字符串反转过来。输入字符串以字符数组 char[] 的形式给出。
- *
- * 不要给另外的数组分配额外的空间,你必须原地修改输入数组、使用 O(1) 的额外空间解决这一问题。
- *
- * 你可以假设数组中的所有字符都是 ASCII 码表中的可打印字符。
- *
- *
- *
- * 示例 1:
- *
- * 输入:['h','e','l','l','o']
- * 输出:['o','l','l','e','h']
- * 示例 2:
- *
- * 输入:['H','a','n','n','a','h']
- * 输出:['h','a','n','n','a','H']
+ * LeetCode 344 https://leetcode-cn.com/problems/reverse-string/
*
* @author yangyi 2019年02月10日22:12:46
*/
-public class ReverseString {
+public class Solution {
private char[] a;
private char[] b;
@@ -43,7 +27,7 @@ public void reverseString(char[] s) {
}
public static void main(String[] args) {
- ReverseString reverseString = new ReverseString();
+ Solution reverseString = new Solution();
reverseString.a = new char[]{'h', 'e', 'l', 'l', 'o'};
reverseString.b = new char[]{'H', 'a', 'n', 'n', 'a', 'h'};
reverseString.reverseString(reverseString.a);
diff --git a/src/main/java/ds/reverse/leetcode541/Solution.java b/src/main/java/ds/reverse/leetcode541/Solution.java
new file mode 100644
index 0000000..e94c7e6
--- /dev/null
+++ b/src/main/java/ds/reverse/leetcode541/Solution.java
@@ -0,0 +1,41 @@
+package ds.reverse.leetcode541;
+
+/**
+ * 反转字符串II
+ * LeetCode 541 https://leetcode-cn.com/problems/reverse-string-ii/
+ *
+ * @author yangyi 2021年01月19日16:01:41
+ */
+public class Solution {
+
+ public String reverseStr(String s, int k) {
+ char[] chars = s.toCharArray();
+ for (int i = 0; i < chars.length; i += (2 * k)) { + if (i + k < chars.length) { + reverseString(chars, i, i + k - 1); + continue; + } + reverseString(chars, i, chars.length - 1); + } + return new String(chars); + } + + public char[] reverseString(char[] s, int start, int end) { + if (s == null) { + return new char[]{}; + } + while (start < end) { + char temp = s[start]; + s[start] = s[end]; + s[end] = temp; + start++; + end--; + } + return s; + } + + public static void main(String[] args) { + System.out.println(new Solution().reverseStr("abcdefg", 2)); + System.out.println(new Solution().reverseString("abcdefg".toCharArray(), 0, "abcdefg".length() - 1)); + } +} diff --git a/src/main/java/ds/reverse/ReverseWordsIII.java b/src/main/java/ds/reverse/leetcode557/Solution.java similarity index 65% rename from src/main/java/ds/reverse/ReverseWordsIII.java rename to src/main/java/ds/reverse/leetcode557/Solution.java index 58136ee..592f70f 100644 --- a/src/main/java/ds/reverse/ReverseWordsIII.java +++ b/src/main/java/ds/reverse/leetcode557/Solution.java @@ -1,19 +1,12 @@ -package ds.reverse; +package ds.reverse.leetcode557; /** * 反转字符串中的单词 III - *
- * 给定一个字符串,你需要反转字符串中每个单词的字符顺序,同时仍保留空格和单词的初始顺序。
- *
- * 示例 1:
- *
- * 输入: "Let's take LeetCode contest"
- * 输出: "s'teL ekat edoCteeL tsetnoc"
- * 注意:在字符串中,每个单词由单个空格分隔,并且字符串中不会有任何额外的空格。
+ * LeetCode 557 https://leetcode-cn.com/problems/reverse-words-in-a-string-iii/
*
- * @author yangyi 2019年02月10日23:15:01
+ * @author yangyi 2021年03月02日23:40:21
*/
-public class ReverseWordsIII {
+public class Solution {
public String reverseWords(String s) {
String[] strings = s.split(" ");
@@ -41,7 +34,7 @@ public char[] reverse(char[] chars) {
public static void main(String[] args) {
String s = "Let's take LeetCode contest";
- ReverseWordsIII reverseWordsIII = new ReverseWordsIII();
+ Solution reverseWordsIII = new Solution();
String result = reverseWordsIII.reverseWords(s);
System.out.println(result);
}
diff --git a/src/main/java/ds/reverse/Transpose.java b/src/main/java/ds/reverse/leetcode867/Solution.java
similarity index 77%
rename from src/main/java/ds/reverse/Transpose.java
rename to src/main/java/ds/reverse/leetcode867/Solution.java
index f073744..ceace0e 100644
--- a/src/main/java/ds/reverse/Transpose.java
+++ b/src/main/java/ds/reverse/leetcode867/Solution.java
@@ -1,13 +1,14 @@
-package ds.reverse;
+package ds.reverse.leetcode867;
import java.util.Arrays;
/**
* 转置矩阵
+ * LeetCode 867 https://leetcode-cn.com/problems/transpose-matrix/
*
- * @author yangyi 2019年02月16日23:27:58
+ * @author yangyi 2021年03月02日23:44:44
*/
-public class Transpose {
+public class Solution {
public int[][] transpose(int[][] A) {
if (A == null || A.length == 0 || A[0].length == 0) {
@@ -25,7 +26,7 @@ public int[][] transpose(int[][] A) {
public static void main(String[] args) {
int[][] a = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}};
int[][] b = {{1, 2, 3}, {4, 5, 6}};
- Transpose transpose = new Transpose();
+ Solution transpose = new Solution();
System.out.println(Arrays.deepToString(transpose.transpose(a)));
System.out.println(Arrays.deepToString(transpose.transpose(b)));
}
diff --git a/src/main/java/ds/MaxSlidingWindow.java b/src/main/java/ds/sliding/leetcode239/Solution.java
similarity index 68%
rename from src/main/java/ds/MaxSlidingWindow.java
rename to src/main/java/ds/sliding/leetcode239/Solution.java
index 66de540..9ce2b8e 100644
--- a/src/main/java/ds/MaxSlidingWindow.java
+++ b/src/main/java/ds/sliding/leetcode239/Solution.java
@@ -1,29 +1,15 @@
-package ds;
+package ds.sliding.leetcode239;
import java.util.ArrayDeque;
import java.util.Deque;
/**
- * 在一个固定大小的滚动窗口(此处的滚动窗口可以理解为屏幕)中,输出每次滚动时屏幕当中的最大值。
- *
- * 示例:
- *
- * 输入: nums = [1,3,-1,-3,5,3,6,7], 和 k = 3
- * 输出: [3,3,5,5,6,7]
- * 解释:
- *
- * 滑动窗口的位置 最大值
- * --------------- -----
- * [1 3 -1] -3 5 3 6 7 3
- * 1 [3 -1 -3] 5 3 6 7 3
- * 1 3 [-1 -3 5] 3 6 7 5
- * 1 3 -1 [-3 5 3] 6 7 5
- * 1 3 -1 -3 [5 3 6] 7 6
- * 1 3 -1 -3 5 [3 6 7] 7
- *
- * Created by yangyi on 2019年1月24日.
+ * 滑动窗口最大值
+ * LeetCode 239 https://leetcode-cn.com/problems/sliding-window-maximum/
+ *
+ * @author yangyi 2021年07月12日15:08:28
*/
-public class MaxSlidingWindow {
+public class Solution {
//关键1: 窗口中保存的元素的下标,window只有k大,i-k就代表着window的左边界
private Deque windows = new ArrayDeque();
@@ -58,8 +44,8 @@ public int[] maxSlidingWindow(int[] nums, int k) {
public static void main(String[] args) {
int[] arrays = new int[]{1, 3, -1, -3, 5, 3, 6, 7};
- MaxSlidingWindow maxSlidingWindow = new MaxSlidingWindow();
- int[] result = maxSlidingWindow.maxSlidingWindow(arrays, 3);
+ Solution solution = new Solution();
+ int[] result = solution.maxSlidingWindow(arrays, 3);
for (int i : result) {
System.out.println(i);
}
diff --git a/src/main/java/ds/BigHeap.java b/src/main/java/ds/sort/BigHeapSort.java
similarity index 96%
rename from src/main/java/ds/BigHeap.java
rename to src/main/java/ds/sort/BigHeapSort.java
index 956dedc..5123796 100644
--- a/src/main/java/ds/BigHeap.java
+++ b/src/main/java/ds/sort/BigHeapSort.java
@@ -1,18 +1,18 @@
-package ds;
+package ds.sort;
/**
* 堆(大顶堆)
*
* @author yangyi 2019年01月22日18:05:48
*/
-public class BigHeap {
+public class BigHeapSort {
//堆因为是个完全二叉树,用数组来进行表示
private int[] heapArray;
private int capacity;
private int count;
- public BigHeap(int capacity) {
+ public BigHeapSort(int capacity) {
this.capacity = capacity;
heapArray = new int[capacity + 1];
count = 0;
@@ -120,7 +120,7 @@ public static void main(String[] args) {
ints[i] = (int) (Math.random() * 10);
}
- BigHeap bigHeap = new BigHeap(capacity);
+ BigHeapSort bigHeap = new BigHeapSort(capacity);
System.out.println("遍历一下构造好的数组:");
for (int anInt : ints) {
System.out.println(anInt);
diff --git a/src/main/java/ds/BubbleSort.java b/src/main/java/ds/sort/BubbleSort.java
similarity index 98%
rename from src/main/java/ds/BubbleSort.java
rename to src/main/java/ds/sort/BubbleSort.java
index 2727f49..04c058f 100644
--- a/src/main/java/ds/BubbleSort.java
+++ b/src/main/java/ds/sort/BubbleSort.java
@@ -1,4 +1,4 @@
-package ds;
+package ds.sort;
/**
* 冒泡排序
diff --git a/src/main/java/ds/CountSort.java b/src/main/java/ds/sort/CountSort.java
similarity index 98%
rename from src/main/java/ds/CountSort.java
rename to src/main/java/ds/sort/CountSort.java
index f60b0b2..e404338 100644
--- a/src/main/java/ds/CountSort.java
+++ b/src/main/java/ds/sort/CountSort.java
@@ -1,4 +1,4 @@
-package ds;
+package ds.sort;
/**
* 计数排序
diff --git a/src/main/java/ds/InsertSort.java b/src/main/java/ds/sort/InsertSort.java
similarity index 99%
rename from src/main/java/ds/InsertSort.java
rename to src/main/java/ds/sort/InsertSort.java
index 52e6320..78e1248 100644
--- a/src/main/java/ds/InsertSort.java
+++ b/src/main/java/ds/sort/InsertSort.java
@@ -1,4 +1,4 @@
-package ds;
+package ds.sort;
/**
* 插入排序
diff --git a/src/main/java/ds/QuickSort.java b/src/main/java/ds/sort/QuickSort.java
similarity index 99%
rename from src/main/java/ds/QuickSort.java
rename to src/main/java/ds/sort/QuickSort.java
index a0a652e..c755995 100644
--- a/src/main/java/ds/QuickSort.java
+++ b/src/main/java/ds/sort/QuickSort.java
@@ -1,4 +1,4 @@
-package ds;
+package ds.sort;
/**
* 快速排序
diff --git a/src/main/java/ds/SelectionSort.java b/src/main/java/ds/sort/SelectionSort.java
similarity index 98%
rename from src/main/java/ds/SelectionSort.java
rename to src/main/java/ds/sort/SelectionSort.java
index eff38ea..0307081 100644
--- a/src/main/java/ds/SelectionSort.java
+++ b/src/main/java/ds/sort/SelectionSort.java
@@ -1,4 +1,4 @@
-package ds;
+package ds.sort;
/**
* 选择排序
diff --git a/src/main/java/ds/stack/leetcode1047/Solution.java b/src/main/java/ds/stack/leetcode1047/Solution.java
new file mode 100644
index 0000000..21ea1b3
--- /dev/null
+++ b/src/main/java/ds/stack/leetcode1047/Solution.java
@@ -0,0 +1,32 @@
+package ds.stack.leetcode1047;
+
+import java.util.Stack;
+
+/**
+ * 删除字符串中的所有相邻重复项
+ * LeetCode 1047 https://leetcode-cn.com/problems/remove-all-adjacent-duplicates-in-string/
+ *
+ * @author yangyi 2021年07月12日11:57:00
+ */
+public class Solution {
+
+ public String removeDuplicates(String s) {
+ Stack stack = new Stack();
+ StringBuilder result = new StringBuilder();
+ for (int i = 0; i < s.length(); i++) { + if (stack.isEmpty() || stack.peek() != s.charAt(i)) { + stack.push(s.charAt(i)); + } else { + stack.pop(); + } + } + while (!stack.isEmpty()) { + result.append(stack.pop()); + } + return result.reverse().toString(); + } + + public static void main(String[] args) { + System.out.println(new Solution().removeDuplicates("abbaca")); + } +} diff --git a/src/main/java/ds/stack/leetcode150/Solution.java b/src/main/java/ds/stack/leetcode150/Solution.java new file mode 100644 index 0000000..b57058c --- /dev/null +++ b/src/main/java/ds/stack/leetcode150/Solution.java @@ -0,0 +1,44 @@ +package ds.stack.leetcode150; + +import java.util.Stack; + +/** + * 逆波兰表达式求值 + * LeetCode 150 https://leetcode-cn.com/problems/evaluate-reverse-polish-notation/ + * + * @author yangyi 2021年07月12日14:19:21 + */ +public class Solution { + + public int evalRPN(String[] tokens) { + Stack stack = new Stack();
+ for (int i = 0; i < tokens.length; i++) { + if ("+".equals(tokens[i]) || "-".equals(tokens[i]) || "*".equals(tokens[i]) || "/".equals(tokens[i])) { + String num1 = stack.pop(); + String num2 = stack.pop(); + if ("+".equals(tokens[i])) { + int result = Integer.parseInt(num2) + Integer.parseInt(num1); + stack.push(String.valueOf(result)); + } else if ("-".equals(tokens[i])) { + int result = Integer.parseInt(num2) - Integer.parseInt(num1); + stack.push(String.valueOf(result)); + } else if ("*".equals(tokens[i])) { + int result = Integer.parseInt(num2) * Integer.parseInt(num1); + stack.push(String.valueOf(result)); + } else if ("/".equals(tokens[i])) { + int result = Integer.parseInt(num2) / Integer.parseInt(num1); + stack.push(String.valueOf(result)); + } + } else { + stack.push(tokens[i]); + } + } + return Integer.parseInt(stack.pop()); + } + + public static void main(String[] args) { + System.out.println(new Solution().evalRPN(new String[]{"2", "1", "+", "3", "*"})); + System.out.println(new Solution().evalRPN(new String[]{"4", "13", "5", "/", "+"})); + System.out.println(new Solution().evalRPN(new String[]{"10", "6", "9", "3", "+", "-11", "*", "/", "*", "17", "+", "5", "+"})); + } +} diff --git a/src/main/java/ds/stack/leetcode20/Solution.java b/src/main/java/ds/stack/leetcode20/Solution.java new file mode 100644 index 0000000..f2df444 --- /dev/null +++ b/src/main/java/ds/stack/leetcode20/Solution.java @@ -0,0 +1,47 @@ +package ds.stack.leetcode20; + +import java.util.Stack; + +/** + * 有效的括号 + * LeetCode 20 https://leetcode-cn.com/problems/valid-parentheses/ + * + * @author yangyi 2021年07月09日19:20:06 + */ +public class Solution { + + public boolean isValid(String s) { + Stack stack = new Stack();
+ for (int i = 0; i < s.length(); i++) { + if (s.charAt(i) == '(') { + stack.push(")"); + } else if (s.charAt(i) == ('{')) { + stack.push("}"); + } else if (s.charAt(i) == ('[')) { + stack.push("]"); + } else if (stack.isEmpty()) { + return false; + } else if (!stack.peek().equals(String.valueOf(s.charAt(i)))) { + return false; + } else { + stack.pop(); + } + } + return stack.isEmpty(); + } + + public static void main(String[] args) { + String one = "()"; + String two = "()[]"; + String three = "([)]"; + String four = "(((([]))"; + String five = "]][["; + + Solution solution = new Solution(); + System.out.println(one + (solution.isValid(one) ? "有效" : "无效")); + System.out.println(two + (solution.isValid(two) ? "有效" : "无效")); + System.out.println(three + (solution.isValid(three) ? "有效" : "无效")); + System.out.println(four + (solution.isValid(four) ? "有效" : "无效")); + System.out.println(five + (solution.isValid(five) ? "有效" : "无效")); + } +} diff --git a/src/main/java/ds/stack/leetcode232/MyQueue.java b/src/main/java/ds/stack/leetcode232/MyQueue.java new file mode 100644 index 0000000..2681aa5 --- /dev/null +++ b/src/main/java/ds/stack/leetcode232/MyQueue.java @@ -0,0 +1,81 @@ +package ds.stack.leetcode232; + +import java.util.Stack; + +/** + * 用栈实现队列 + * LeetCode 232 https://leetcode-cn.com/problems/implement-queue-using-stacks/ + * + * @author yangyi 2021年07月09日17:53:18 + */ +public class MyQueue { + + private Stack input;
+ private Stack output;
+
+ /**
+ * Initialize your data structure here.
+ */
+ public MyQueue() {
+ input = new Stack();
+ output = new Stack();
+ }
+
+ /**
+ * Push element x to the back of queue.
+ */
+ public void push(int x) {
+ input.push(x);
+ }
+
+ /**
+ * Removes the element from in front of queue and returns that element.
+ */
+ public int pop() {
+ if (output.isEmpty()) {
+ while (!input.isEmpty()) {
+ int cur = input.pop();
+ output.push(cur);
+ }
+ }
+ return output.pop();
+ }
+
+ /**
+ * Get the front element.
+ */
+ public int peek() {
+ int res = pop();
+ output.push(res);
+ return res;
+ }
+
+ /**
+ * Returns whether the queue is empty.
+ */
+ public boolean empty() {
+ return input.isEmpty() && output.isEmpty();
+ }
+
+ /**
+ * Your MyQueue object will be instantiated and called as such:
+ * MyQueue obj = new MyQueue();
+ * obj.push(x);
+ * int param_2 = obj.pop();
+ * int param_3 = obj.peek();
+ * boolean param_4 = obj.empty();
+ */
+
+ public static void main(String[] args) {
+ MyQueue myQueue = new MyQueue();
+ myQueue.push(1); // queue is: [1]
+ myQueue.push(2); // queue is: [1, 2] (leftmost is front of the queue)
+ //return 1
+ System.out.println(myQueue.peek());
+ //return 1, queue is [2]
+ System.out.println(myQueue.pop());
+ //return false
+ System.out.println(myQueue.empty());
+ }
+
+}
diff --git a/src/main/java/ds/stack/leetcode739/Solution.java b/src/main/java/ds/stack/leetcode739/Solution.java
new file mode 100644
index 0000000..8cd695e
--- /dev/null
+++ b/src/main/java/ds/stack/leetcode739/Solution.java
@@ -0,0 +1,39 @@
+package ds.stack.leetcode739;
+
+import java.util.Arrays;
+import java.util.Stack;
+
+/**
+ * 每日温度
+ * LeetCode 739 https://leetcode-cn.com/problems/daily-temperatures/
+ *
+ * @author yangyi 2021年07月09日15:50:24
+ */
+public class Solution {
+
+ public int[] dailyTemperatures(int[] temperatures) {
+ int[] result = new int[temperatures.length];
+ Stack stack = new Stack();
+ stack.push(0);
+ for (int i = 1; i < temperatures.length; i++) { + if (temperatures[i] < temperatures[stack.peek()]) { + stack.push(i); + } else if (temperatures[i] == temperatures[stack.peek()]) { + stack.push(i); + } else { + while (!stack.isEmpty() && temperatures[i]> temperatures[stack.peek()]) {
+ int top = stack.peek();
+ result[top] = i - top;
+ stack.pop();
+ }
+ stack.push(i);
+ }
+ }
+ return result;
+ }
+
+ public static void main(String[] args) {
+ int[] tem = new int[]{73, 74, 75, 71, 69, 72, 76, 73};
+ System.out.println(Arrays.toString(new Solution().dailyTemperatures(tem)));
+ }
+}
diff --git a/src/main/java/ds/string/ReplaceBlankInString.java b/src/main/java/ds/string/ReplaceBlankInString.java
deleted file mode 100644
index 80a4bef..0000000
--- a/src/main/java/ds/string/ReplaceBlankInString.java
+++ /dev/null
@@ -1,71 +0,0 @@
-package ds.string;
-
-/**
- * 替换字符串中的空格
- *
- * 目标: 将字符串中的字符替换为%20
- *
- * @author yangyi 2019年02月09日09:51:12
- */
-public class ReplaceBlankInString {
-
- public char[] replaceBlankInString(char[] chars) {
- if (chars == null || chars.length <= 0) { - return new char[0]; - } - - //字符串实际长度 - int originalLength = 0; - //空格的个数 - int numberOfBlank = 0; - int i = 0; - //先统计出来源字符串有多长,以及其中包含多少个空格 - while (i < chars.length) { - originalLength++; - if (chars[i] == ' ') { - numberOfBlank++; - } - i++; - } - //统计出来之后开辟一个新数组的长度 - int newLength = originalLength + numberOfBlank * 2; - if (newLength < chars.length) { - return new char[0]; - } - - //开辟一个新的长度的数组用来进行原始数据的移动 - char[] newChar = new char[newLength]; - for (int i1 = 0; i1 < chars.length; i1++) { - newChar[i1] = chars[i1]; - } - - int indexOfOriginal = originalLength - 1; - int indexOfNew = newLength - 1; - //从尾到头替换 - while (indexOfOriginal>= 0 && indexOfNew> indexOfOriginal) {
- if (newChar[indexOfOriginal] == ' ') {
- newChar[indexOfNew--] = '0';
- newChar[indexOfNew--] = '2';
- newChar[indexOfNew--] = '%';
- } else {
- newChar[indexOfNew--] = chars[indexOfOriginal];
- }
- indexOfOriginal--;
- }
- return newChar;
- }
-
- public static void main(String[] args) {
- String string = "we are Chinese";
- String string1 = " ";
- String string2 = "";
- String string3 = " ";
- String string4 = " we are Chinese ";
- ReplaceBlankInString replaceBlankInString = new ReplaceBlankInString();
- System.out.println(replaceBlankInString.replaceBlankInString(string.toCharArray()));
- System.out.println(replaceBlankInString.replaceBlankInString(string1.toCharArray()));
- System.out.println(replaceBlankInString.replaceBlankInString(string2.toCharArray()));
- System.out.println(replaceBlankInString.replaceBlankInString(string3.toCharArray()));
- System.out.println(replaceBlankInString.replaceBlankInString(string4.toCharArray()));
- }
-}
diff --git a/src/main/java/ds/tree/TreeNodeCount.java b/src/main/java/ds/tree/TreeNodeCount.java
deleted file mode 100644
index a7c83ee..0000000
--- a/src/main/java/ds/tree/TreeNodeCount.java
+++ /dev/null
@@ -1,51 +0,0 @@
-package ds.tree;
-
-/**
- * 二叉树的节点个数
- *
- * @author yangyi 2020年11月25日10:28:19
- */
-public class TreeNodeCount {
-
- /**
- * 4
- * / \
- * 2 7
- * / \ / \
- * 1 3 6 9
- */
- private SameTree.TreeNode createTree() {
- SameTree.TreeNode root = new SameTree.TreeNode(4);
- SameTree.TreeNode node_2 = new SameTree.TreeNode(2);
- SameTree.TreeNode node_7 = new SameTree.TreeNode(7);
- SameTree.TreeNode node_1 = new SameTree.TreeNode(1);
- SameTree.TreeNode node_3 = new SameTree.TreeNode(3);
- SameTree.TreeNode node_6 = new SameTree.TreeNode(6);
- SameTree.TreeNode node_9 = new SameTree.TreeNode(9);
- root.left = node_2;
- root.right = node_7;
- node_2.left = node_1;
- node_2.right = node_3;
- node_7.left = node_6;
- node_7.right = node_9;
- return root;
- }
-
- /**
- * 统计二叉树的节点个数
- */
- private int countTree(SameTree.TreeNode root) {
- if (root == null) {
- return 0;
- }
- return 1 + countTree(root.left) + countTree(root.right);
- }
-
- public static void main(String[] args) {
- TreeNodeCount treeNodeCount = new TreeNodeCount();
- SameTree.TreeNode root = treeNodeCount.createTree();
- int count = treeNodeCount.countTree(root);
- System.out.println("此二叉树的节点个数为: " + count);
- }
-
-}
diff --git a/src/main/java/ds/tree/SameTree.java b/src/main/java/ds/tree/leetcode100/Solution.java
similarity index 54%
rename from src/main/java/ds/tree/SameTree.java
rename to src/main/java/ds/tree/leetcode100/Solution.java
index c4d6ff5..8aa2631 100644
--- a/src/main/java/ds/tree/SameTree.java
+++ b/src/main/java/ds/tree/leetcode100/Solution.java
@@ -1,63 +1,45 @@
-package ds.tree;
+package ds.tree.leetcode100;
/**
* 相同的树
- *
- * 给定两个二叉树,编写一个函数来检验它们是否相同。
- *
- * 如果两个树在结构上相同,并且节点具有相同的值,则认为它们是相同的。
- *
- * 示例 1:
- *
- * 输入: 1 1
- * / \ / \
- * 2 3 2 3
- *
- * [1,2,3], [1,2,3]
- *
- * 输出: true
- * 示例 2:
- *
- * 输入: 1 1
- * / \
- * 2 2
- *
- * [1,2], [1,null,2]
- *
- * 输出: false
- * 示例 3:
- *
- * 输入: 1 1
- * / \ / \
- * 2 1 1 2
- *
- * [1,2,1], [1,1,2]
- *
- * 输出: false
- *
+ * LeetCode 100 https://leetcode-cn.com/problems/same-tree/
*
- * @author yangyi 2019年02月10日21:26:34
+ * @author yangyi 2021年01月31日23:02:44
*/
-public class SameTree {
+public class Solution {
- public static class TreeNode {
- public int val;
- public TreeNode left;
- public TreeNode right;
+ public class TreeNode {
+ int val;
+ TreeNode left;
+ TreeNode right;
- public TreeNode(int x) {
- val = x;
+ TreeNode() {
+ }
+
+ TreeNode(int val) {
+ this.val = val;
+ }
+
+ TreeNode(int val, TreeNode left, TreeNode right) {
+ this.val = val;
+ this.left = left;
+ this.right = right;
}
}
public boolean isSameTree(TreeNode p, TreeNode q) {
if (p == null && q == null) {
return true;
+ } else if (p == null && q != null) {
+ return false;
+ } else if (p != null && q == null) {
+ return false;
+ } else if (p.val != q.val) {
+ return false;
}
- if (p != null && q != null && p.val == q.val) {
- return isSameTree(p.left, q.left) && isSameTree(p.right, q.right);
- }
- return false;
+ boolean leftSame = isSameTree(p.left, q.left);
+ boolean rightSame = isSameTree(p.right, q.right);
+ return leftSame && rightSame;
}
public TreeNode[] createTreeNode() {
@@ -88,9 +70,10 @@ public TreeNode[] createTreeNode() {
}
public static void main(String[] args) {
- SameTree sameTree = new SameTree();
+ Solution sameTree = new Solution();
TreeNode[] treeNodes = sameTree.createTreeNode();
System.out.println("两个树是否相同:" + sameTree.isSameTree(treeNodes[0], treeNodes[1]));
System.out.println("两个树是否相同:" + sameTree.isSameTree(treeNodes[0], treeNodes[2]));
}
+
}
diff --git a/src/main/java/ds/tree/SymmetricTree.java b/src/main/java/ds/tree/leetcode101/Solution.java
similarity index 50%
rename from src/main/java/ds/tree/SymmetricTree.java
rename to src/main/java/ds/tree/leetcode101/Solution.java
index 216ed0d..f905cb7 100644
--- a/src/main/java/ds/tree/SymmetricTree.java
+++ b/src/main/java/ds/tree/leetcode101/Solution.java
@@ -1,11 +1,13 @@
-package ds.tree;
+package ds.tree.leetcode101;
/**
* 对称二叉树
+ * LeetCode 101 https://leetcode-cn.com/problems/symmetric-tree/
+ * 剑指 Offer 28 https://leetcode-cn.com/problems/dui-cheng-de-er-cha-shu-lcof/
*
- * @author yangyi 2019年02月10日23:50:38
+ * @author yangyi 2021年01月27日18:44:17
*/
-public class SymmetricTree {
+public class Solution {
public static class TreeNode {
int val;
@@ -18,17 +20,22 @@ public static class TreeNode {
}
public boolean isSymmetric(TreeNode root) {
- return isMirror(root, root);
+ return compare(root, root);
}
- public boolean isMirror(TreeNode p, TreeNode q) {
- if (p == null && q == null) {
+ private boolean compare(TreeNode left, TreeNode right) {
+ if (left == null && right == null) {
return true;
- }
- if (p == null || q == null) {
+ } else if (left != null && right == null) {
+ return false;
+ } else if (left == null && right != null) {
+ return false;
+ } else if (left.val != right.val) {
return false;
}
- return p.val == q.val && isMirror(p.left, q.right) && isMirror(p.right, q.left);
+ boolean compareLeft = compare(left.left, right.right);
+ boolean compareRight = compare(left.right, right.left);
+ return compareLeft && compareRight;
}
public static void main(String[] args) {
@@ -43,7 +50,7 @@ public static void main(String[] args) {
val__1.left = val__2;
val__1.right = val__2;
- SymmetricTree symmetricTree = new SymmetricTree();
+ Solution symmetricTree = new Solution();
System.out.println(symmetricTree.isSymmetric(val_1));
System.out.println(symmetricTree.isSymmetric(val__1));
}
diff --git a/src/main/java/ds/tree/leetcode104/Solution.java b/src/main/java/ds/tree/leetcode104/Solution.java
new file mode 100644
index 0000000..bbe4518
--- /dev/null
+++ b/src/main/java/ds/tree/leetcode104/Solution.java
@@ -0,0 +1,83 @@
+package ds.tree.leetcode104;
+
+import java.util.LinkedList;
+import java.util.Queue;
+
+/**
+ * 二叉树的最大深度
+ * LeetCode 104 https://leetcode-cn.com/problems/maximum-depth-of-binary-tree/
+ *
+ * @author yangyi 2021年01月28日16:10:32
+ */
+public class Solution {
+
+ public class TreeNode {
+ int val;
+ TreeNode left;
+ TreeNode right;
+ }
+
+ /**
+ * 递归方式解决
+ */
+ public int maxDepthRecursion(TreeNode root) {
+ if (root == null) {
+ return 0;
+ }
+ int leftDepth = maxDepthRecursion(root.left);
+ int rightDepth = maxDepthRecursion(root.right);
+ return Math.max(leftDepth, rightDepth) + 1;
+ }
+
+ /**
+ * 层序遍历(广度优先搜索)方式解决
+ */
+ public int maxDepth(TreeNode root) {
+ if (root == null) {
+ return 0;
+ }
+ Queue
queue = new LinkedList
();
+ queue.offer(root);
+ int level = 0;
+ while (!queue.isEmpty()) {
+ int size = queue.size();
+ level++;
+ for (int i = 0; i < size; i++) { + TreeNode cur = queue.poll(); + if (cur.left != null) { + queue.offer(cur.left); + } + if (cur.right != null) { + queue.offer(cur.right); + } + } + } + return level; + } + + public TreeNode createTree() { + TreeNode node_3 = new TreeNode(); + node_3.val = 3; + TreeNode node_9 = new TreeNode(); + node_9.val = 9; + TreeNode node_20 = new TreeNode(); + node_20.val = 20; + TreeNode node_15 = new TreeNode(); + node_15.val = 15; + TreeNode node_7 = new TreeNode(); + node_7.val = 7; + node_3.left = node_9; + node_3.right = node_20; + node_9.left = node_15; + node_20.right = node_7; + return node_3; + } + + public static void main(String[] args) { + Solution maxDepth = new Solution(); + int level = maxDepth.maxDepth(maxDepth.createTree()); + System.out.println("最大层级数为:" + level); + int level2 = maxDepth.maxDepthRecursion(maxDepth.createTree()); + System.out.println("最大层级数为:" + level2); + } +} diff --git a/src/main/java/ds/tree/PreInOrderBuildTree.java b/src/main/java/ds/tree/leetcode105/Solution.java similarity index 90% rename from src/main/java/ds/tree/PreInOrderBuildTree.java rename to src/main/java/ds/tree/leetcode105/Solution.java index 8eadfc6..5882952 100644 --- a/src/main/java/ds/tree/PreInOrderBuildTree.java +++ b/src/main/java/ds/tree/leetcode105/Solution.java @@ -1,12 +1,13 @@ -package ds.tree; +package ds.tree.leetcode105; /** * 从前序与中序遍历序列构造二叉树 * Leetcode 105 https://leetcode-cn.com/problems/construct-binary-tree-from-preorder-and-inorder-traversal/ + * 剑指 Offer 07 https://leetcode-cn.com/problems/zhong-jian-er-cha-shu-lcof/ * * @author yangyi 2020年11月29日14:41:50 */ -public class PreInOrderBuildTree { +public class Solution { public static class TreeNode { int val; @@ -22,7 +23,7 @@ public static class TreeNode { * 前序遍历 preorder = [3,9,20,15,7] * 中序遍历 inorder = [9,3,15,20,7] */ - private TreeNode buildTree(int[] preorder, int[] inorder) { + public TreeNode buildTree(int[] preorder, int[] inorder) { return build(preorder, 0, preorder.length - 1, inorder, 0, inorder.length - 1); } @@ -70,7 +71,7 @@ public static void main(String[] args) { int[] preOrderNums = {3, 9, 20, 15, 7}; int[] inOrderNums = {9, 3, 15, 20, 7}; System.out.println("通过前序遍历结果和中序遍历结果构造二叉树: "); - PreInOrderBuildTree preInOrderBuildTree = new PreInOrderBuildTree(); + Solution preInOrderBuildTree = new Solution(); TreeNode root = preInOrderBuildTree.buildTree(preOrderNums, inOrderNums); System.out.println("构建完成之后验证结果: "); System.out.println("输出前序遍历的结果: "); diff --git a/src/main/java/ds/tree/InPostOrderBuildTree.java b/src/main/java/ds/tree/leetcode106/Solution.java similarity index 94% rename from src/main/java/ds/tree/InPostOrderBuildTree.java rename to src/main/java/ds/tree/leetcode106/Solution.java index 3fca5de..c7ee8ab 100644 --- a/src/main/java/ds/tree/InPostOrderBuildTree.java +++ b/src/main/java/ds/tree/leetcode106/Solution.java @@ -1,4 +1,4 @@ -package ds.tree; +package ds.tree.leetcode106; /** * 从中序与后序遍历序列构造二叉树 @@ -6,7 +6,7 @@ * * @author yangyi 2020年11月29日15:19:51 */ -public class InPostOrderBuildTree { +public class Solution { public class TreeNode { int val; @@ -68,7 +68,7 @@ private void postOrder(TreeNode root) { } public static void main(String[] args) { - InPostOrderBuildTree inPostOrderBuildTree = new InPostOrderBuildTree(); + Solution inPostOrderBuildTree = new Solution(); int[] inOrderNums = {9, 3, 15, 20, 7}; int[] postOrderNums = {9, 15, 7, 20, 3}; System.out.println("从中序与后序遍历序列构造二叉树"); diff --git a/src/main/java/ds/tree/IsBalancedTree.java b/src/main/java/ds/tree/leetcode110/Solution.java similarity index 94% rename from src/main/java/ds/tree/IsBalancedTree.java rename to src/main/java/ds/tree/leetcode110/Solution.java index 356ba1f..fc34067 100644 --- a/src/main/java/ds/tree/IsBalancedTree.java +++ b/src/main/java/ds/tree/leetcode110/Solution.java @@ -1,4 +1,4 @@ -package ds.tree; +package ds.tree.leetcode110; /** * 验证一颗二叉树是否为平衡二叉树 @@ -8,7 +8,7 @@ * * @author yangyi 2020年12月07日17:18:12 */ -public class IsBalancedTree { +public class Solution { public class TreeNode { int val; @@ -21,7 +21,7 @@ public class TreeNode { } public boolean isBalanced(TreeNode root) { - if (root == null) { + if(root == null){ return true; } if (root.left == null && root.right == null) { @@ -90,7 +90,7 @@ private TreeNode create2() { } public static void main(String[] args) { - IsBalancedTree isBalancedTree = new IsBalancedTree(); + Solution isBalancedTree = new Solution(); TreeNode root = isBalancedTree.create(); TreeNode root2 = isBalancedTree.create2(); System.out.println("第1颗树是否为平衡二叉树: " + isBalancedTree.isBalanced(root)); diff --git a/src/main/java/ds/tree/leetcode111/Solution.java b/src/main/java/ds/tree/leetcode111/Solution.java new file mode 100644 index 0000000..f858b26 --- /dev/null +++ b/src/main/java/ds/tree/leetcode111/Solution.java @@ -0,0 +1,98 @@ +package ds.tree.leetcode111; + +import java.util.LinkedList; +import java.util.Queue; + +/** + * 二叉树的最小深度 + * LeetCode 111 https://leetcode-cn.com/problems/minimum-depth-of-binary-tree/ + * + * @author yangyi 2021年01月28日16:53:38 + */ +public class Solution { + + public class TreeNode { + int val; + TreeNode left; + TreeNode right; + } + + /** + * 递归方式解决 + */ + public int minDepthRecursive(TreeNode root) { + if (root == null) { + return 0; + } + int leftDepth = minDepth(root.left); + int rightDepth = minDepth(root.right); + if (root.left == null && root.right != null) { + return rightDepth + 1; + } + if (root.left != null && root.right == null) { + return leftDepth + 1; + } + return Math.min(leftDepth, rightDepth) + 1; + } + + /** + * 层序遍历方式解决 + */ + public int minDepth(TreeNode root) { + if (root == null) { + return 0; + } + Queue queue = new LinkedList();
+ queue.offer(root);
+ int level = 0;
+ while (!queue.isEmpty()) {
+ int size = queue.size();
+ level++;
+ boolean finished = false;
+ for (int i = 0; i < size; i++) { + TreeNode cur = queue.poll(); + if (cur.left != null) { + queue.offer(cur.left); + } + if (cur.right != null) { + queue.offer(cur.right); + } + if (cur.left == null && cur.right == null) { + finished = true; + break; + } + } + if(finished){ + break; + } + } + return level; + } + + public TreeNode createTree() { + TreeNode node_3 = new TreeNode(); + node_3.val = 3; + TreeNode node_9 = new TreeNode(); + node_9.val = 9; + TreeNode node_20 = new TreeNode(); + node_20.val = 20; + TreeNode node_15 = new TreeNode(); + node_15.val = 15; + TreeNode node_7 = new TreeNode(); + node_7.val = 7; + node_3.left = node_9; + node_3.right = node_20; + node_20.left = node_15; + node_20.right = node_7; + return node_3; + } + + public static void main(String[] args) { + Solution minDepth = new Solution(); + TreeNode node = minDepth.createTree(); + int min = minDepth.minDepthRecursive(node); + System.out.println("最小深度为:" + min); + int min2 = minDepth.minDepth(node); + System.out.println("最小深度为:" + min2); + } +} diff --git a/src/main/java/ds/tree/leetcode112/Solution.java b/src/main/java/ds/tree/leetcode112/Solution.java new file mode 100644 index 0000000..02d8d0e --- /dev/null +++ b/src/main/java/ds/tree/leetcode112/Solution.java @@ -0,0 +1,96 @@ +package ds.tree.leetcode112; + + +/** + * 路径总和 + * LeetCode 112 https://leetcode-cn.com/problems/path-sum/ + * + * @author yangyi 2021年02月04日18:28:38 + */ +public class Solution { + + public class TreeNode { + int val; + TreeNode left; + TreeNode right; + + TreeNode() { + } + + TreeNode(int val) { + this.val = val; + } + + TreeNode(int val, TreeNode left, TreeNode right) { + this.val = val; + this.left = left; + this.right = right; + } + } + + public boolean hasPathSum(TreeNode root, int targetSum) { + if (root == null) { + return false; + } + return backtrack(root, targetSum - root.val); + } + + private boolean backtrack(TreeNode cur, int targetSum) { + if (cur != null && cur.left == null && cur.right == null && targetSum == 0) { + return true; + } + if (cur != null && cur.left == null && cur.right == null) { + return false; + } + if (cur.left != null) { + targetSum -= cur.left.val; + if (backtrack(cur.left, targetSum)) { + return true; + } + targetSum += cur.left.val; + } + if (cur.right != null) { + targetSum -= cur.right.val; + if (backtrack(cur.right, targetSum)) { + return true; + } + targetSum += cur.right.val; + } + return false; + } + + private TreeNode createTree() { + TreeNode node_5 = new TreeNode(5); + TreeNode node_4 = new TreeNode(4); + TreeNode node_8 = new TreeNode(8); + TreeNode node_11 = new TreeNode(11); + TreeNode node_13 = new TreeNode(13); + TreeNode node_4_4 = new TreeNode(4); + TreeNode node_7 = new TreeNode(7); + TreeNode node_2 = new TreeNode(2); + TreeNode node_1 = new TreeNode(1); + node_5.left = node_4; + node_5.right = node_8; + node_4.left = node_11; + node_11.left = node_7; + node_11.right = node_2; + node_8.left = node_13; + node_8.right = node_4_4; + node_4_4.right = node_1; + return node_5; + } + + private TreeNode createTree2() { + TreeNode node_1 = new TreeNode(1); + TreeNode node_2 = new TreeNode(2); + TreeNode node_3 = new TreeNode(3); + node_1.left = node_2; + node_1.right = node_3; + return node_1; + } + + public static void main(String[] args) { + System.out.println(new Solution().hasPathSum(new Solution().createTree(), 22)); + System.out.println(new Solution().hasPathSum(new Solution().createTree2(), 5)); + } +} diff --git a/src/main/java/ds/tree/leetcode113/Solution.java b/src/main/java/ds/tree/leetcode113/Solution.java new file mode 100644 index 0000000..6f0a973 --- /dev/null +++ b/src/main/java/ds/tree/leetcode113/Solution.java @@ -0,0 +1,99 @@ +package ds.tree.leetcode113; + +import java.util.Arrays; +import java.util.LinkedList; +import java.util.List; + +/** + * 路径总和II + * LeetCode 113 https://leetcode-cn.com/problems/path-sum-ii/ + * + * @author yangyi 2021年02月05日16:39:12 + */ +public class Solution { + + public class TreeNode { + int val; + TreeNode left; + TreeNode right; + + TreeNode() { + } + + TreeNode(int val) { + this.val = val; + } + + TreeNode(int val, TreeNode left, TreeNode right) { + this.val = val; + this.left = left; + this.right = right; + } + } + + public List> pathSum(TreeNode root, int targetSum) {
+ if (root == null) {
+ return new LinkedList();
+ }
+ List> result = new LinkedList();
+ LinkedList path = new LinkedList();
+ path.add(root.val);
+ backtrack(root, targetSum - root.val, result, path);
+ return result;
+ }
+
+ private void backtrack(
+ TreeNode cur,
+ int targetSum,
+ List> result,
+ LinkedList path) {
+ if (cur != null && cur.left == null && cur.right == null && targetSum == 0) {
+ result.add(new LinkedList(path));
+ return;
+ }
+ if (cur != null && cur.left == null && cur.right == null) {
+ return;
+ }
+ if (cur.left != null) {
+ path.add(cur.left.val);
+ targetSum -= cur.left.val;
+ backtrack(cur.left, targetSum, result, path);
+ targetSum += cur.left.val;
+ path.removeLast();
+ }
+ if (cur.right != null) {
+ path.add(cur.right.val);
+ targetSum -= cur.right.val;
+ backtrack(cur.right, targetSum, result, path);
+ targetSum += cur.right.val;
+ path.removeLast();
+ }
+ }
+
+ private TreeNode createTree() {
+ TreeNode node_5 = new TreeNode(5);
+ TreeNode node_4 = new TreeNode(4);
+ TreeNode node_8 = new TreeNode(8);
+ TreeNode node_11 = new TreeNode(11);
+ TreeNode node_13 = new TreeNode(13);
+ TreeNode node_4_4 = new TreeNode(4);
+ TreeNode node_7 = new TreeNode(7);
+ TreeNode node_2 = new TreeNode(2);
+ TreeNode node_5_5 = new TreeNode(5);
+ TreeNode node_1 = new TreeNode(1);
+ node_5.left = node_4;
+ node_5.right = node_8;
+ node_4.left = node_11;
+ node_8.left = node_13;
+ node_8.right = node_4_4;
+ node_11.left = node_7;
+ node_11.right = node_2;
+ node_4_4.left = node_5_5;
+ node_4_4.right = node_1;
+ return node_5;
+ }
+
+ public static void main(String[] args) {
+ System.out.println(Arrays.toString(new Solution().pathSum(new Solution().createTree(), 22).toArray()));
+ }
+}
diff --git a/src/main/java/ds/tree/FlattenLink.java b/src/main/java/ds/tree/leetcode114/Solution.java
similarity index 88%
rename from src/main/java/ds/tree/FlattenLink.java
rename to src/main/java/ds/tree/leetcode114/Solution.java
index ddc8b13..4eac0ab 100644
--- a/src/main/java/ds/tree/FlattenLink.java
+++ b/src/main/java/ds/tree/leetcode114/Solution.java
@@ -1,12 +1,13 @@
-package ds.tree;
+package ds.tree.leetcode114;
/**
* 将二叉树展开为链表
* LeetCode 114 https://leetcode-cn.com/problems/flatten-binary-tree-to-linked-list/
+ * https://assets.leetcode.com/uploads/2021/01/14/flaten.jpg
*
* @author yangyi 2020年11月25日16:22:39
*/
-public class FlattenLink {
+public class Solution {
public static class TreeNode {
int val;
@@ -93,14 +94,14 @@ private void preOrder(TreeNode root) {
}
public static void main(String[] args) {
- FlattenLink flattenLink = new FlattenLink();
- TreeNode root = flattenLink.createTree();
+ Solution solution = new Solution();
+ TreeNode root = solution.createTree();
System.out.println("中序遍历创建完成的二叉树: ");
- flattenLink.inOrder(root);
+ solution.inOrder(root);
System.out.println();
System.out.println("将此二叉树拉平成为一个链表: ");
- flattenLink.flatten(root);
+ solution.flatten(root);
System.out.println("打印这条二叉树被拉平后生成的链表: ");
- flattenLink.preOrder(root);
+ solution.preOrder(root);
}
}
diff --git a/src/main/java/ds/tree/ConnectRightTree.java b/src/main/java/ds/tree/leetcode116/Solution.java
similarity index 94%
rename from src/main/java/ds/tree/ConnectRightTree.java
rename to src/main/java/ds/tree/leetcode116/Solution.java
index 0020302..20c7dea 100644
--- a/src/main/java/ds/tree/ConnectRightTree.java
+++ b/src/main/java/ds/tree/leetcode116/Solution.java
@@ -1,12 +1,13 @@
-package ds.tree;
+package ds.tree.leetcode116;
/**
* 填充每个节点的下一个右侧节点指针
* LeetCode 116 https://leetcode-cn.com/problems/populating-next-right-pointers-in-each-node/
+ * eg: https://assets.leetcode.com/uploads/2019/02/14/116_sample.png
*
* @author yangyi 2020年11月25日11:10:04
*/
-public class ConnectRightTree {
+public class Solution {
public static class TreeNode {
public int val;
@@ -89,7 +90,7 @@ private void preOrderLink(TreeNode node) {
}
public static void main(String[] args) {
- ConnectRightTree connectRightTree = new ConnectRightTree();
+ Solution connectRightTree = new Solution();
TreeNode root = connectRightTree.createTree();
System.out.println("中序遍历创建完成的树并打印:");
connectRightTree.inOrder(root);
diff --git a/src/main/java/ds/tree/leetcode144/Solution.java b/src/main/java/ds/tree/leetcode144/Solution.java
new file mode 100644
index 0000000..9d19f3c
--- /dev/null
+++ b/src/main/java/ds/tree/leetcode144/Solution.java
@@ -0,0 +1,63 @@
+package ds.tree.leetcode144;
+
+import java.util.Arrays;
+import java.util.LinkedList;
+import java.util.List;
+
+/**
+ * 二叉树的前序遍历
+ * LeetCode 144 https://leetcode-cn.com/problems/binary-tree-preorder-traversal/
+ *
+ * @author yangyi 2021年01月21日15:24:33
+ */
+public class Solution {
+
+ public class TreeNode {
+ int val;
+ TreeNode left;
+ TreeNode right;
+
+ TreeNode() {
+ }
+
+ TreeNode(int val) {
+ this.val = val;
+ }
+
+ TreeNode(int val, TreeNode left, TreeNode right) {
+ this.val = val;
+ this.left = left;
+ this.right = right;
+ }
+ }
+
+ public List preorderTraversal(TreeNode root) {
+ List result = new LinkedList