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] ). 搜索一个给定的目标值, ...
随机推荐
- python unittest TestCase间共享数据(全局变量的使用)
文章目录 1.setupclass里设置self.xxx变量,不同用例之间无法实时共享参数变动 2.setupclass里设置globals().["xxx"]变量,不同用例之间可 ...
- post请求导出表单。
postExcelFile(params, url) { //params是post请求需要的参数,url是请求url地址 var form = document.createElement(&quo ...
- Docker之镜像地址
转载自https://www.cnblogs.com/doraman/p/9570891.html 官方docker hub 官方:https://hub.docker.com/explore/ 常用 ...
- json 格式要求
json 格式中, 字符串类型需要使用双引号,不能为单引号
- context的简单应用
数据上传 context.setAttribute protected void doGet(HttpServletRequest req, HttpServletResponse resp) thr ...
- 9.1 Go 反射
9.1 Go 反射 反射:可以在运行时,动态获取变量的信息,比如变量的类型,类别 1.对于结构体变量,还可以获取到结构体的字段,方法 2.实现这个功能的是 reflect包 reflect.TypeO ...
- form提交(图片,excel其他文件)
HTML表单需要设置enctype="multipart/form-data"这个属性,如果不这么设置,在提交表单时候,相关文件将无法获取. HTML表单如何打包数据文件是由enc ...
- ftp服务器搭建(二)
1.已经安装好了vsftpd 进入到根目录下的/etc目录 ls查看一下 2.拷贝一下上面的两个配置文件 我拷贝到了我新建的目录中了 3.查看现在的网络连接方式——我的是-net方式 当然其他方式也 ...
- python的性能测试(timeit)
import timeit def test(): lista = [] listb = [] for i in range(100): lista.append(i) for i in range( ...
- [自动化-脚本]002.cocos2dx-lua lua代码windows加密批处理
在开发软件的时候,我们都会在项目上线时候对代码进行加密,用来防止被不法分子盗走牟利.不同的语言有不同的加密方式,比较出名的有加壳,代码混淆等.在Lua开发cocos2dx的时候,框架会有提供加密的脚本 ...