目录
一、滑动窗口最大值
题目:滑动窗口最大值
思路:这道题思路比较奇特,大家可能第一步想到的思路就是对目前中窗口的值进行从小到达排序,然后再移动窗口,但是这种方式会超出时间限制。
看别人的思路是写的是,弄一个单调双向队列,自己来实现。具体功能就是,在Push操作时,要保证新加入的这个元素前面没有比它还小的元素,如果有则从队列后方出队列。Pop操作时,看弹出的元素是否为当前队列队首元素,否则不用操作。这个逻辑是这么个逻辑,具体它为什么这样是对的,需要自己脑补一下具体的滑动过程。
type myQueue struct {
queue []int
}
func NewQueue() *myQueue {
return &myQueue{[]int{}}
}
func (q *myQueue)pop(val int) {
if len(q.queue) > 0 && val == q.queue[0] {
q.queue = q.queue[1:]
}
}
func (q *myQueue)push(val int) {
length := len(q.queue)
for length > 0 && val > q.queue[length - 1] {
q.queue = q.queue[:length-1]
length--
}
q.queue = append(q.queue,val)
}
func maxSlidingWindow(nums []int, k int) []int {
i:=0
q := NewQueue()
for ;i<k;i++ {
q.push(nums[i])
}
res := make([]int,0)
res = append(res,q.queue[0])
for ;i<len(nums);i++ {
q.pop(nums[i-k])
q.push(nums[i])
res = append(res,q.queue[0])
}
return res
}
二、二叉树遍历
二叉树前中后序列的递归和非递归遍历
链接:
递归遍历:
这个比较简单
递归前序:
/**
* Definition for a binary tree node.
* type TreeNode struct {
* Val int
* Left *TreeNode
* Right *TreeNode
* }
*/
func preorderTraversal(root *TreeNode) []int {
res := make([]int,0)
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)
}
递归中序:
/**
* Definition for a binary tree node.
* type TreeNode struct {
* Val int
* Left *TreeNode
* Right *TreeNode
* }
*/
func inorderTraversal(root *TreeNode) []int {
res := make([]int,0)
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)
}
递归后序:
/**
* Definition for a binary tree node.
* type TreeNode struct {
* Val int
* Left *TreeNode
* Right *TreeNode
* }
*/
func postorderTraversal(root *TreeNode) []int {
res := make([]int,0)
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 preorderTraversal(root *TreeNode) []int {
if root == nil {
return []int{}
}
stack := make([]*TreeNode,0)
res := make([]int,0)
stack = append(stack,root)
//res = append(res,root.Val)
for len(stack) > 0 {
ptr := stack[len(stack)-1]
stack = stack[:len(stack)-1]
res = append(res,ptr.Val)
//这样的话弹出来就是先访问左子树了
if ptr.Right != nil {
stack = append(stack,ptr.Right)
}
if ptr.Left != nil {
stack = append(stack,ptr.Left)
}
}
return res
}
非递归后序:
func postorderTraversal(root *TreeNode) []int {
if root == nil {
return []int{}
}
stack := make([]*TreeNode,0)
res := make([]int,0)
stack = append(stack,root)
//res = append(res,root.Val)
for len(stack) > 0 {
ptr := stack[len(stack)-1]
stack = stack[:len(stack)-1]
res = append(res,ptr.Val)
//采用中右左的策略进行遍历
//注意这里是栈,所以是先进栈的反而后访问
if ptr.Left != nil {
stack = append(stack,ptr.Left)
}
if ptr.Right != nil {
stack = append(stack,ptr.Right)
}
}
//之后进行逆序,得到的是左右中
reverse(res)
return res
}
func reverse(a []int) {
l, r := 0, len(a) - 1
for l < r {
a[l], a[r] = a[r], a[l]
l, r = l+1, r-1
}
}
非递归中序:
中序比较特殊,和前序、后序不太一样
func inorderTraversal(root *TreeNode) []int {
if root == nil {
return []int{}
}
res := make([]int,0)
statck := make([]*TreeNode,0)
cur := root
for cur != nil || len(statck) > 0 {
//只要有左子树,就一直往左边走
if cur != nil {
statck = append(statck,cur)
cur = cur.Left
} else {
//没有了,则开始访问当前节点,并往右走一个
cur = statck[len(statck) - 1]
statck = statck[:len(statck) - 1]
res = append(res, cur.Val)
cur = cur.Right
}
}
return res
}
层次遍历:
func levelOrder(root *TreeNode) [][]int {
if root == nil {
return [][]int{}
}
ress := make([][]int,0)
// queue := make([]*TreeNode,0)
// queue = append(queue,root)
queue := list.New()
queue.PushBack(root)
num := 0//记录下一层有多少个节点
pre := 1//记录当前遍历的层有多少节点
res := make([]int,0)
for queue.Len() > 0 {
//从队列头部拿东西
ptr := queue.Remove(queue.Front()).(*TreeNode)
res = append(res,ptr.Val)
//当前层所剩个数减少
pre--
if ptr.Left != nil {
queue.PushBack(ptr.Left)
num++
}
if ptr.Right != nil {
queue.PushBack(ptr.Right)
num++
}
if pre == 0 {
ress = append(ress,res)
res = make([]int,0)
pre = num
num = 0
}
}
return ress
}