美文网首页线段树
Java 算法-区间求和I(线段树)

Java 算法-区间求和I(线段树)

作者: 琼珶和予 | 来源:发表于2018-01-11 09:45 被阅读0次

  我之前学过线段树,掌握的不是很牢固,而这道题是线段树,为了加深记忆,所以还是觉得有必要记录下来,就当是对线段树的一个复习。

题意:
给定一个整数数组(下标由 0 到 n-1,其中 n 表示数组的规模),以及一个查
询列表。每一个查询列表有两个整数 [start, end] 。 对于每个查询,计算出数
组中从下标 start 到 end 之间的数的总和,并返回在结果列表中。
样例:
对于数组 [1,2,7,8,5],查询[(1,2),(0,4),(2,4)], 返回 [9,23,20]

1.解题思路

  这道题用线段树数做起来不是很难,同时时间复杂度也不是很高。由于楼主之前学过线段树,所以这里不再详细的讲解什么是线段树。
  我们在构建线段树时,向线段树的每一个节点加一个属性--sum,用来表示当前节点的范围的数值总和。然后在使用线段树的查询就可以得到我们想要的值了。

(1).构建线段树

private SegmentTreeNode build(int A[], int start ,int end) {
        SegmentTreeNode node = new SegmentTreeNode(start, end, A[0]);
        if(node.start == node.end) {
            node.sum = A[start];
            return node;
        }
        int mid = (node.start + node.end) / 2;
        node.left = build(A, start, mid);
        node.right = build(A, mid + 1, end);
        node.sum = node.left.sum + node.right.sum;
        return node;
    }

(2).查询线段树

private long query(SegmentTreeNode node, int start , int end) {
        if(start > end) {
            return 0;
        }
        if(node.start == start && node.end == end) {
            return node.sum;
        }
        int mid = (node.start + node.end) /  2;
        if(end <= mid) {
            return query(node.left, start, end);
        }
        else if(start > mid) {
            return query(node.right, start, end);
        }else {
            return query(node.left, start, mid) + query(node.right, mid + 1, end);
        }
    }

2.代码

public List<Long> intervalSum(int[] A, List<Interval> queries) {
        List<Long> list = new ArrayList<>();
        if(A.length == 0 || queries.size() == 0) {
            return list;
        }
        SegmentTreeNode node = build(A, 0, A.length - 1);
        
        for(int i = 0; i < queries.size(); i++) {
            list.add(query(node, queries.get(i).start, queries.get(i).end));
        }
        return list;
    }
    //构建线段树
    private SegmentTreeNode build(int A[], int start ,int end) {
        SegmentTreeNode node = new SegmentTreeNode(start, end, A[0]);
        if(node.start == node.end) {
            node.sum = A[start];
            return node;
        }
        int mid = (node.start + node.end) / 2;
        node.left = build(A, start, mid);
        node.right = build(A, mid + 1, end);
        node.sum = node.left.sum + node.right.sum;
        return node;
    }
    //查询线段树
    private long query(SegmentTreeNode node, int start , int end) {
        if(start > end) {
            return 0;
        }
        if(node.start == start && node.end == end) {
            return node.sum;
        }
        int mid = (node.start + node.end) / 2;
        if(end <= mid) {
            return query(node.left, start, mid);
        }
        else if(start > mid) {
            return query(node.right, start, end);
        }else {
            return query(node.left, start, mid) + query(node.right, mid + 1, end);
        }
    }

相关文章

  • Java 算法 - 约翰的生意(线段树)

    题意 样例 1.解题思路   这是一道非常典型的线段树题。之前我也做过类似的题,Java 算法-区间求和I(线段树...

  • Java 算法-区间求和I(线段树)

      我之前学过线段树,掌握的不是很牢固,而这道题是线段树,为了加深记忆,所以还是觉得有必要记录下来,就当是对线段树...

  • 线段树 + 树状数组 + ST表 模板

    线段树 区间修改+区间求和 logN 树状数组 区间求和+单点修改 logN ST表 离线查询区间最值 构造Nlo...

  • 线段树

    专题 B线段树求逆序对 C[] D 区间不同值求和

  • 10.线段树(比较高级的数据结构)

    一、线段树(区间树)的概念 Segment Tree;线段树属于高级数据结构,经常出现在算法竞赛中为什么要使用线段...

  • 线段树

    一、线段树建树、单点修改、区间查询 二、线段树建树、区间修改、区间查询

  • 算法模板(七) 线段树

    线段树单点操作 线段树区间操作

  • 数据结构-线段树

    线段树定义: 线段树是一种二叉搜索树,又叫区间树,它将一个区间划分成一些单元区间,每个单元区间对应线段树中的一个...

  • 线段树系列之——单点更新与区段总和

    线段树 线段树是一种二叉搜索树,与区间树相似,它将一个区间划分成一些单元区间,每个单元区间对应线段树中的一个叶结点...

  • 2019-03-26线段树

    线段树是一种二叉搜索树,与区间树相似,它将一个区间划分成一些单元区间,每个单元区间对应线段树中的一个叶结点。 线段...

网友评论

    本文标题:Java 算法-区间求和I(线段树)

    本文链接:https://www.haomeiwen.com/subject/askznxtx.html