Java 中的线段树2025年5月12日 | 阅读 8 分钟 线段树也是一种二叉树,但它用于以更好的时间复杂度解决特定问题。与堆类似,Java 中的线段树也通过数组来表示。 使用线段树的场景让我们来了解一下线段树在哪些场景下非常有用。 假设我们有一个数组 a[] = {0, 1, …, n - 1};并且需要在此数组上执行两项任务。这些任务是:
让我们讨论解决上述任务的各种方法。 朴素方法完成这些任务很容易。我们可以从索引 x 到 y 运行一个 for 循环,并计算位于索引 x 到 y 之间的元素之和。如果我们分析求和的时间复杂度,我们将得到 O(n) 时间。 另外,要更新第 j 个索引的值,可以执行 a[j] = p,此操作需要 O(1) 时间。因此,完成这两项任务的总时间复杂度为 O(n) + O(1) = O(n)。 另一种方法另一种方法是提前创建一个前缀数组,然后完成上述任务。创建前缀数组后,从索引 x 到 y 的元素之和需要 O(1) 时间。但是,第 j 个索引的更新将需要 O(n) 时间。这是因为任何索引的更新都会影响前缀数组,而更新需要 O(1) 时间。因此,总时间复杂度为 O(1) + O(n) = O(n),与朴素方法相同。 由于这两种方法的总体时间复杂度保持不变,因此我们需要找到一种方法来降低其时间复杂度,而这种方法就是使用线段树。线段树需要 O(log(n)) 时间来计算从索引 x 到 y 的和。对于第 j 个索引处值的更新,线段树需要 O(log(n)) 时间。因此,总体时间复杂度变为 O(log(n)) + O(log(n)) = O(2 *(log(n))),这小于 O(n)。 线段树的表示
因此,对于数组 a[] = {2, 4, 7, 10, 12, 13},线段树在数组中的表示将是 segArr[] = {48, 13, 35, 6, 7, 22, 13, 2, 4, k, k, 10, 12, k, k},其中 k 是虚拟值。虚拟值没有用。事实上,由于数组表示,这会浪费一些空间。 线段树将是 ![]() 红色节点(叶子节点)代表数组中的元素,而橙色节点是合并其子节点的结果。 线段树表示中数组的大小如果输入数组的大小是 2 的幂,则没有虚拟节点。因此,线段树的大小为 (2 * n - 1),其中 n 是输入数组的大小。这是因为叶子节点的总数为 s,内部节点为 n - 1。因此,n + n - 1 = 2 * n - 1 是数组的总大小。 如果输入数组的大小不是 2 的幂,则线段树的大小为 2 * y - 1,其中 y 是大于 n 的最小的 2 的幂。例如,如果 n 的值为 9,则大于 9 的最小的 2 的幂是 16。所以 y 是 16。 给定范围求和的伪代码构建线段树后,挑战在于使用线段树计算和。以下伪代码解决了这个问题。 更新线段树中的值线段树中的更新操作是递归完成的。假设需要更新第 j 个索引,值为 val。从线段树的根开始,将值 val 添加到其范围包含给定范围的所有节点中。如果给定节点的范围不包含给定索引,则不应对该节点进行任何更改。 线段树的实现下面的程序展示了线段树的实现。 文件名:SegTree.java 输出 Sum of values in the given range 1 to 4 = 33 Updated sum of values in the given range = 34 下一主题交通灯程序(Java) |
计算所有 1 的子矩阵是编程中一个常见的问题,它涉及到在一个给定的二进制矩阵(仅包含 0 和 1)中找到所有元素都是 1 的子矩阵的数量。这个问题广泛应用于图像处理、数据分析等领域...
14 分钟阅读
在 Java 编程中,在字符串内交换字符是一项常见操作,涉及重新排列单个字符以达到所需的顺序。此过程在各种场景中都很重要,例如数据加密、算法转换或增强 Java 应用程序中的字符串操作功能。让我们探索各种 Java 方法……
阅读 8 分钟
字符串的回文分割意味着将给定字符串分成若干部分,使得从给定字符串形成的所有子字符串本身都是回文。在 Java 的回文分割问题中,我们返回使每个部分都成为回文所需的最小分割次数...
7 分钟阅读
合并两个已排序的链表是学习算法时必须解决的基本问题之一。这是一个将两个已排序列表合并的过程,合并后,结果列表仍然保持已排序状态。这个问题通常作为一项编码挑战出现...
5 分钟阅读
Java 中面向对象编程的基本单位是类。它们使我们能够指定对象的组成和操作。类的静态实例是 Java 中的一个关键概念。类的单个实例,该实例由该类的所有对象共享...
5 分钟阅读
由相同数字非平凡地组成的偶数称为 Zygodrome。这意味着如果相同的数字总是成对地出现在数字中,那么该数字就称为 Zygodrome。Zyg 是一个希腊词,意思是联合或...
5 分钟阅读
在本节中,我们将学习什么是 Peterson 数,以及如何通过 Java 程序检查给定的数字是否为 Peterson 数。Peterson 数 如果一个数字的每个数字的阶乘之和等于该数字本身,则称该数字为 Peterson 数...
阅读 2 分钟
是 Java 中可用的按位运算符之一。XOR(又名异或)接受两个布尔操作数,如果它们不同则返回 true。XOR 运算符的最佳用例是当两个给定的布尔条件不能同时为真时....
5 分钟阅读
在编程世界中,null 值长期以来一直是令人沮丧的根源,导致 NullPointerException 导致应用程序崩溃并产生意外行为。为了解决这个问题,Java 在 Java 8 中引入了 Optional 类,提供了一个容器类型,该类型包含一个非 null...
阅读 4 分钟
Java 中的字符串是字符序列,可以使用数组进行反转。反转字符串意味着以相反的顺序重新排列字符串中的字符。本文将探讨使用数组在 Java 中反转文本的各种技术。方法...
5 分钟阅读
我们请求您订阅我们的新闻通讯以获取最新更新。
我们提供所有技术(如 Java 教程、Android、Java 框架)的教程和面试问题
G-13, 2nd Floor, Sec-3, Noida, UP, 201301, India