【LeetCode】剑指 Offer <二刷>(3)

目录

[题目:剑指 Offer 06. 从尾到头打印链表 - 力扣(LeetCode)](#题目:剑指 Offer 06. 从尾到头打印链表 - 力扣(LeetCode))

题目的接口:

解题思路:

代码:

过啦!!!

[题目:剑指 Offer 07. 重建二叉树 - 力扣(LeetCode)](#题目:剑指 Offer 07. 重建二叉树 - 力扣(LeetCode))

题目的接口:

解题思路:

代码:

过啦!!!

写在最后:


题目:剑指 Offer 06. 从尾到头打印链表 - 力扣(LeetCode)

题目的接口:

Go 复制代码
/**
 * Definition for singly-linked list.
 * type ListNode struct {
 *     Val int
 *     Next *ListNode
 * }
 */
func reversePrint(head *ListNode) []int {

}

解题思路:

这道题我读完之后想到了两种思路,1、直接从后往前去链表的值放进数组,但是这样既不好写,复杂度也非常的高,不推荐,

2、先将链表存进一个临时数组,再创建一个返回数组,将临时数组的值从后往前存进返回数组中,这样就实现了,来看代码:

Go 复制代码
/**
 * Definition for singly-linked list.
 * type ListNode struct {
 *     Val int
 *     Next *ListNode
 * }
 */
 
func reversePrint(head *ListNode) []int {
    r := make([]int, 0)
    for head != nil {
        r = append(r, head.Val)
        head = head.Next
    } 

    ans := make([]int, 0)
    i := len(r) - 1
    for i >= 0 {
        ans = append(ans, r[i])
        i--
    }

    return ans
}

不过做完这道题之后,我去翻看题解区,看到了一个大佬写了一个很妙的解法,就是利用递归的特性,用 append 函数将链表的值倒着连接成一个切片返回。

代码:

Go 复制代码
/**
 * Definition for singly-linked list.
 * type ListNode struct {
 *     Val int
 *     Next *ListNode
 * }
 */
func reversePrint(head *ListNode) []int {
    var f func(head *ListNode) []int 
    f = func(head *ListNode) []int {
        if head == nil {return []int{}}
        return append(f(head.Next), head.Val) 
    }
    return f(head)
}

过啦!!!

题目:剑指 Offer 07. 重建二叉树 - 力扣(LeetCode)

题目的接口:

Go 复制代码
/**
 * Definition for a binary tree node.
 * type TreeNode struct {
 *     Val int
 *     Left *TreeNode
 *     Right *TreeNode
 * }
 */
func buildTree(preorder []int, inorder []int) *TreeNode {

}

解题思路:

这种二叉树的题目一般也是有两种解法,一个递归一个迭代,递归比较简单,所以我们当然是先来递归,这里递归的核心思路就是根据题目给的前序和中序遍历找到这棵树的根节点,以及左右子树,具体思路如下:

前序的第一个值就是根节点,根据这个根节点我们就能找到中序遍历中的根节点位置,然后将中序数组分成左右子树两个部分,再根据中序左右子树的长度,我们就能找到前序数组左右字数的位置,再递归求解即可,代码如下:

Go 复制代码
/**
 * Definition for a binary tree node.
 * type TreeNode struct {
 *     Val int
 *     Left *TreeNode
 *     Right *TreeNode
 * }
 */
func buildTree(preorder []int, inorder []int) *TreeNode {
    for k := range inorder {
        if inorder[k] == preorder[0] {
            return &TreeNode {
                Val:   preorder[0],
                Left:  buildTree(preorder[1:k+1], inorder[0:k]),
                Right: buildTree(preorder[k+1:], inorder[k+1:]),
            } 
        }
    }
    return nil
}

递归求解还是相对简单的,比较有难度的就是迭代的解法,使用这个迭代法的核心思想就是:若这颗树是一颗只有左子树的树,相当于一条单链表 那中序遍历和先序遍历的结果是反过来的,利用这个特性,我们就能用栈来存储节点,到最左下的位置时,开始取栈中元素和中序数组匹配,如果遇到不相等的情况,证明这个不相等的值是右节点,代码思路如下:

代码:

Go 复制代码
/**
 * Definition for a binary tree node.
 * type TreeNode struct {
 *     Val int
 *     Left *TreeNode
 *     Right *TreeNode
 * }
 */
func buildTree(preorder []int, inorder []int) *TreeNode {
    if len(preorder) == 0 {return nil}

    root := &TreeNode{preorder[0], nil, nil}
    stack := []*TreeNode{}
    stack = append(stack, root)
    var inorderIndex int

    // 首先一直遍历到最左下的地方
    // 这里的意思就是一直找左子树,直到找不到
    for i := 1; i < len(preorder); i++ {
        preorderVal := preorder[i]
        node := stack[len(stack)-1]
        if node.Val != inorder[inorderIndex] {
            node.Left = &TreeNode{preorderVal, nil, nil} // 组装二叉树的左子树
            stack = append(stack, node.Left)
        } else { // 已经到了最左下的位置
            // 这里的逻辑是:不断出栈直到不匹配,而不匹配的那个节点就是右节点
            for len(stack) != 0 && stack[len(stack)-1].Val == inorder[inorderIndex] {
                node = stack[len(stack)-1]
                stack = stack[:len(stack)-1]
                inorderIndex++
            }
            // 将这个右子树的节点入栈
            // 也就是这个右子树将作为新的根节点,继续找他的左子树(重新上去走循环)
            node.Right = &TreeNode{preorderVal, nil, nil} // 组装二叉树的右子树
            stack = append(stack, node.Right)
        }
    }
    return root
}

过啦!!!

写在最后:

以上就是本篇文章的内容了,感谢你的阅读。

如果感到有所收获的话可以给博主点一个哦。

如果文章内容有遗漏或者错误的地方欢迎私信博主或者在评论区指出~

相关推荐
一切皆是因缘际会2 小时前
从概率拟合到内生心智:2026 下一代 AI 架构演进与落地实践
人工智能·深度学习·算法·架构
Java成神之路-2 小时前
【LeetCode 刷题笔记】34. 在排序数组中查找元素的第一个和最后一个位置 | 二分查找经典刷题题解
算法·leetcode
不忘不弃2 小时前
用BFS方法求解平分汽油问题
算法·宽度优先
AI科技星2 小时前
全域数学·72分册·射影原本 无穷维射影几何卷细化子目录【乖乖数学】
人工智能·线性代数·算法·机器学习·数学建模·数据挖掘·量子计算
风落无尘2 小时前
《智能重生:从垃圾堆到AI工程师》——第四章 变化的艺术
人工智能·线性代数·算法
JAVA面经实录9172 小时前
计算机基础(完整版·超详细可背诵)
java·linux·数据结构·算法
AC赳赳老秦2 小时前
知识产权辅助:用 OpenClaw 批量生成专利交底书 / 软著申请材料,自动校验格式与内容合规性
java·人工智能·python·算法·elasticsearch·deepseek·openclaw
WBluuue3 小时前
Codeforces 1093 Div2(ABCD1D2)
c++·算法
浅念-3 小时前
「一文吃透 BFS:从层序遍历到锯齿形、最大宽度、每层最大值」
数据结构·算法
汉克老师3 小时前
GESP5级C++考试语法知识(十三、贪心算法(一))
算法·贪心算法·海盗船·gesp5级·gesp五级·排队接水