22年39周

目录

一、滑动窗口最大值

 二、二叉树遍历

递归遍历:这个比较简单

递归前序:

递归中序:

递归后序:

非递归遍历:

非递归前序:

非递归后序:

非递归中序:

层次遍历:


一、滑动窗口最大值

题目:滑动窗口最大值

思路:这道题思路比较奇特,大家可能第一步想到的思路就是对目前中窗口的值进行从小到达排序,然后再移动窗口,但是这种方式会超出时间限制。
看别人的思路是写的是,弄一个单调双向队列,自己来实现。具体功能就是,在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
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
美国大学生数学建模竞赛(MCM/ICM)每都会提供一系列问题供参赛者选择,其中C题是其中之一。在过去的22间,C题的数据包涵盖了各种不同的主题和问题,涉及了许多领域和学科。 这些数据包通常包含有关特定问题领域的相关背景知识,例如物理、经济、生态学、社会学等。它们提供了关于问题的具体细节,包括问题的定义、目标、约束条件和可能的解决方案。此外,数据包还提供了用于解答问题的数据集、图表、公式和模型。 数据包还可能包括问题所需的附加信息和参考资料,例如研究论文、统计数据、实验结果等。这些信息有助于参赛者理解问题的背景和前沿研究,并为他们提供可能的研究方向和方法。 参赛者需要通过综合分析、建模和求解这些数据包中提供的问题,来提出全面、合理和创新的解决方案。他们可以使用各种数学和统计方法、计算机编程和模拟技术,以及其他相关的学科知识来解答问题。 这些数据包在美赛中扮演着至关重要的角色,它们帮助参赛者深入理解问题、准确建立模型、有效选择策略,并最终提出可行的解决方案。通过解答这些问题,参赛者能够培养团队合作、创新思维、问题解决和技术推理等关键能力,提升他们在数学建模领域的技能和竞争力。 总之,22的美赛C题数据包提供了各种复杂和多样的问题,涵盖了多个学科和领域。它们为参赛者提供了建模和解决问题的机会,同时也促使他们发展和提升各类关键能力。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值