From 80aa37ed93e7ccd6367c441478430c60d572baea Mon Sep 17 00:00:00 2001 From: yuanguangxin <274841922@qq.com> Date: Tue, 25 Feb 2020 22:42:46 +0800 Subject: [PATCH] add q73/q102/q118/q224 --- .idea/workspace.xml | 38 +++++--- README.md | 4 + .../Main.java | 2 +- .../TreeNode.java | 2 +- .../q118_杨辉三角/Solution.java | 35 +++++++ .../q73_矩阵置零/Solution.java | 54 +++++++++++ .../q224_基本计算器/f1/Solution.java | 96 +++++++++++++++++++ .../q224_基本计算器/f2/Solution.java | 59 ++++++++++++ .../Solution.java | 43 +++++++++ .../TreeNode.java | 11 +++ 10 files changed, 331 insertions(+), 13 deletions(-) rename src/其他/{二叉树的遍历 => 二叉树的前中后序遍历}/Main.java (98%) rename src/其他/{二叉树的遍历 => 二叉树的前中后序遍历}/TreeNode.java (72%) create mode 100644 src/动态规划/q118_杨辉三角/Solution.java create mode 100644 src/数组操作/q73_矩阵置零/Solution.java create mode 100644 src/栈操作/q224_基本计算器/f1/Solution.java create mode 100644 src/栈操作/q224_基本计算器/f2/Solution.java create mode 100644 src/树的遍历/q102_二叉树的层次遍历/Solution.java create mode 100644 src/树的遍历/q102_二叉树的层次遍历/TreeNode.java diff --git a/.idea/workspace.xml b/.idea/workspace.xml index f25d900..da96c19 100644 --- a/.idea/workspace.xml +++ b/.idea/workspace.xml @@ -1,9 +1,15 @@ - + + + + + + + - + + - @@ -246,7 +252,10 @@ - + + + + 1580045439607 @@ -479,7 +488,14 @@ - @@ -570,10 +586,10 @@ - + - + @@ -623,18 +639,18 @@ - + - + - + - + diff --git a/README.md b/README.md index e627df0..db1669f 100644 --- a/README.md +++ b/README.md @@ -38,10 +38,12 @@ ### 数组操作 * [q54_螺旋矩阵](/src/数组操作/q54_螺旋矩阵) +* [q73_矩阵置零](/src/数组操作/q73_矩阵置零) ### 栈操作 * [q20_有效的括号](/src/栈操作/q20_有效的括号) +* [q224_基本计算器](/src/栈操作/q224_基本计算器) ### 递归 @@ -58,6 +60,7 @@ * [q5_最长回文子串](/src/动态规划/q5_最长回文子串) * [q53_最大子序和](/src/动态规划/q53_最大子序和) +* [q118_杨辉三角](/src/动态规划/q118_杨辉三角) * [q746_使用最小花费爬楼梯](/src/动态规划/q746_使用最小花费爬楼梯) * [q1277_统计全为1的正方形子矩阵](/src/动态规划/q1277_统计全为1的正方形子矩阵) @@ -70,6 +73,7 @@ ### 树的遍历 * [q94_二叉树的中序遍历](/src/树的遍历/q94_二叉树的中序遍历) +* [q102_二叉树的层次遍历](/src/树的遍历/q102_二叉树的层次遍历) * [q110_平衡二叉树](/src/树的遍历/q110_平衡二叉树) * [q144_二叉树的前序遍历](/src/树的遍历/q144_二叉树的前序遍历) * [q145_二叉树的后序遍历](/src/树的遍历/q145_二叉树的后序遍历) diff --git a/src/其他/二叉树的遍历/Main.java b/src/其他/二叉树的前中后序遍历/Main.java similarity index 98% rename from src/其他/二叉树的遍历/Main.java rename to src/其他/二叉树的前中后序遍历/Main.java index 8740f3e..1e76af0 100644 --- a/src/其他/二叉树的遍历/Main.java +++ b/src/其他/二叉树的前中后序遍历/Main.java @@ -1,4 +1,4 @@ -package 其他.二叉树的遍历; +package 其他.二叉树的前中后序遍历; import java.util.Stack; diff --git a/src/其他/二叉树的遍历/TreeNode.java b/src/其他/二叉树的前中后序遍历/TreeNode.java similarity index 72% rename from src/其他/二叉树的遍历/TreeNode.java rename to src/其他/二叉树的前中后序遍历/TreeNode.java index 9cfd047..bc4fa32 100644 --- a/src/其他/二叉树的遍历/TreeNode.java +++ b/src/其他/二叉树的前中后序遍历/TreeNode.java @@ -1,4 +1,4 @@ -package 其他.二叉树的遍历; +package 其他.二叉树的前中后序遍历; public class TreeNode { int val; diff --git a/src/动态规划/q118_杨辉三角/Solution.java b/src/动态规划/q118_杨辉三角/Solution.java new file mode 100644 index 0000000..74fa09e --- /dev/null +++ b/src/动态规划/q118_杨辉三角/Solution.java @@ -0,0 +1,35 @@ +package 动态规划.q118_杨辉三角; + +import java.util.ArrayList; +import java.util.List; + +/** + * 找规律,动态规划 o(n^2) + */ +public class Solution { + + public List> generate(int numRows) { + List> triangle = new ArrayList>(); + + if (numRows == 0) { + return triangle; + } + + triangle.add(new ArrayList<>()); + triangle.get(0).add(1); + + for (int rowNum = 1; rowNum < numRows; rowNum++) { + List row = new ArrayList<>(); + List prevRow = triangle.get(rowNum-1); + row.add(1); + + for (int j = 1; j < rowNum; j++) { + row.add(prevRow.get(j-1) + prevRow.get(j)); + } + + row.add(1); + triangle.add(row); + } + return triangle; + } +} diff --git a/src/数组操作/q73_矩阵置零/Solution.java b/src/数组操作/q73_矩阵置零/Solution.java new file mode 100644 index 0000000..dbc69d7 --- /dev/null +++ b/src/数组操作/q73_矩阵置零/Solution.java @@ -0,0 +1,54 @@ +package 数组操作.q73_矩阵置零; + +/** + * 用每行和每列的第一个元素作为标记,空间复杂度是o(1),时间复杂度 o(m*n) + */ +public class Solution { + + public void setZeroes(int[][] matrix) { + //第一行是否需要置零 + boolean row = false; + //第一列是否需要置零 + boolean column = false; + for (int i = 0; i < matrix.length; i++) { + for (int j = 0; j < matrix[i].length; j++) { + if (matrix[i][j] == 0) { + if (i == 0) { + row = true; + } + if (j == 0) { + column = true; + } + //第i行第一个元素置零,表示这一行需要全部置零 + matrix[i][0] = 0; + //第j列第一个元素置零,表示这一列需要全部置零 + matrix[0][j] = 0; + } + } + } + for (int i = 1; i < matrix.length; i++) { + if (matrix[i][0] == 0) { + for (int j = 1; j < matrix[i].length; j++) { + matrix[i][j] = 0; + } + } + } + for (int j = 1; j < matrix[0].length; j++) { + if (matrix[0][j] == 0) { + for (int i = 1; i < matrix.length; i++) { + matrix[i][j] = 0; + } + } + } + if (row) { + for (int j = 1; j < matrix[0].length; j++) { + matrix[0][j] = 0; + } + } + if (column) { + for (int i = 1; i < matrix.length; i++) { + matrix[i][0] = 0; + } + } + } +} diff --git a/src/栈操作/q224_基本计算器/f1/Solution.java b/src/栈操作/q224_基本计算器/f1/Solution.java new file mode 100644 index 0000000..cfded09 --- /dev/null +++ b/src/栈操作/q224_基本计算器/f1/Solution.java @@ -0,0 +1,96 @@ +package 栈操作.q224_基本计算器.f1; + +import java.util.Stack; + +/** + * 双栈(操作数栈+操作符栈)o(n) + */ +public class Solution { + + public int calculate(String s) { + char[] array = s.toCharArray(); + int n = array.length; + Stack num = new Stack<>(); + Stack op = new Stack<>(); + int temp = -1; + for (int i = 0; i < n; i++) { + if (array[i] == ' ') { + continue; + } + // 数字进行累加 + if (isNumber(array[i])) { + if (temp == -1) { + temp = array[i] - '0'; + } else { + temp = temp * 10 + array[i] - '0'; + } + } else { + //将数字入栈 + if (temp != -1) { + num.push(temp); + temp = -1; + } + //遇到操作符 + if (isOperation(array[i] + "")) { + while (!op.isEmpty()) { + if (op.peek() == '(') { + break; + } + //不停的出栈,进行运算,并将结果再次压入栈中 + int num1 = num.pop(); + int num2 = num.pop(); + if (op.pop() == '+') { + num.push(num1 + num2); + } else { + num.push(num2 - num1); + } + + } + //当前运算符入栈 + op.push(array[i]); + } else { + //遇到左括号,直接入栈 + if (array[i] == '(') { + op.push(array[i]); + } + //遇到右括号,不停的进行运算,直到遇到左括号 + if (array[i] == ')') { + while (op.peek() != '(') { + int num1 = num.pop(); + int num2 = num.pop(); + if (op.pop() == '+') { + num.push(num1 + num2); + } else { + num.push(num2 - num1); + } + } + op.pop(); + } + + } + } + } + if (temp != -1) { + num.push(temp); + } + //将栈中的其他元素继续运算 + while (!op.isEmpty()) { + int num1 = num.pop(); + int num2 = num.pop(); + if (op.pop() == '+') { + num.push(num1 + num2); + } else { + num.push(num2 - num1); + } + } + return num.pop(); + } + + private boolean isNumber(char c) { + return c >= '0' && c <= '9'; + } + + private boolean isOperation(String t) { + return t.equals("+") || t.equals("-") || t.equals("*") || t.equals("/"); + } +} diff --git a/src/栈操作/q224_基本计算器/f2/Solution.java b/src/栈操作/q224_基本计算器/f2/Solution.java new file mode 100644 index 0000000..aec71cb --- /dev/null +++ b/src/栈操作/q224_基本计算器/f2/Solution.java @@ -0,0 +1,59 @@ +package 栈操作.q224_基本计算器.f2; + +import java.util.Stack; + +/** + * 单栈 拆分递归思想 o(n) + */ +public class Solution { + + public int evaluateExpr(Stack stack) { + int res = 0; + + if (!stack.empty()) { + res = (int) stack.pop(); + } + + while (!stack.empty() && !((char) stack.peek() == ')')) { + char sign = (char) stack.pop(); + if (sign == '+') { + res += (int) stack.pop(); + } else { + res -= (int) stack.pop(); + } + } + return res; + } + + public int calculate(String s) { + int operand = 0; + int n = 0; + Stack stack = new Stack(); + + for (int i = s.length() - 1; i >= 0; i--) { + char ch = s.charAt(i); + if (Character.isDigit(ch)) { + operand = (int) Math.pow(10, n) * (int) (ch - '0') + operand; + n += 1; + } else if (ch != ' ') { + if (n != 0) { + stack.push(operand); + n = 0; + operand = 0; + } + if (ch == '(') { + int res = evaluateExpr(stack); + stack.pop(); + stack.push(res); + } else { + stack.push(ch); + } + } + } + + if (n != 0) { + stack.push(operand); + } + return evaluateExpr(stack); + } +} diff --git a/src/树的遍历/q102_二叉树的层次遍历/Solution.java b/src/树的遍历/q102_二叉树的层次遍历/Solution.java new file mode 100644 index 0000000..826afcb --- /dev/null +++ b/src/树的遍历/q102_二叉树的层次遍历/Solution.java @@ -0,0 +1,43 @@ +package 树的遍历.q102_二叉树的层次遍历; + +import java.util.ArrayList; +import java.util.LinkedList; +import java.util.List; +import java.util.Queue; + +/** + * 利用队列迭代 o(n) + */ +public class Solution { + public List> levelOrder(TreeNode root) { + + List> levels = new ArrayList<>(); + if (root == null) { + return levels; + } + + Queue queue = new LinkedList<>(); + queue.add(root); + int level = 0; + while (!queue.isEmpty()) { + + levels.add(new ArrayList<>()); + + int levelLength = queue.size(); + + for (int i = 0; i < levelLength; ++i) { + TreeNode node = queue.remove(); + levels.get(level).add(node.val); + + if (node.left != null) { + queue.add(node.left); + } + if (node.right != null) { + queue.add(node.right); + } + } + level++; + } + return levels; + } +} diff --git a/src/树的遍历/q102_二叉树的层次遍历/TreeNode.java b/src/树的遍历/q102_二叉树的层次遍历/TreeNode.java new file mode 100644 index 0000000..79e246e --- /dev/null +++ b/src/树的遍历/q102_二叉树的层次遍历/TreeNode.java @@ -0,0 +1,11 @@ +package 树的遍历.q102_二叉树的层次遍历; + +public class TreeNode { + int val; + TreeNode left; + TreeNode right; + + TreeNode(int x) { + val = x; + } +}