You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于数组的两类查询:区间三角形最大周长计算与元素更新

数组区间三角形最大周长查询与单点更新问题解决方案

嘿,我来帮你梳理这个问题的解法。我们的核心需求是处理一个数值数组,支持两种操作:一是查询指定区间内能构成三角形的三边的最大周长,二是更新数组中的某个元素值。先从你给出的示例入手,再展开讲高效的实现思路。

示例场景回顾

初始数组:a[] = [3, 1, 8, 9, 7]
4次操作流程:

  1. 区间查询(1,5):

    这个区间覆盖了整个数组,元素是3、1、8、9、7。要找最大周长的三角形,优先看最大的几个数——8、9、7,它们满足三角形三边条件(任意两边之和大于第三边),所以周长是8+9+7=24,返回24。

  2. 单点更新:把索引2的元素改成12(这里要注意是1-based索引,对应0-based的话是索引1),更新后数组变成a[] = [3, 12, 8, 9, 7]。
  3. 再次区间查询:

    现在最大的三个数是12、9、8,检查12 < 9+8(17),满足条件,所以周长是12+9+8=29,这就是当前的最大周长。

  4. (你可以继续补充后续操作,比如再更新某个元素或者查询其他区间)

核心思路:为什么只需要关注最大的几个元素?

三角形的最大周长一定来自区间内最大的、能满足三边条件的三个数。道理很简单:假设我们有三个数x ≥ y ≥ z,如果x < y + z,那它们的和就是最大的可能周长,因为任何其他组合的和都不会超过x+y+z;如果这三个不满足,那更小的数组合的和只会更小,也没必要再看了。

实现方案选择

根据你的数据规模和操作频率,有两种方案可选:

  • 简单方案(小数据/少操作):每次查询时直接提取区间元素,排序后从后往前验证三边条件。这种方法写起来快,但效率低——查询时间复杂度是O(n log n),更新是O(1)。
  • 高效方案(大数据/多操作):用线段树来存储每个区间的前3大元素。这样查询时可以快速合并区间的前3大元素,更新时也只需修改对应节点的信息,查询和更新的时间复杂度都是O(log n),非常适合高频操作的场景。

高效方案的具体实现(Python示例)

下面是线段树的实现代码,每个节点保存对应区间的前3大元素:

class SegmentTreeNode:
    def __init__(self, start, end):
        self.start = start
        self.end = end
        self.left = None
        self.right = None
        self.top3 = []  # 降序存储区间内最大的3个元素

def build_segment_tree(arr, start, end):
    node = SegmentTreeNode(start, end)
    if start == end:
        node.top3 = [arr[start]]
        return node
    mid = (start + end) // 2
    node.left = build_segment_tree(arr, start, mid)
    node.right = build_segment_tree(arr, mid + 1, end)
    # 合并左右子节点的top3,取最大的3个
    merged = sorted(node.left.top3 + node.right.top3, reverse=True)
    node.top3 = merged[:3]
    return node

def update_node(node, idx, val):
    if node.start == node.end == idx:
        node.top3 = [val]
        return
    mid = (node.start + node.end) // 2
    if idx <= mid:
        update_node(node.left, idx, val)
    else:
        update_node(node.right, idx, val)
    # 更新当前节点的top3
    merged = sorted(node.left.top3 + node.right.top3, reverse=True)
    node.top3 = merged[:3]

def query_range(node, l, r):
    if node.end < l or node.start > r:
        return []
    if l <= node.start and node.end <= r:
        return node.top3.copy()
    left_top = query_range(node.left, l, r)
    right_top = query_range(node.right, l, r)
    merged = sorted(left_top + right_top, reverse=True)
    return merged[:3]

def calculate_max_perimeter(top3_list):
    sorted_nums = sorted(top3_list, reverse=True)
    if len(sorted_nums) < 3:
        return -1  # 无法构成三角形的标识
    # 先验证最大的三个数
    if sorted_nums[0] < sorted_nums[1] + sorted_nums[2]:
        return sum(sorted_nums[:3])
    # 若前三个不满足,说明区间内没有能构成三角形的三元组
    return -1

# 示例使用
original_arr = [3, 1, 8, 9, 7]
root = build_segment_tree(original_arr, 0, len(original_arr)-1)

# 第一次查询整个区间(对应示例的(1,5),1-based转0-based是0-4)
top3 = query_range(root, 0, 4)
print(calculate_max_perimeter(top3))  # 输出24

# 更新1-based索引2的元素为12(对应0-based索引1)
update_node(root, 1, 12)
top3_updated = query_range(root, 0, 4)
print(calculate_max_perimeter(top3_updated))  # 输出29

注意点

  • 索引问题:一定要区分清楚题目中是1-based还是0-based索引,代码里用的是0-based,实际使用时要对应调整。
  • 边界情况:如果区间内元素不足3个,或者所有三元组都不满足三边条件,记得返回一个明确的标识(比如代码里的-1),表示无法构成三角形。

内容的提问来源于stack exchange,提问作者John Simmons

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 08:51:43