This commit is contained in:
youngyangyang04
2021-05-20 09:51:21 +08:00
24 changed files with 1173 additions and 23 deletions

View File

@ -135,6 +135,28 @@ func removeNthFromEnd(head *ListNode, n int) *ListNode {
}
```
JavaScript:
```js
/**
* @param {ListNode} head
* @param {number} n
* @return {ListNode}
*/
var removeNthFromEnd = function(head, n) {
let ret = new ListNode(0, head),
slow = fast = ret;
while(n--) fast = fast.next;
if(!fast) return ret.next;
while (fast.next) {
fast = fast.next;
slow = slow.next
};
slow.next = slow.next.next;
return ret.next;
};
```
-----------------------
* 作者微信:[程序员Carl](https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw)
* B站视频[代码随想录](https://space.bilibili.com/525438321)

View File

@ -193,6 +193,26 @@ class Solution:
```
Go
```Go
func jump(nums []int) int {
dp:=make([]int ,len(nums))
dp[0]=0
for i:=1;i<len(nums);i++{
dp[i]=i
for j:=0;j<i;j++{
if nums[j]+j>i{
dp[i]=min(dp[j]+1,dp[i])
}
}
}
return dp[len(nums)-1]
}
/*
dp[i]表示从起点到当前位置的最小跳跃次数
dp[i]=min(dp[j]+1,dp[i]) 表示从j位置用一步跳跃到当前位置这个j位置可能有很多个却最小一个就可以
*/
```

View File

@ -122,6 +122,24 @@ class Solution:
```
Go
```Go
func canJUmp(nums []int) bool {
if len(nums)<=1{
return true
}
dp:=make([]bool,len(nums))
dp[0]=true
for i:=1;i<len(nums);i++{
for j:=i-1;j>=0;j--{
if dp[j]&&nums[j]+j>=i{
dp[i]=true
break
}
}
}
return dp[len(nums)-1]
}
```

View File

@ -370,8 +370,45 @@ class Solution {
Python
```python
class Solution:
result: List[List[int]] = []
path: List[int] = []
def combine(self, n: int, k: int) -> List[List[int]]:
self.result = []
self.combineHelper(n, k, 1)
return self.result
def combineHelper(self, n: int, k: int, startIndex: int):
if (l := len(self.path)) == k:
self.result.append(self.path.copy())
return
for i in range(startIndex, n - (k - l) + 2):
self.path.append(i)
self.combineHelper(n, k, i + 1)
self.path.pop()
```
javascript
```javascript
let result = []
let path = []
var combine = function(n, k) {
result = []
combineHelper(n, k, 1)
return result
};
const combineHelper = (n, k, startIndex) => {
if (path.length === k) {
result.push([...path])
return
}
for (let i = startIndex; i <= n - (k - path.length) + 1; ++i) {
path.push(i)
combineHelper(n, k, i + 1)
path.pop()
}
}
```
Go
```Go
var res [][]int

View File

