目录
144. 二叉树的前序遍历 Binary-tree Preorder Traversal 🌟
145. 二叉树的前序遍历 Binary-tree Postorder Traversal 🌟
对比: 94. 二叉树的中序遍历 Binary-tree Inorder Traversal 🌟
146. LRU缓存 LRU Cache 🌟🌟
🌟 每日一练刷题专栏 🌟
Golang每日一练 专栏
Python每日一练 专栏
C/C++每日一练 专栏
Java每日一练 专栏
二叉树专题(9)第146题除外
给你二叉树的根节点 root ,返回它节点值的 前序 遍历。
示例 1:
输入:root = [1,null,2,3] 输出:[1,2,3]
示例 2:
输入:root = [] 输出:[]
示例 3:
输入:root = [1] 输出:[1]
示例 4:
输入:root = [1,2] 输出:[1,2]
示例 5:
输入:root = [1,null,2] 输出:[1,2]
提示:
进阶:递归算法很简单,你可以通过迭代算法完成吗?
公用的示例二叉树:
3 / \ 9 20 / \ 15 7
遍历结果:
前序遍历 preorder = [3,9,20,15,7] 中序遍历 inorder = [9,3,15,20,7] 后序遍历 postorder = [9,15,7,20,3]
代码1: 递归
package main import ( "fmt" ) const null = -1 << 31 type TreeNode struct { Val int Left *TreeNode Right *TreeNode } func preorderTraversal(root *TreeNode) []int { var res []int preorder(root, &res) return res } func preorder(root *TreeNode, res *[]int) { if root == nil { return } *res = append(*res, root.Val) preorder(root.Left, res) preorder(root.Right, res) } func buildTree(nums []int) *TreeNode { if len(nums) == 0 { return nil } root := &TreeNode{Val: nums[0]} Queue := []*TreeNode{root} idx := 1 for idx < len(nums) { node := Queue[0] Queue = Queue[1:] if nums[idx] != null { node.Left = &TreeNode{Val: nums[idx]} Queue = append(Queue, node.Left) } idx++ if idx < len(nums) && nums[idx] != null { node.Right = &TreeNode{Val: nums[idx]} Queue = append(Queue, node.Right) } idx++ } return root } func ArrayToString(arr []int) string { res := "[" for i := 0; i < len(arr); i++ { res += fmt.Sprint(arr[i]) if i != len(arr)-1 { res += "," } } return res + "]" } func main() { nums := []int{1, null, 2, 3} root := buildTree(nums) fmt.Println(ArrayToString(preorderTraversal(root))) nums = []int{3, 9, 20, null, null, 15, 7} root = buildTree(nums) fmt.Println(ArrayToString(preorderTraversal(root))) }
代码2: 迭代
package main import ( "fmt" ) const null = -1 << 31 type TreeNode struct { Val int Left *TreeNode Right *TreeNode } func preorderTraversal(root *TreeNode) []int { var res []int if root == nil { return res } stack := []*TreeNode{} stack = append(stack, root) for len(stack) > 0 { cur := stack[len(stack)-1] stack = stack[:len(stack)-1] res = append(res, cur.Val) if cur.Right != nil { stack = append(stack, cur.Right) } if cur.Left != nil { stack = append(stack, cur.Left) } } return res } func buildTree(nums []int) *TreeNode { if len(nums) == 0 { return nil } root := &TreeNode{Val: nums[0]} Queue := []*TreeNode{root} idx := 1 for idx < len(nums) { node := Queue[0] Queue = Queue[1:] if nums[idx] != null { node.Left = &TreeNode{Val: nums[idx]} Queue = append(Queue, node.Left) } idx++ if idx < len(nums) && nums[idx] != null { node.Right = &TreeNode{Val: nums[idx]} Queue = append(Queue, node.Right) } idx++ } return root } func ArrayToString(arr []int) string { res := "[" for i := 0; i < len(arr); i++ { res += fmt.Sprint(arr[i]) if i != len(arr)-1 { res += "," } } return res + "]" } func main() { nums := []int{1, null, 2, 3} root := buildTree(nums) fmt.Println(ArrayToString(preorderTraversal(root))) nums = []int{3, 9, 20, null, null, 15, 7} root = buildTree(nums) fmt.Println(ArrayToString(preorderTraversal(root))) }
输出:
[1,2,3]
[3,9,20,15,7]
给你一棵二叉树的根节点 root ,返回其节点值的 后序遍历 。
示例 1:
输入:root = [1,null,2,3] 输出:[3,2,1]
示例 2:
输入:root = [] 输出:[]
示例 3:
输入:root = [1] 输出:[1]
提示:
进阶:递归算法很简单,你可以通过迭代算法完成吗?
代码1: 递归
package main import ( "fmt" ) const null = -1 << 31 type TreeNode struct { Val int Left *TreeNode Right *TreeNode } func postorderTraversal(root *TreeNode) []int { var res []int postorder(root, &res) return res } func postorder(root *TreeNode, res *[]int) { if root == nil { return } postorder(root.Left, res) postorder(root.Right, res) *res = append(*res, root.Val) } func buildTree(nums []int) *TreeNode { if len(nums) == 0 { return nil } root := &TreeNode{Val: nums[0]} Queue := []*TreeNode{root} idx := 1 for idx < len(nums) { node := Queue[0] Queue = Queue[1:] if nums[idx] != null { node.Left = &TreeNode{Val: nums[idx]} Queue = append(Queue, node.Left) } idx++ if idx < len(nums) && nums[idx] != null { node.Right = &TreeNode{Val: nums[idx]} Queue = append(Queue, node.Right) } idx++ } return root } func ArrayToString(arr []int) string { res := "[" for i := 0; i < len(arr); i++ { res += fmt.Sprint(arr[i]) if i != len(arr)-1 { res += "," } } return res + "]" } func main() { nums := []int{1, null, 2, 3} root := buildTree(nums) fmt.Println(ArrayToString(postorderTraversal(root))) nums = []int{3, 9, 20, null, null, 15, 7} root = buildTree(nums) fmt.Println(ArrayToString(postorderTraversal(root))) }
代码2: 迭代
package main import ( "fmt" ) const null = -1 << 31 type TreeNode struct { Val int Left *TreeNode Right *TreeNode } func postorderTraversal(root *TreeNode) []int { var res []int if root == nil { return res } stack := []*TreeNode{} stack = append(stack, root) for len(stack) > 0 { cur := stack[len(stack)-1] stack = stack[:len(stack)-1] res = append([]int{cur.Val}, res...) if cur.Left != nil { stack = append(stack, cur.Left) } if cur.Right != nil { stack = append(stack, cur.Right) } } return res } func buildTree(nums []int) *TreeNode { if len(nums) == 0 { return nil } root := &TreeNode{Val: nums[0]} Queue := []*TreeNode{root} idx := 1 for idx < len(nums) { node := Queue[0] Queue = Queue[1:] if nums[idx] != null { node.Left = &TreeNode{Val: nums[idx]} Queue = append(Queue, node.Left) } idx++ if idx < len(nums) && nums[idx] != null { node.Right = &TreeNode{Val: nums[idx]} Queue = append(Queue, node.Right) } idx++ } return root } func ArrayToString(arr []int) string { res := "[" for i := 0; i < len(arr); i++ { res += fmt.Sprint(arr[i]) if i != len(arr)-1 { res += "," } } return res + "]" } func main() { nums := []int{1, null, 2, 3} root := buildTree(nums) fmt.Println(ArrayToString(postorderTraversal(root))) nums = []int{3, 9, 20, null, null, 15, 7} root = buildTree(nums) fmt.Println(ArrayToString(postorderTraversal(root))) }
输出:
[3,2,1]
[9,15,7,20,3]
给定一个二叉树的根节点 root ,返回 它的 中序 遍历 。
示例 1:
输入:root = [1,null,2,3] 输出:[1,3,2]
示例 2:
输入:root = [] 输出:[]
示例 3:
输入:root = [1] 输出:[1]
提示:
进阶: 递归算法很简单,你可以通过迭代算法完成吗?
代码1: 递归法
package main import ( "fmt" ) const null = -1 << 31 type TreeNode struct { Val int Left *TreeNode Right *TreeNode } func inorderTraversal(root *TreeNode) []int { var res []int inorder(root, &res) return res } func inorder(root *TreeNode, res *[]int) { if root == nil { return } inorder(root.Left, res) *res = append(*res, root.Val) inorder(root.Right, res) } func buildTree(nums []int) *TreeNode { if len(nums) == 0 { return nil } root := &TreeNode{Val: nums[0]} Queue := []*TreeNode{root} idx := 1 for idx < len(nums) { node := Queue[0] Queue = Queue[1:] if nums[idx] != null { node.Left = &TreeNode{Val: nums[idx]} Queue = append(Queue, node.Left) } idx++ if idx < len(nums) && nums[idx] != null { node.Right = &TreeNode{Val: nums[idx]} Queue = append(Queue, node.Right) } idx++ } return root } func ArrayToString(arr []int) string { res := "[" for i := 0; i < len(arr); i++ { res += fmt.Sprint(arr[i]) if i != len(arr)-1 { res += "," } } return res + "]" } func main() { nums := []int{1, null, 2, 3} root := buildTree(nums) fmt.Println(ArrayToString(inorderTraversal(root))) nums = []int{3, 9, 20, null, null, 15, 7} root = buildTree(nums) fmt.Println(ArrayToString(inorderTraversal(root))) }
代码2: 迭代法
package main import ( "fmt" ) const null = -1 << 31 type TreeNode struct { Val int Left *TreeNode Right *TreeNode } func inorderTraversal(root *TreeNode) []int { var res []int stack := []*TreeNode{} cur := root for cur != nil || len(stack) > 0 { for cur != nil { stack = append(stack, cur) cur = cur.Left } cur = stack[len(stack)-1] stack = stack[:len(stack)-1] res = append(res, cur.Val) cur = cur.Right } return res } func buildTree(nums []int) *TreeNode { if len(nums) == 0 { return nil } root := &TreeNode{Val: nums[0]} Queue := []*TreeNode{root} idx := 1 for idx < len(nums) { node := Queue[0] Queue = Queue[1:] if nums[idx] != null { node.Left = &TreeNode{Val: nums[idx]} Queue = append(Queue, node.Left) } idx++ if idx < len(nums) && nums[idx] != null { node.Right = &TreeNode{Val: nums[idx]} Queue = append(Queue, node.Right) } idx++ } return root } func ArrayToString(arr []int) string { res := "[" for i := 0; i < len(arr); i++ { res += fmt.Sprint(arr[i]) if i != len(arr)-1 { res += "," } } return res + "]" } func main() { nums := []int{1, null, 2, 3} root := buildTree(nums) fmt.Println(ArrayToString(inorderTraversal(root))) nums = []int{3, 9, 20, null, null, 15, 7} root = buildTree(nums) fmt.Println(ArrayToString(inorderTraversal(root))) }
输出:
[1,3,2] [9,3,15,20,7]
“根左右、左根右、左右根”
func preorder(root *TreeNode, res *[]int) { *res = append(*res, root.Val) preorder(root.Left, res) preorder(root.Right, res) } func inorder(root *TreeNode, res *[]int) { inorder(root.Left, res) *res = append(*res, root.Val) inorder(root.Right, res) } func postorder(root *TreeNode, res *[]int) { postorder(root.Left, res) postorder(root.Right, res) *res = append(*res, root.Val) }
注意左、右子节点的压栈顺序,以及后序结果中的“追加”实为“前插”
func preorderTraversal(root *TreeNode) []int { var res []int if root == nil { return res } stack := []*TreeNode{} stack = append(stack, root) for len(stack) > 0 { cur := stack[len(stack)-1] stack = stack[:len(stack)-1] res = append(res, cur.Val) if cur.Right != nil { stack = append(stack, cur.Right) } if cur.Left != nil { stack = append(stack, cur.Left) } } return res } func inorderTraversal(root *TreeNode) []int { var res []int stack := []*TreeNode{} cur := root for cur != nil || len(stack) > 0 { for cur != nil { stack = append(stack, cur) cur = cur.Left } cur = stack[len(stack)-1] stack = stack[:len(stack)-1] res = append(res, cur.Val) cur = cur.Right } return res } func postorderTraversal(root *Treecur) []int { var res []int if root == nil { return res } stack := []*Treecur{} stack = append(stack, root) for len(stack) > 0 { cur := stack[len(stack)-1] stack = stack[:len(stack)-1] res = append([]int{cur.Val}, res...) if cur.Left != nil { stack = append(stack, cur.Left) } if cur.Right != nil { stack = append(stack, cur.Right) } } return res }
请你设计并实现一个满足 LRU (最近最少使用) 缓存 约束的数据结构。
实现 LRUCache 类:
函数 get 和 put 必须以 O(1) 的平均时间复杂度运行。
示例:
输入 ["LRUCache", "put", "put", "get", "put", "get", "put", "get", "get", "get"] [[2], [1, 1], [2, 2], [1], [3, 3], [2], [4, 4], [1], [3], [4]] 输出 [null, null, null, 1, null, -1, null, -1, 3, 4] 解释 LRUCache lRUCache = new LRUCache(2); lRUCache.put(1, 1); // 缓存是 {1=1} lRUCache.put(2, 2); // 缓存是 {1=1, 2=2} lRUCache.get(1); // 返回 1 lRUCache.put(3, 3); // 该操作会使得关键字 2 作废,缓存是 {1=1, 3=3} lRUCache.get(2); // 返回 -1 (未找到) lRUCache.put(4, 4); // 该操作会使得关键字 1 作废,缓存是 {4=4, 3=3} lRUCache.get(1); // 返回 -1 (未找到) lRUCache.get(3); // 返回 3 lRUCache.get(4); // 返回 4
提示:
代码:
type LRUCache struct { capacity int cache map[int]*list.Element list *list.List } type pair struct { key int value int } func Constructor(capacity int) LRUCache { return LRUCache{ capacity: capacity, cache: make(map[int]*list.Element), list: list.New(), } } func (c *LRUCache) Get(key int) int { if elem, ok := c.cache[key]; ok { c.list.MoveToFront(elem) return elem.Value.(*pair).value } return -1 } func (c *LRUCache) Put(key int, value int) { if elem, ok := c.cache[key]; ok { elem.Value.(*pair).value = value c.list.MoveToFront(elem) } else { if c.list.Len() == c.capacity { // remove the least recently used element tailElem := c.list.Back() delete(c.cache, tailElem.Value.(*pair).key) c.list.Remove(tailElem) } // insert new element to front newElem := c.list.PushFront(&pair{key, value}) c.cache[key] = newElem } }
输出:
略
✨ 持续,努力奋斗做强刷题搬运工!
👍 点赞,你的认可是我坚持的动力!
🌟 收藏,你的青睐是我努力的方向!
✎ 评论,你的意见是我进步的财富!
☸ 主页:https://hannyang.blog.csdn.net/
Golang每日一练 专栏 | |
Python每日一练 专栏 | |
C/C++每日一练 专栏 | |
Java每日一练 专栏 |