双指针,平衡二叉树与最小生成树

news/2024/10/4 14:20:54 标签: 算法, python, 数据结构

1:直方图的水量

题目链接:面试题 17.21. 直方图的水量 - 力扣(LeetCode)

双指针

  1. 初始化:我们使用两个指针 left 和 right 分别指向数组的开始和结束。同时,我们记录下这两个位置的高度,即 max_left 和 max_right

  2. 遍历数组:我们使用一个 while 循环来遍历整个数组,直到 left 和 right 相遇。在每次循环中,我们比较 left 和 right 位置的柱子高度。

  3. 处理较矮的柱子

    • 如果 left 位置的柱子高度小于 right 位置的柱子高度,我们检查 left 位置的柱子高度是否大于或等于 max_left。如果是,我们更新 max_left;如果不是,那么 left 位置的柱子与 max_left 之间的差距就是可以存储的水量。然后,我们将 left 指针向右移动一位。
    • 如果 right 位置的柱子高度小于或等于 left 位置的柱子高度,我们执行类似的操作,但针对 right 位置的柱子。
  4. 计算水量:在每次循环中,我们计算较矮柱子与它对应的最大高度之间的差距,并将这个差距累加到 water 变量中。

  5. 结束条件:当 left 和 right 相遇时,循环结束。

这个算法的关键在于,我们总是从两边向中间遍历,并确保在每次比较中,我们都有当前方向上的最大高度。这样,我们就可以确保在移动指针时正确地计算水量。因为我们是从两边向中间移动,所以每个位置只被访问一次,这使得算法的时间复杂度为 O(n)。

python">def trap(height):
    if not height:
        return 0

    left, right = 0, len(height) - 1
    max_left, max_right = height[left], height[right]
    water = 0

    while left < right:
        if height[left] < height[right]:
            if height[left] >= max_left:
                max_left = height[left]
            else:
                water += max_left - height[left]
            left += 1
        else:
            if height[right] >= max_right:
                max_right = height[right]
            else:
                water += max_right - height[right]
            right -= 1

    return water

a = list(map(int, input().split()))
print(trap(a))

2:平衡二叉树

题目链接:LCR 176. 判断是否为平衡二叉树 - 力扣(LeetCode)

平衡二叉树的定义是:对于树中的任意一个节点,其左右子树的高度差不超过1。以下是一个判断二叉树是否为平衡二叉树的Python代码实现:

python">class TreeNode:
    def __init__(self, val=0, left=None, right=None):
        self.val = val
        self.left = left
        self.right = right

def list_to_tree(lst):
    if not lst:
        return None
    root = TreeNode(lst[0])
    queue = [root]
    i = 1
    while queue and i < len(lst):
        current = queue.pop(0)
        if i < len(lst) and lst[i] is not None:
            current.left = TreeNode(lst[i])
            queue.append(current.left)
        i += 1
        if i < len(lst) and lst[i] is not None:
            current.right = TreeNode(lst[i])
            queue.append(current.right)
        i += 1
    return root

def isBalanced(root):
    def check_balance(node):
        if not node:
            return 0, True
        left_height, left_balanced = check_balance(node.left)
        right_height, right_balanced = check_balance(node.right)
        balanced = left_balanced and right_balanced and abs(left_height - right_height) <= 1
        height = max(left_height, right_height) + 1
        return height, balanced
    _, is_tree_balanced = check_balance(root)
    return is_tree_balanced

# 用户输入处理
user_input = input()
root = list_to_tree(input_tree)
print(isBalanced(root))

这段代码中的 list_to_tree 函数负责将列表转换为二叉树结构。它使用广度优先搜索(BFS)的方法来遍历列表,并构建相应的树节点。然后,isBalanced 函数会检查这个树是否是平衡的。

