LeetCode50天刷题计划第二季(Day 14 — 填充每个节点的下一个右侧节点指针II(12.30-13.00)三角形最小路径和(13.10-13.40)

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


前言

第一次体验深度专注

一、题目

填充每个节点的下一个右侧节点指针 II

给定一个二叉树

struct Node {
int val;
Node *left;
Node *right;
Node *next;
}
填充它的每个 next 指针,让这个指针指向其下一个右侧节点。如果找不到下一个右侧节点,则将 next 指针设置为 NULL。

初始状态下,所有 next 指针都被设置为 NULL。

进阶

你只能使用常量级额外空间。
使用递归解题也符合要求,本题中递归程序占用的栈空间不算做额外的空间复杂度。

示例

输入:root = [1,2,3,4,5,null,7]
输出:[1,#,2,3,#,4,5,7,#]
解释:给定二叉树如图 A 所示,你的函数应该填充它的每个 next 指针,以指向其下一个右侧节点,如图 B 所示。序列化输出按层序遍历顺序(由 next 指针连接),‘#’ 表示每层的末尾。

提示

树中的节点数小于 6000
-100 <= node.val <= 100

二、思路

因为不规整了,所以建议用队列(层序遍历),但使用队列就不是常量级的额外空间了。
采用三个指针,一个指针遍历上层(假定上层的next指针已经改好),另外两个指针遍历当前层,用于修改next指针指向。
对于每一个上层父节点,依次遍历其左孩子和右孩子,然后移动上层指针即可。在此过程中需要不断记录和移动指向前面数值的指针。

三、代码

"""
# Definition for a Node.
class Node:
    def __init__(self, val: int = 0, left: 'Node' = None, right: 'Node' = None, next: 'Node' = None):
        self.val = val
        self.left = left
        self.right = right
        self.next = next
"""

class Solution:
    def connect(self, root: 'Node') -> 'Node':
        #因为不规整了,所以建议用队列(层序遍历),但使用队列就不是常量级的额外空间了
        #采用三个指针,一个指针遍历上层(假定上层的next指针已经改好),另外两个指针遍历当前层,用于修改next指针指向。
        father_root=root
        first=past=None #下层指针
        while (father_root != None):  
            if(father_root.left): #先看左孩子
                if(first == None): #如果首个还没找到
                    first=father_root.left #这个就是下层第一个
                    past=first #记录
                else: #首个已经有了,上一个肯定也有了
                    past.next=father_root.left
                    past=father_root.left #指针右移
            if(father_root.right):  #再看右孩子
                if(first == None): #如果首个还没找到
                    first=father_root.right #这个就是本层第一个
                    past=first #记录
                else: #首个已经有了,上一个肯定也有了
                    past.next=father_root.right
                    past=father_root.right #指针右移
            if(father_root.next !=None): #本层还有,就next
                father_root=father_root.next
            else: #本层没有,到下一层第一个
                father_root=first
                first=None #更新first
                past=None #记录遍历时的上一个指针 
        return root

在这里插入图片描述

四、题目

三角形最小路径和

给定一个三角形 triangle ,找出自顶向下的最小路径和。

每一步只能移动到下一行中相邻的结点上。相邻的结点 在这里指的是 下标 与 上一层结点下标 相同或者等于 上一层结点下标 + 1 的两个结点。也就是说,如果正位于当前行的下标 i ,那么下一步可以移动到下一行的下标 i 或 i + 1 。

示例

示例 1:
输入:triangle = [[2],[3,4],[6,5,7],[4,1,8,3]]
输出:11
解释:如下面简图所示:
2
3 4
6 5 7
4 1 8 3
自顶向下的最小路径和为 11(即,2 + 3 + 5 + 1 = 11)。

示例 2:
输入:triangle = [[-10]]
输出:-10

提示:

1 <= triangle.length <= 200
triangle[0].length == 1
triangle[i].length == triangle[i - 1].length + 1
-104 <= triangle[i][j] <= 104

进阶

你可以只使用 O(n) 的额外空间(n 为三角形的总行数)来解决这个问题吗?

五、思路

维持一个长度为n的列表,表示进行到第n行时,每个数字作为出口的最短路径和,最后找到列表最大值即可
注意在每层遍历时必须从后向前,否则就会覆盖住还有用的值

六、代码

class Solution:
    def minimumTotal(self, triangle: List[List[int]]) -> int:
        n=len(triangle)
        relist=[triangle[0][0]]+[None for i in range(n-1)]
        for i in range(1,n):
            for j in range(i,-1,-1): #必须从后往前更改
                if(j==0): #每行第一个 直接加上正上方元素
                    relist[j]+=triangle[i][j]
                elif(relist[j] == None): #每行最后一个,直接加上左上方元素
                    relist[j]=relist[j-1]+triangle[i][j]
                else: #正上方和左上方哪个小加哪个
                    relist[j]=min(relist[j-1],relist[j])+triangle[i][j]
        return min(relist)
                

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值