Java实现 LeetCode 307 区域和检索 - 数组可修改
307. 区域和检索 - 数组可修改
给定一个整数数组 nums,求出数组从索引 i 到 j (i ≤ j) 范围内元素的总和,包含 i, j 两点。
update(i, val) 函数可以通过将下标为 i 的数值更新为 val,从而对数列进行修改。
示例:
Given nums = [1, 3, 5]
sumRange(0, 2) -> 9
update(1, 2)
sumRange(0, 2) -> 8
说明:
数组仅可以在 update 函数下进行修改。
你可以假设 update 函数与 sumRange 函数的调用次数是均匀分布的。
PS:
线段树
import java.util.function.*;
public class NumArray{
private SegmentTree<Integer> segTree;
public NumArray(int[] nums) {
if (nums.length>0) {
Integer[] data=new Integer[nums.length];
for (int i=0;i<nums.length;i++) {
data[i]=nums[i];
}
segTree = new SegmentTree<Integer>(data,(a,b)->a+b);
}
}
public void update(int i, int val) {
segTree.update(i,val);
}
public int sumRange(int i, int j) {
return segTree.searchRange(i,j);
}
}
class SegmentTree<E>{
private E[] data;
private E[] tree;
private BiFunction<E,E,E> function;
public SegmentTree(E[] arr,BiFunction<E,E,E> function){
data = (E[]) new Object[arr.length];
this.function=function;
System.arraycopy(arr,0,data,0,arr.length);
tree = (E[]) new Object[4*arr.length];
buildSegmentTree(0,0,arr.length-1);
}
//根据传入的BiFuction构建线段树
private void buildSegmentTree(int index,int left,int right){
if (left==right) {
tree[index] =data[right];
return;
}
int leftIndex=leftChild(index);
int rightIndex=rightChild(index);
int mid=left+(right-left)/2;
buildSegmentTree(leftIndex,left,mid);
buildSegmentTree(rightIndex,mid+1,right);
//区间数据和,根据业务需求来
tree[index]=function.apply(tree[leftIndex],tree[rightIndex]);
}
//范围搜索
public E searchRange(int left,int right){
return searchRange(0,0,data.length-1,left,right);
}
private E searchRange(int rootIndex,int left,int right,int targetLeft,int targetRight){
if (targetLeft == left && targetRight == right) {
return tree[rootIndex];
}
int mid=left+(right-left)/2;
if (targetLeft>mid) {
return searchRange(rightChild(rootIndex),mid+1,right,targetLeft,targetRight);
}
if (targetRight<=mid) {
return searchRange(leftChild(rootIndex),left,mid,targetLeft,targetRight);
}
return function.apply(searchRange(leftChild(rootIndex),left,mid,targetLeft,mid),searchRange(rightChild(rootIndex),mid+1,right,mid+1,targetRight));
}
public void update(int index,E e){
if (index<0 || index>=data.length) {
throw new IllegalArgumentException("index illegal");
}
update(0,0,data.length-1,index,e);
}
public void update(int rootIndex,int left,int right,int targetIndex,E e){
if (left == right) {
tree[rootIndex]=e;
return;
}
int mid=left+(right-left)/2;
if (targetIndex<=mid) {
update(leftChild(rootIndex),left,mid,targetIndex,e);
}else{
update(rightChild(rootIndex),mid+1,right,targetIndex,e);
}
tree[rootIndex]=function.apply(tree[leftChild(rootIndex)],tree[rightChild(rootIndex)]);
}
//左孩子
private int leftChild(int index){
return index*2+1;
}
//右孩子
private int rightChild(int index){
return index*2+2;
}
}
Java实现 LeetCode 307 区域和检索 - 数组可修改的更多相关文章
- LeetCode 307. 区域和检索 - 数组可修改
地址 https://leetcode-cn.com/problems/range-sum-query-mutable/ 题目描述给定一个整数数组 nums,求出数组从索引 i 到 j (i ≤ ...
- Java实现 LeetCode 303 区域和检索 - 数组不可变
303. 区域和检索 - 数组不可变 给定一个整数数组 nums,求出数组从索引 i 到 j (i ≤ j) 范围内元素的总和,包含 i, j 两点. 示例: 给定 nums = [-2, 0, 3, ...
- [Leetcode] 第307题 区域和检索-数组可修改
参考博客:(LeetCode 307) Range Sum Query - Mutable(Segment Tree) 一.题目描述 给定一个整数数组 nums,求出数组从索引 i 到 j (i ...
- [Swift]LeetCode307. 区域和检索 - 数组可修改 | Range Sum Query - Mutable
Given an integer array nums, find the sum of the elements between indices i and j (i ≤ j), inclusive ...
- LeetCode:区域和检索【303】
LeetCode:区域和检索[303] 题目描述 给定一个整数数组 nums,求出数组从索引 i 到 j (i ≤ j) 范围内元素的总和,包含 i, j 两点. 示例: 给定 nums = [ ...
- [Leetcode]303.区域和检索&&304.二维区域和检索
题目 1.区域和检索: 简单题,前缀和方法 乍一看就觉得应该用前缀和来做,一个数组多次查询. 实现方法: 新建一个private数组prefix_sum[i],用来存储nums前i个数组的和, 需要找 ...
- 【leetcode 简单】 第七十九题 区域和检索 - 数组不可变
给定一个整数数组 nums,求出数组从索引 i 到 j (i ≤ j) 范围内元素的总和,包含 i, j 两点. 示例: 给定 nums = [-2, 0, 3, -5, 2, -1],求和函数 ...
- [Swift]LeetCode303. 区域和检索 - 数组不可变 | Range Sum Query - Immutable
Given an integer array nums, find the sum of the elements between indices i and j (i ≤ j), inclusive ...
- Java实现 LeetCode 33 搜索旋转排序数组
33. 搜索旋转排序数组 假设按照升序排序的数组在预先未知的某个点上进行了旋转. ( 例如,数组 [0,1,2,4,5,6,7] 可能变为 [4,5,6,7,0,1,2] ). 搜索一个给定的目标值, ...
随机推荐
- 新抽象语法树(AST)给 PHP7 带来的变化
本文大部分内容参照 AST 的 RFC 文档而成:https://wiki.php.net/rfc/abstract_syntax_tree,为了易于理解从源文档中节选部分进行介绍. 我的官方群点击此 ...
- 在ef core中使用postgres数据库的全文检索功能实战
起源 之前做的很多项目都使用solr/elasticsearch作为全文检索引擎,它们功能全面而强大,但是对于较小的项目而言,构建和维护成本显然过高,尤其是从关系数据库/文档数据库到全文检索引擎的数据 ...
- Windows系统目录
文件功能 编辑 ├—WINDOWS │ ├—system32(存放Windows的系统文件和硬件驱动程序) │ │ ├—config(用户配置信息和密码信息) │ │ │ └—systemprofil ...
- HttpPoolUtils 连接池管理的GET POST请求
package com.nextjoy.projects.usercenter.util.http; import org.apache.http.Consts; import org.apache. ...
- ArrayList详解-源码分析
ArrayList详解-源码分析 1. 概述 在平时的开发中,用到最多的集合应该就是ArrayList了,本篇文章将结合源代码来学习ArrayList. ArrayList是基于数组实现的集合列表 支 ...
- react-debug
最近练习react的时候遇到一些问题: 在redux模式下,同一个api依据参数获取不同data的时候,返回的data相同 原因:多次调用该接口时,action的type相同,导致对应于该接口的每个r ...
- MySQL索引及查询优化
mysql 索引 1.索引介绍 索引按数据结构分可分为哈希表,有序数组,搜索树,跳表: 哈希表适用于只有等值查询的场景 有序数组适用于有等值查询和范围查询的场景,但有序数组索引的更新代价很大,所以最好 ...
- 5.1 Go函数定义
1 Go函数定义 Go函数是指:一段具有独立功能的代码,然后可以在程序中其他地方多次调用. Go分为自定义函数,系统函数. 函数可以将一个大的工作拆解成小的任务. 函数对用户隐藏了细节. Golang ...
- 3.2 Go整数类型
1. Go整数类型 Go语言的数值类型包含不同大小的整数型.浮点数和负数,每种数值类型都有大小范围以及正负符号. 官方文档解释数据类型 int类型中哪些支持负数 有符号(负号):int8 int16 ...
- 201771010128王玉兰《面向对象程序设计(Java)》第十三周学习总结
第一部分:基础理论知识 1.事件处理基础 事件源(event source):能够产生事件的对象都可 以成为事件源,如文本框.按钮等.一个事件源是一个 能够注册监听器并向监听器发送事件对象的对象. 事 ...