zoukankan      html  css  js  c++  java
  • LeetCode——区域和检索-数组可修改

    Q:给定一个整数数组  nums,求出数组从索引 i 到 j  (i ≤ j) 范围内元素的总和,包含 i,  j 两点。
    update(i, val) 函数可以通过将下标为 i 的数值更新为 val,从而对数列进行修改。

    示例:
    Given nums = [1, 3, 5]
    sumRange(0, 2) -> 9
    update(1, 2) //把3改成2
    sumRange(0, 2) -> 8
    说明:
    数组仅可以在 update 函数下进行修改。
    你可以假设 update 函数与 sumRange 函数的调用次数是均匀分布的。

    A:
    使用线索树。
    线索树介绍:线段树是一种平衡二叉搜索树(完全二叉树),他将一个线段区间划分成一些单元区间。对于线段树中的每个非叶子节点 [a,b],他的左儿子表示的区间为 [ a, (a+b)/2] ,右儿子表示的区间为 [(a+b)/2+1, b] , 最后的叶子节点数目为 N, 与数组下标对应。
    线段树的一般包括建立、查询、插入、更新等操作,建立规模为 N 的时间复杂度是 O(nlogn),其他操作时间复杂度为O(logn)。

    class NumArray {
        class SegmentTreeNode {
            SegmentTreeNode lchild;
            SegmentTreeNode rchild;
            int left;
            int right;
            int val;
    
            SegmentTreeNode(int left, int right) {
                this.left = left;
                this.right = right;
                this.val = 0;
                this.lchild = null;
                this.rchild = null;
            }
        }
    
        private SegmentTreeNode root = null;
    
        NumArray(int[] nums) {
            root = buildSegmentTree(nums, 0, nums.length - 1);
        }
    
        private SegmentTreeNode buildSegmentTree(int[] nums, int left, int right) {
            if (left > right)
                return null;
            SegmentTreeNode root = new SegmentTreeNode(left, right);
            if (left == right)
                root.val = nums[left];
            else {
                int mid = (left + right) / 2;
                root.lchild = buildSegmentTree(nums, left, mid);
                root.rchild = buildSegmentTree(nums, mid + 1, right);
                root.val = root.rchild.val + root.lchild.val;
            }
            return root;
        }
    
        public void update(int i, int val) {
            update(root, i, val);
        }
    
        private void update(SegmentTreeNode root, int pos, int val) {
            if (root.left == root.right)
                root.val = val;
            else {
                int mid = (root.left + root.right) / 2;
                if (pos <= mid)
                    update(root.lchild, pos, val);
                else
                    update(root.rchild, pos, val);
                root.val = root.lchild.val + root.rchild.val;
            }
        }
    
        public int sumRange(int i, int j) {
            return sumRange(root, i, j);
        }
    
        private int sumRange(SegmentTreeNode root, int left, int right) {
            if (root.right == right && root.left == left)
                return root.val;
            else {
                int mid = (root.left + root.right) / 2;
                if (left >= mid + 1) {
                    return sumRange(root.rchild, left, right);
                } else if (right <= mid) {
                    return sumRange(root.lchild, left, right);
                } else
                    return sumRange(root.rchild, mid + 1, right) + sumRange(root.lchild, left, mid);
            }
        }
    }
    
  • 相关阅读:
    关于input输入框placeholder属性的样式问题
    关于input输入框checkbox类型的样式问题
    三层构架
    盒模型
    line height
    sql
    继承
    对象
    正则表达式
    事件
  • 原文地址:https://www.cnblogs.com/xym4869/p/12562979.html
Copyright © 2011-2022 走看看