3:最小生成树(Prim算法

题目链接:1584. 连接所有点的最小费用 - 力扣(LeetCode)

这个问题可以通过使用Prim算法或者Kruskal算法来解决,这两种算法都是用来寻找最小生成树的经典算法。最小生成树是指在一个加权无向图中,包含图中全部顶点的、权值之和最小的树形结构。

对于这个问题,我们可以按以下步骤实现Prim算法

  1. 创建一个数组,用来记录每个点到最小生成树的最短距离。
  2. 初始化这个数组,将除了起点外的所有点的距离设置为无穷大。
  3. 创建一个最小堆(优先队列),将所有点按照到最小生成树的距离排序。
  4. 依次从堆中取出距离最小的点,并将其连接到最小生成树中,同时更新其他点到最小生成树的距离。

现在,我将用Python代码来实现这个算法

python">import heapq

def minCostConnectPoints(points):
    # 计算两个点之间的曼哈顿距离
    def manhattan_distance(p1, p2):
        return abs(p1[0] - p2[0]) + abs(p1[1] - p2[1])

    n = len(points)
    # 初始化最小生成树距离数组,全部设置为无穷大
    min_span_tree = [float('inf')] * n
    # 从第一个点开始构建最小生成树
    min_span_tree[0] = 0
    # 创建一个最小堆,存储(距离, 点的索引)
    heap = [(0, 0)]
    total_cost = 0
    visited = [False] * n

    while heap:
        # 从堆中取出距离最小的点
        cost, idx = heapq.heappop(heap)
        if visited[idx]:
            continue
        # 将这个点加入最小生成树
        visited[idx] = True
        total_cost += cost
        # 更新其他点到最小生成树的距离
        for i in range(n):
            if not visited[i]:
                dist = manhattan_distance(points[idx], points[i])
                if dist < min_span_tree[i]:
                    min_span_tree[i] = dist
                    heapq.heappush(heap, (dist, i))

    return total_cost


http://www.niftyadmin.cn/n/5690018.html

相关文章

C++ STL 初探:打开标准模板库的大门

文章目录 C STL 初探&#xff1a;打开标准模板库的大门前言第一章: 什么是STL&#xff1f;1.1 标准模板库简介1.2 STL的历史背景1.3 STL的组成 第二章: STL的版本与演进2.1 不同的STL版本2.2 STL的影响与重要性 第三章: 为什么学习 STL&#xff1f;3.1 从手动编写到标准化解决方…

【C++】——list的介绍和模拟实现

P. S.&#xff1a;以下代码均在VS2019环境下测试&#xff0c;不代表所有编译器均可通过。 P. S.&#xff1a;测试代码均未展示头文件stdio.h的声明&#xff0c;使用时请自行添加。 博主主页&#xff1a;Yan. yan.                        …

Python酷库之旅-第三方库Pandas(133)

目录 一、用法精讲 596、pandas.DataFrame.plot.density方法 596-1、语法 596-2、参数 596-3、功能 596-4、返回值 596-5、说明 596-6、用法 596-6-1、数据准备 596-6-2、代码示例 596-6-3、结果输出 597、pandas.DataFrame.plot.hexbin方法 597-1、语法 597-2、…

【宽搜】1. 层序遍历模板讲解

题目描述 题目链接&#xff1a;N叉树的层序遍历 层序遍历流程 请仔细阅读下图&#xff1a; 根据上图的流程&#xff0c;下面再明确几个问题&#xff1a; 1. 为什么要使用队列&#xff1f; 队列是先进先出的数据结构&#xff0c;在数的层序遍历中&#xff0c;需要先将节点p…

Spring Boot新闻推荐系统设计与实现

3系统分析 3.1可行性分析 通过对本新闻推荐系统实行的目的初步调查和分析&#xff0c;提出可行性方案并对其一一进行论证。我们在这里主要从技术可行性、经济可行性、操作可行性等方面进行分析。 3.1.1技术可行性 本新闻推荐系统采用JAVA作为开发语言&#xff0c;Spring Boot框…

IPsec手动方式

文章目录 实验要求实验配置 实验要求 配置 IPsec vpn 采用手动方式同时要满足上网和VPN两种需求使用NAT进行地址映射认证方法和加密算法自行配置采用安全的方法 实验配置 R1&#xff1a; #基本配置sy sy R1 dhcp enable acl 2000 rule permit sour 192.168.1.0 0.0.0.255 int…

【一文理解】conda install pip install 区别

大部分情况下&#xff0c;conda install & pip install 二者安装的package都可以正常work&#xff0c;但是混装多种package后容易版本冲突&#xff0c;出现各种报错。 目录 检查机制 支持语言 库的位置 环境隔离 编译情况 检查机制 conda有严格的检查机制&#xff0c…

SpringMVC2~~~

数据格式化 提交数据(比如表单)&#xff0c;对提交的数据进行转换和处理 基本数据类型可以和字符串自动转换 <a href"<%request.getContextPath()%>/addMonsterUI">添加妖怪</a> Controller Scope(value "prototype") public class …