@ -336,8 +336,26 @@ class Solution {
```
Python
```python
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
//递归法
class Solution:
def isValidBST(self, root: TreeNode) -> bool:
res = [] //把二叉搜索树按中序遍历写成list
def buildalist(root):
if not root: return
buildalist(root.left) //
res.append(root.val) //
buildalist(root.right) //
return res
buildalist(root)
return res == sorted(res) and len(set(res)) == len(res) //检查list里的数有没有重复元素以及是否按从小到大排列
```
Go
```Go
import "math"

View File

@ -302,6 +302,53 @@ class Solution:
Go
JavaScript:
递归法:
```javascript
/**
* @param {TreeNode} root
* @return {number}
*/
var minDepth1 = function(root) {
if(!root) return 0;
// 到叶子节点 返回 1
if(!root.left && !root.right) return 1;
// 只有右节点时 递归右节点
if(!root.left) return 1 + minDepth(root.right);、
// 只有左节点时 递归左节点
if(!root.right) return 1 + minDepth(root.left);
return Math.min(minDepth(root.left), minDepth(root.right)) + 1;
};
```
迭代法:
```javascript
/**
* @param {TreeNode} root
* @return {number}
*/
var minDepth = function(root) {
if(!root) return 0;
const queue = [root];
let dep = 0;
while(true) {
let size = queue.length;
dep++;
while(size--){
const node = queue.shift();
// 到第一个叶子节点 返回 当前深度
if(!node.left && !node.right) return dep;
node.left && queue.push(node.left);
node.right && queue.push(node.right);
}
}
};
```
-----------------------

View File

@ -254,7 +254,25 @@ Python
Go
```Go
func wordBreak(s string,wordDict []string) bool {
wordDictSet:=make(map[string]bool)
for _,w:=range wordDict{
wordDictSet[w]=true
}
dp:=make([]bool,len(s)+1)
dp[0]=true
for i:=1;i<=len(s);i++{
for j:=0;j<i;j++{
if dp[j]&& wordDictSet[s[j:i]]{
dp[i]=true
break
}
}
}
return dp[len(s)]
}
```

View File

@ -258,6 +258,50 @@ Go
}
```
javaScript
```js
// 两种循环实现方式
/**
* @param {ListNode} head
* @return {ListNode}
*/
// 先判断是否是环形链表
var detectCycle = function(head) {
if(!head || !head.next) return null;
let slow =head.next, fast = head.next.next;
while(fast && fast.next && fast!== slow) {
slow = slow.next;
fast = fast.next.next;
}
if(!fast || !fast.next ) return null;
slow = head;
while (fast !== slow) {
slow = slow.next;
fast = fast.next;
}
return slow;
};
var detectCycle = function(head) {
if(!head || !head.next) return null;
let slow =head.next, fast = head.next.next;
while(fast && fast.next) {
slow = slow.next;
fast = fast.next.next;
if(fast == slow) {
slow = head;
while (fast !== slow) {
slow = slow.next;
fast = fast.next;
}
return slow;
}
}
return null;
};
```
-----------------------
* 作者微信:[程序员Carl](https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw)

View File

@ -112,6 +112,40 @@ Python
Go
javaScript:
```js
function getN(n) {
if (n == 1 || n == 0) return n;
let res = 0;
while (n) {
res += (n % 10) * (n % 10);
n = parseInt(n / 10);
}
return res;
}
var isHappy = function(n) {
const sumSet = new Set();
while (n != 1 && !sumSet.has(n)) {
sumSet.add(n);
n = getN(n);
}
return n == 1;
};
// 使用环形链表的思想 说明出现闭环 退出循环
var isHappy = function(n) {
if (getN(n) == 1) return true;
let a = getN(n), b = getN(getN(n));
// 如果 a === b
while (b !== 1 && getN(b) !== 1 && a !== b) {
a = getN(a);
b = getN(getN(b));
}
return b === 1 || getN(b) === 1 ;
};
```

View File

@ -156,6 +156,7 @@ public:
Java
使用两个 Queue 实现
```java
class MyStack {
@ -205,7 +206,94 @@ class MyStack {
* boolean param_4 = obj.empty();
*/
```
使用两个 Deque 实现
```java
class MyStack {
// Deque 接口继承了 Queue 接口
// 所以 Queue 中的 add、poll、peek等效于 Deque 中的 addLast、pollFirst、peekFirst
Deque<Integer> que1; // 和栈中保持一样元素的队列
Deque<Integer> que2; // 辅助队列
/** Initialize your data structure here. */
public MyStack() {
que1 = new ArrayDeque<>();
que2 = new ArrayDeque<>();
}
/** Push element x onto stack. */
public void push(int x) {
que1.addLast(x);
}
/** Removes the element on top of the stack and returns that element. */
public int pop() {
int size = que1.size();
size--;
// 将 que1 导入 que2 ,但留下最后一个值
while (size-- > 0) {
que2.addLast(que1.peekFirst());
que1.pollFirst();
}
int res = que1.pollFirst();
// 将 que2 对象的引用赋给了 que1 ,此时 que1que2 指向同一个队列
que1 = que2;
// 如果直接操作 que2que1 也会受到影响,所以为 que2 分配一个新的空间
que2 = new ArrayDeque<>();
return res;
}
/** Get the top element. */
public int top() {
return que1.peekLast();
}
/** Returns whether the stack is empty. */
public boolean empty() {
return que1.isEmpty();
}
}
```
优化,使用一个 Deque 实现
```java
class MyStack {
// Deque 接口继承了 Queue 接口
// 所以 Queue 中的 add、poll、peek等效于 Deque 中的 addLast、pollFirst、peekFirst
Deque<Integer> que1;
/** Initialize your data structure here. */
public MyStack() {
que1 = new ArrayDeque<>();
}
/** Push element x onto stack. */
public void push(int x) {
que1.addLast(x);
}
/** Removes the element on top of the stack and returns that element. */
public int pop() {
int size = que1.size();
size--;
// 将 que1 导入 que2 ,但留下最后一个值
while (size-- > 0) {
que1.addLast(que1.peekFirst());
que1.pollFirst();
}
int res = que1.pollFirst();
return res;
}
/** Get the top element. */
public int top() {
return que1.peekLast();
}
/** Returns whether the stack is empty. */
public boolean empty() {
return que1.isEmpty();
}
}
```
Python

View File

@ -131,6 +131,101 @@ public:
Java
使用Stack(堆栈)同名方法:
```java
class MyQueue {
// java中的 Stack 有设计上的缺陷,官方推荐使用 Deque(双端队列) 代替 Stack
Deque<Integer> stIn;
Deque<Integer> stOut;
/** Initialize your data structure here. */
public MyQueue() {
stIn = new ArrayDeque<>();
stOut = new ArrayDeque<>();
}
/** Push element x to the back of queue. */
public void push(int x) {
stIn.push(x);
}
/** Removes the element from in front of queue and returns that element. */
public int pop() {
// 只要 stOut 为空,那么就应该将 stIn 中所有的元素倒腾到 stOut 中
if (stOut.isEmpty()) {
while (!stIn.isEmpty()) {
stOut.push(stIn.pop());
}
}
// 再返回 stOut 中的元素
return stOut.pop();
}
/** Get the front element. */
public int peek() {
// 直接使用已有的pop函数
int res = this.pop();
// 因为pop函数弹出了元素res所以再添加回去
stOut.push(res);
return res;
}
/** Returns whether the queue is empty. */
public boolean empty() {
// 当 stIn 栈为空时,说明没有元素可以倒腾到 stOut 栈了
// 并且 stOut 栈也为空时,说明没有以前从 stIn 中倒腾到的元素了
return stIn.isEmpty() && stOut.isEmpty();
}
}
```
个人习惯写法使用Deque通用api
```java
class MyQueue {
// java中的 Stack 有设计上的缺陷,官方推荐使用 Deque(双端队列) 代替 Stack
// Deque 中的 addFirst、removeFirst、peekFirst 等方法等效于 Stack(堆栈) 中的 push、pop、peek
Deque<Integer> stIn;
Deque<Integer> stOut;
/** Initialize your data structure here. */
public MyQueue() {
stIn = new ArrayDeque<>();
stOut = new ArrayDeque<>();
}
/** Push element x to the back of queue. */
public void push(int x) {
stIn.addLast(x);
}
/** Removes the element from in front of queue and returns that element. */
public int pop() {
// 只要 stOut 为空,那么就应该将 stIn 中所有的元素倒腾到 stOut 中
if (stOut.isEmpty()) {
while (!stIn.isEmpty()) {
stOut.addLast(stIn.pollLast());
}
}
// 再返回 stOut 中的元素
return stOut.pollLast();
}
/** Get the front element. */
public int peek() {
// 直接使用已有的pop函数
int res = this.pop();
// 因为pop函数弹出了元素res所以再添加回去
stOut.addLast(res);
return res;
}
/** Returns whether the queue is empty. */
public boolean empty() {
// 当 stIn 栈为空时,说明没有元素可以倒腾到 stOut 栈了
// 并且 stOut 栈也为空时,说明没有以前从 stIn 中倒腾到的元素了
return stIn.isEmpty() && stOut.isEmpty();
}
}
```
```java
class MyQueue {
@ -190,6 +285,73 @@ Python
Go
```Go
type MyQueue struct {
stack []int
back []int
}
/** Initialize your data structure here. */
func Constructor() MyQueue {
return MyQueue{
stack: make([]int, 0),
back: make([]int, 0),
}
}
/** Push element x to the back of queue. */
func (this *MyQueue) Push(x int) {
for len(this.back) != 0 {
val := this.back[len(this.back)-1]
this.back = this.back[:len(this.back)-1]
this.stack = append(this.stack, val)
}
this.stack = append(this.stack, x)
}
/** Removes the element from in front of queue and returns that element. */
func (this *MyQueue) Pop() int {
for len(this.stack) != 0 {
val := this.stack[len(this.stack)-1]
this.stack = this.stack[:len(this.stack)-1]
this.back = append(this.back, val)
}
if len(this.back) == 0 {
return 0
}
val := this.back[len(this.back)-1]
this.back = this.back[:len(this.back)-1]
return val
}
/** Get the front element. */
func (this *MyQueue) Peek() int {
for len(this.stack) != 0 {
val := this.stack[len(this.stack)-1]
this.stack = this.stack[:len(this.stack)-1]
this.back = append(this.back, val)
}
if len(this.back) == 0 {
return 0
}
val := this.back[len(this.back)-1]
return val
}
/** Returns whether the queue is empty. */
func (this *MyQueue) Empty() bool {
return len(this.stack) == 0 && len(this.back) == 0
}
/**
* Your MyQueue object will be instantiated and called as such:
* obj := Constructor();
* obj.Push(x);
* param_2 := obj.Pop();
* param_3 := obj.Peek();
* param_4 := obj.Empty();
*/
```

View File

@ -136,7 +136,34 @@ class Solution {
```
Python
```
class Solution(object):
def canConstruct(self, ransomNote, magazine):
"""
:type ransomNote: str
:type magazine: str
:rtype: bool
"""
# use a dict to store the number of letter occurance in ransomNote
hashmap = dict()
for s in ransomNote:
if s in hashmap:
hashmap[s] += 1
else:
hashmap[s] = 1
# check if the letter we need can be found in magazine
for l in magazine:
if l in hashmap:
hashmap[l] -= 1
for key in hashmap:
if hashmap[key] > 0:
return False
return True
```
Go

View File

@ -121,6 +121,37 @@ class Solution {
Python
```
class Solution(object):
def fourSumCount(self, nums1, nums2, nums3, nums4):
"""
:type nums1: List[int]
:type nums2: List[int]
:type nums3: List[int]
:type nums4: List[int]
:rtype: int
"""
# use a dict to store the elements in nums1 and nums2 and their sum
hashmap = dict()
for n1 in nums1:
for n2 in nums2:
if n1 + n2 in hashmap:
hashmap[n1+n2] += 1
else:
hashmap[n1+n2] = 1
# if the -(a+b) exists in nums3 and nums4, we shall add the count
count = 0
for n3 in nums3:
for n4 in nums4:
key = - n3 - n4
if key in hashmap:
count += hashmap[key]
return count
```
Go

View File

@ -149,9 +149,38 @@ public:
## 其他语言版本
Java
```java
class Solution {
public boolean repeatedSubstringPattern(String s) {
if (s.equals("")) return false;
int len = s.length();
// 原串加个空格(哨兵)使下标从1开始这样j从0开始也不用初始化了
s = " " + s;
char[] chars = s.toCharArray();
int[] next = new int[len + 1];
// 构造 next 数组过程j从0开始(空格)i从2开始
for (int i = 2, j = 0; i <= len; i++) {
// 匹配不成功j回到前一位置 next 数组所对应的值
while (j > 0 && chars[i] != chars[j + 1]) j = next[j];
// 匹配成功j往后移
if (chars[i] == chars[j + 1]) j++;
// 更新 next 数组的值
next[i] = j;
}
// 最后判断是否是重复的子字符串,这里 next[len] 即代表next数组末尾的值
if (next[len] > 0 && len % (len - next[len]) == 0) {
return true;
}
return false;
}
}
```
Python

View File

@ -173,6 +173,33 @@ Python
Go
```Go
func longestPalindromeSubseq(s string) int {
lenth:=len(s)
dp:=make([][]int,lenth)
for i:=0;i<lenth;i++{
for j:=0;j<lenth;j++{
if dp[i]==nil{
dp[i]=make([]int,lenth)
}
if i==j{
dp[i][j]=1
}
}
}
for i:=lenth-1;i>=0;i--{
for j:=i+1;j<lenth;j++{
if s[i]==s[j]{
dp[i][j]=dp[i+1][j-1]+2
}else {
dp[i][j]=max(dp[i+1][j],dp[i][j-1])
}
}
}
return dp[0][lenth-1]
}
```

View File

@ -177,8 +177,29 @@ class Solution {
```
Python
```python
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def getMinimumDifference(self, root: TreeNode) -> int:
res = []
r = float("inf")
def buildaList(root): //把二叉搜索树转换成有序数组
if not root: return None
if root.left: buildaList(root.left) //左
res.append(root.val) //中
if root.right: buildaList(root.right) //右
return res
buildaList(root)
for i in range(len(res)-1): // 统计有序数组的最小差值
r = min(abs(res[i]-res[i+1]),r)
return r
```
Go

View File

@ -312,7 +312,23 @@ class Solution {
```
Python
```python
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
//递归法*前序遍历
class Solution:
def mergeTrees(self, root1: TreeNode, root2: TreeNode) -> TreeNode:
if not root1: return root2 // 如果t1为空合并之后就应该是t2
if not root2: return root1 // 如果t2为空合并之后就应该是t1
root1.val = root1.val + root2.val //中
root1.left = self.mergeTrees(root1.left , root2.left) //左
root1.right = self.mergeTrees(root1.right , root2.right) //右
return root1 //root1修改了结构和数值
```
Go

View File

@ -212,13 +212,18 @@ Python
递归法:
```python
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def searchBST(self, root: TreeNode, val: int) -> TreeNode:
if root is None:
return None
if val < root.val: return self.searchBST(root.left, val)
elif val > root.val: return self.searchBST(root.right, val)
else: return root
if not root or root.val == val: return root //为空或者已经找到都是直接返回root所以合并了
if root.val > val: return self.searchBST(root.left,val) //注意一定要加return
else: return self.searchBST(root.right,val)
```
迭代法:

View File

@ -153,6 +153,10 @@ Java
```java
class Solution {
public int search(int[] nums, int target) {
// 避免当 target 小于nums[0] nums[nums.length - 1]时多次循环运算
if (target < nums[0] || target > nums[nums.length - 1]) {
return -1;
}
int left = 0, right = nums.length - 1;
while (left <= right) {
int mid = left + ((right - left) >> 1);
@ -210,6 +214,47 @@ class Solution:
Go
(版本一)左闭右闭区间
```go
func search(nums []int, target int) int {
high := len(nums)-1
low := 0
for low <= high {
mid := low + (high-low)/2
if nums[mid] == target {
return mid
} else if nums[mid] > target {
high = mid-1
} else {
low = mid+1
}
}
return -1
}
```
(版本二)左闭右开区间
```go
func search(nums []int, target int) int {
high := len(nums)
low := 0
for low < high {
mid := low + (high-low)/2
if nums[mid] == target {
return mid
} else if nums[mid] > target {
high = mid
} else {
low = mid+1
}
}
return -1
}
```

View File

@ -73,7 +73,24 @@ public:
Java
```java
class Solution {
public int maxUncrossedLines(int[] A, int[] B) {
int [][] dp = new int[A.length+1][B.length+1];
for(int i=1;i<=A.length;i++) {
for(int j=1;j<=B.length;j++) {
if (A[i-1]==B[j-1]) {
dp[i][j]=dp[i-1][j-1]+1;
}
else {
dp[i][j]=Math.max(dp[i-1][j], dp[i][j-1]);
}
}
}
return dp[A.length][B.length];
}
}
```
Python

View File

@ -175,7 +175,85 @@ if (cur->right) {
Java
100. 相同的树:递归代码
```java
class Solution {
public boolean compare(TreeNode tree1, TreeNode tree2) {
if(tree1==null && tree2==null)return true;
if(tree1==null || tree2==null)return false;
if(tree1.val!=tree2.val)return false;
// 此时就是:左右节点都不为空,且数值相同的情况
// 此时才做递归,做下一层的判断
boolean compareLeft = compare(tree1.left, tree2.left); // 左子树:左、 右子树:左
boolean compareRight = compare(tree1.right, tree2.right); // 左子树:右、 右子树:右
boolean isSame = compareLeft && compareRight; // 左子树:中、 右子树:中(逻辑处理)
return isSame;
}
boolean isSameTree(TreeNode p, TreeNode q) {
return compare(p, q);
}
}
```
257. 二叉树的所有路径: 回溯代码
```java
class Solution {
public void traversal(TreeNode cur, List<Integer> path, List<String> result) {
path.add(cur.val);
// 这才到了叶子节点
if (cur.left == null && cur.right == null) {
String sPath="";
for (int i = 0; i < path.size() - 1; i++) {
sPath += ""+path.get(i);
sPath += "->";
}
sPath += path.get(path.size() - 1);
result.add(sPath);
return;
}
if (cur.left!=null) {
traversal(cur.left, path, result);
path.remove(path.size()-1); // 回溯
}
if (cur.right!=null) {
traversal(cur.right, path, result);
path.remove(path.size()-1); // 回溯
}
}
public List<String> binaryTreePaths(TreeNode root) {
List<String> result = new LinkedList<>();
List<Integer> path = new LinkedList<>();
if (root == null) return result;
traversal(root, path, result);
return result;
}
}
```
如下为精简之后的递归代码:(257. 二叉树的所有路径)
```java
class Solution {
public void traversal(TreeNode cur, String path, List<String> result) {
path += cur.val; // 中
if (cur.left == null && cur.right == null) {
result.add(path);
return;
}
if (cur.left!=null) traversal(cur.left, path + "->", result); // 左 回溯就隐藏在这里
if (cur.right!=null) traversal(cur.right, path + "->", result); // 右 回溯就隐藏在这里
}
public List<String> binaryTreePaths(TreeNode root) {
List<String> result = new LinkedList<>();
String path = "";
if (root == null) return result;
traversal(root, path, result);
return result;
}
}
```
Python

View File

@ -153,8 +153,91 @@ public:
Java
迭代法前序遍历代码如下:
```java
class Solution {
public List<Integer> preorderTraversal(TreeNode root) {
List<Integer> result = new LinkedList<>();
Stack<TreeNode> st = new Stack<>();
if (root != null) st.push(root);
while (!st.empty()) {
TreeNode node = st.peek();
if (node != null) {
st.pop(); // 将该节点弹出,避免重复操作,下面再将右中左节点添加到栈中
if (node.right!=null) st.push(node.right); // 添加右节点(空节点不入栈)
if (node.left!=null) st.push(node.left); // 添加左节点(空节点不入栈)
st.push(node); // 添加中节点
st.push(null); // 中节点访问过,但是还没有处理,加入空节点做为标记。
} else { // 只有遇到空节点的时候,才将下一个节点放进结果集
st.pop(); // 将空节点弹出
node = st.peek(); // 重新取出栈中元素
st.pop();
result.add(node.val); // 加入到结果集
}
}
return result;
}
}
```
迭代法中序遍历代码如下:
```java
class Solution {
public List<Integer> inorderTraversal(TreeNode root) {
List<Integer> result = new LinkedList<>();
Stack<TreeNode> st = new Stack<>();
if (root != null) st.push(root);
while (!st.empty()) {
TreeNode node = st.peek();
if (node != null) {
st.pop(); // 将该节点弹出,避免重复操作,下面再将右中左节点添加到栈中
if (node.right!=null) st.push(node.right); // 添加右节点(空节点不入栈)
st.push(node); // 添加中节点
st.push(null); // 中节点访问过,但是还没有处理,加入空节点做为标记。
if (node.left!=null) st.push(node.left); // 添加左节点(空节点不入栈)
} else { // 只有遇到空节点的时候,才将下一个节点放进结果集
st.pop(); // 将空节点弹出
node = st.peek(); // 重新取出栈中元素
st.pop();
result.add(node.val); // 加入到结果集
}
}
return result;
}
}
```
迭代法后序遍历代码如下:
```java
class Solution {
public List<Integer> postorderTraversal(TreeNode root) {
List<Integer> result = new LinkedList<>();
Stack<TreeNode> st = new Stack<>();
if (root != null) st.push(root);
while (!st.empty()) {
TreeNode node = st.peek();
if (node != null) {
st.pop(); // 将该节点弹出,避免重复操作,下面再将右中左节点添加到栈中
st.push(node); // 添加中节点
st.push(null); // 中节点访问过,但是还没有处理,加入空节点做为标记。
if (node.right!=null) st.push(node.right); // 添加右节点(空节点不入栈)
if (node.left!=null) st.push(node.left); // 添加左节点(空节点不入栈)
} else { // 只有遇到空节点的时候,才将下一个节点放进结果集
st.pop(); // 将空节点弹出
node = st.peek(); // 重新取出栈中元素
st.pop();
result.add(node.val); // 加入到结果集
}
}
return result;
}
}
```
Python

View File

@ -160,11 +160,239 @@ Java
Python
```python3
# 前序遍历-迭代-LC144_二叉树的前序遍历
class Solution:
def preorderTraversal(self, root: TreeNode) -> List[int]:
# 根结点为空则返回空列表
if not root:
return []
stack = [root]
result = []
while stack:
node = stack.pop()
# 中结点先处理
result.append(node.val)
# 右孩子先入栈
if node.right:
stack.append(node.right)
# 左孩子后入栈
if node.left:
stack.append(node.left)
return result
# 中序遍历-迭代-LC94_二叉树的中序遍历
class Solution:
def inorderTraversal(self, root: TreeNode) -> List[int]:
if not root:
return []
stack = [] # 不能提前将root结点加入stack中
result = []
cur = root
while cur or stack:
# 先迭代访问最底层的左子树结点
if cur:
stack.append(cur)
cur = cur.left
# 到达最左结点后处理栈顶结点
else:
cur = stack.pop()
result.append(cur.val)
# 取栈顶元素右结点
cur = cur.right
return result
# 后序遍历-迭代-LC145_二叉树的后序遍历
class Solution:
def postorderTraversal(self, root: TreeNode) -> List[int]:
if not root:
return []
stack = [root]
result = []
while stack:
node = stack.pop()
# 中结点先处理
result.append(node.val)
# 左孩子先入栈
if node.left:
stack.append(node.left)
# 右孩子后入栈
if node.right:
stack.append(node.right)
# 将最终的数组翻转
return result[::-1]
```
Go
> 迭代法前序遍历
```go
//迭代法前序遍历
/**
type Element struct {
// 元素保管的值
Value interface{}
// 内含隐藏或非导出字段
}
func (l *List) Back() *Element
前序遍历:中左右
压栈顺序:右左中
**/
func preorderTraversal(root *TreeNode) []int {
if root == nil {
return nil
}
var stack = list.New()
stack.PushBack(root.Right)
stack.PushBack(root.Left)
res:=[]int{}
res=append(res,root.Val)
for stack.Len()>0 {
e:=stack.Back()
stack.Remove(e)
node := e.Value.(*TreeNode)//e是Element类型其值为e.Value.由于Value为接口所以要断言
if node==nil{
continue
}
res=append(res,node.Val)
stack.PushBack(node.Right)
stack.PushBack(node.Left)
}
return res
}
```
> 迭代法后序遍历
```go
//迭代法后序遍历
//后续遍历:左右中
//压栈顺序:中右左(按照前序遍历思路),再反转结果数组
func postorderTraversal(root *TreeNode) []int {
if root == nil {
return nil
}
var stack = list.New()
stack.PushBack(root.Left)
stack.PushBack(root.Right)
res:=[]int{}
res=append(res,root.Val)
for stack.Len()>0 {
e:=stack.Back()
stack.Remove(e)
node := e.Value.(*TreeNode)//e是Element类型其值为e.Value.由于Value为接口所以要断言
if node==nil{
continue
}
res=append(res,node.Val)
stack.PushBack(node.Left)
stack.PushBack(node.Right)
}
for i:=0;i<len(res)/2;i++{
res[i],res[len(res)-i-1] = res[len(res)-i-1],res[i]
}
return res
}
```
> 迭代法中序遍历
```go
//迭代法中序遍历
func inorderTraversal(root *TreeNode) []int {
rootRes:=[]int{}
if root==nil{
return nil
}
stack:=list.New()
node:=root
//先将所有左节点找到,加入栈中
for node!=nil{
stack.PushBack(node)
node=node.Left
}
//其次对栈中的每个节点先弹出加入到结果集中,再找到该节点的右节点的所有左节点加入栈中
for stack.Len()>0{
e:=stack.Back()
node:=e.Value.(*TreeNode)
stack.Remove(e)
//找到该节点的右节点,再搜索他的所有左节点加入栈中
rootRes=append(rootRes,node.Val)
node=node.Right
for node!=nil{
stack.PushBack(node)
node=node.Left
}
}
return rootRes
}
```
javaScript
```js
前序遍历:
// 入栈 右 -> 左
// 出栈 中 -> 左 -> 右
var preorderTraversal = function(root, res = []) {
if(!root) return res;
const stack = [root];
let cur = null;
while(stack.length) {
cur = stack.pop();
res.push(cur.val);
cur.right && stack.push(cur.right);
cur.left && stack.push(cur.left);
}
return res;
};
中序遍历:
// 入栈 左 -> 右
// 出栈 左 -> 中 -> 右
var inorderTraversal = function(root, res = []) {
const stack = [];
let cur = root;
while(stack.length || cur) {
if(cur) {
stack.push(cur);
// 左
cur = cur.left;
} else {
// --> 弹出 中
cur = stack.pop();
res.push(cur.val);
// 右
cur = cur.right;
}
};
return res;
};
后序遍历:
// 入栈 左 -> 右
// 出栈 中 -> 右 -> 左 结果翻转
var postorderTraversal = function(root, res = []) {
if (!root) return res;
const stack = [root];
let cur = null;
do {
cur = stack.pop();
res.push(cur.val);
cur.left && stack.push(cur.left);
cur.right && stack.push(cur.right);
} while(stack.length);
return res.reverse();
};
```
-----------------------

View File

@ -272,6 +272,41 @@ func PostorderTraversal(root *TreeNode) (res []int) {
}
```
javaScript:
```js
前序遍历:
var preorderTraversal = function(root, res = []) {
if (!root) return res;
res.push(root.val);
preorderTraversal(root.left, res)
preorderTraversal(root.right, res)
return res;
};
中序遍历:
var inorderTraversal = function(root, res = []) {
if (!root) return res;
inorderTraversal(root.left, res);
res.push(root.val);
inorderTraversal(root.right, res);
return res;
};
后序遍历:
var postorderTraversal = function(root, res = []) {
if (!root) return res;
postorderTraversal(root.left, res);
postorderTraversal(root.right, res);
res.push(root.val);
return res;
};
```