算法:树状数组

server/2024/9/23 20:38:51/

文章目录

      • 面试题 10.10. 数字流的秩
      • 327. 区间和的个数
      • 315. 计算右侧小于当前元素的个数

树状数组可以理解一种数的存储格式。
在这里插入图片描述

面试题 10.10. 数字流的秩

假设你正在读取一串整数。每隔一段时间,你希望能找出数字 x 的秩(小于或等于 x 的值的个数)。
请实现数据结构和算法来支持这些操作,也就是说:
实现 track(int x) 方法,每读入一个数字都会调用该方法;
实现 getRankOfNumber(int x) 方法,返回小于或等于 x 的值的个数。

面试题 10.10. 数字流的秩

class StreamRank {vector<int> v;int lowbit(int x) {return x & -x;}
public:StreamRank(): v(50002, 0) {}void track(int x) {++x; //x + 1是因为树状数组处理的元素下标从1开始while (x <= 50001) {v[x]++;x += lowbit(x);}}int getRankOfNumber(int x) {++x;int ans = 0;while (x) {ans += v[x];x -= lowbit(x);}return ans;}
};
class StreamRank:def __init__(self):self.l = [0]*50002def lowBit(self, x):return x & (-x)def track(self, x: int) -> None:x += 1while x <= 50001:self.l[x] += 1x += self.lowBit(x)def getRankOfNumber(self, x: int) -> int:x += 1ans = 0while x:ans += self.l[x]x -= self.lowBit(x)return ans

327. 区间和的个数

给你一个整数数组 nums 以及两个整数 lower 和 upper 。求数组中,值位于范围 [lower, upper] (包含 lower 和 upper)之内的 区间和的个数 。
区间和 S(i, j) 表示在 nums 中,位置从 i 到 j 的元素之和,包含 i 和 j (i ≤ j)。

327. 区间和的个数
区间过大,hash,然后到树状数组

class Solution:def countRangeSum(self, nums, lower: int, upper: int) -> int:n = len(nums)prefixs = [0]*nt = 0ans = 0for i in range(n):t += nums[i]prefixs[i] = tif lower<= t<= upper:ans += 1s = set()for i in range(n):s.add(prefixs[i])s.add(prefixs[i]-lower)s.add(prefixs[i] - upper)l = sorted(s)d = {x: i+1 for i, x in enumerate(l)}  # hash到固定长度trie = [0]*(len(d)+1)  # 树状数组for i in range(n):left, right = d[prefixs[i]-upper], d[prefixs[i]-lower]ans += self.query(trie, right) - self.query(trie, left-1)self.insert(trie, d[prefixs[i]])return ansdef query(self, trie, x):ans = 0while x:ans += trie[x]x -= x & (-x)return ansdef insert(self, trie, x):while x < len(trie):trie[x] += 1x += x & (-x)

315. 计算右侧小于当前元素的个数

给你一个整数数组 nums ,按要求返回一个新数组 counts 。数组 counts 有该性质: counts[i] 的值是 nums[i] 右侧小于 nums[i] 的元素的数量。

315. 计算右侧小于当前元素的个数

class Solution:def countSmaller(self, nums: List[int]) -> List[int]:n = len(nums)l = [0]*20002 # -10000~10000 -> 2~20002 因为求小于x的值,x=2,count输入x=1ans = [0]*nfor i in range(n-1,-1,-1):x = nums[i] + 10002ans[i] = self.count(l, x-1)self.insert(l, x)return ansdef count(self, l, x):ans = 0while x:ans += l[x]x -= self.lowBit(x)return ansdef lowBit(self, x):return x & (-x)def insert(self, l, x):while x < len(l):l[x] += 1x += self.lowBit(x)

算法学习笔记(2) : 树状数组


http://www.ppmy.cn/server/42913.html

相关文章

非整数倍数据位宽转换24to128

描述 实现数据位宽转换电路&#xff0c;实现24bit数据输入转换为128bit数据输出。其中&#xff0c;先到的数据应置于输出的高bit位。 电路的接口如下图所示。valid_in用来指示数据输入data_in的有效性&#xff0c;valid_out用来指示数据输出data_out的有效性&#xff1b;clk是时…

SkyWalking 介绍及部署

1、SkyWalking简介2、SkyWalking的搭建 2.1 部署Elasticsearch2.2 部署SkyWalking-Server2.3 部署SkyWalking-UI3、应用接入 3.1 jar包部署方式3.2 dockerfile方式3.3 DockerFile示例4、SkyWalking UI 界面说明 4.1 仪表盘 4.1.1 APM &#xff08;1&#xff09;全局维度&#x…

每日一题(4)——String连接,替换,比较,查找等

主要是一些字符串的连接&#xff0c; 替换&#xff0c;比较&#xff0c;去首尾空格&#xff0c;查找等操作&#xff1b; class ZiFu{public static void main(String []args){String s1"hello world";String s2new String("hello,world");s2" "…

Struts2 3万字经典面试题及参考答案

目录 解释Struts2是什么以及它的主要组成部分。 Struts2与Struts1相比有哪些改进?

ARM/Linux嵌入式面经真题(十):浙江大华

大华 嵌入式 二面 一面-电话面试, 1.static 关键词ARM/Linux嵌入式面经(五):联想 可见这是个热点面试题 2.数据链表一步一步教你从零开始写C语言链表(超详细) 照着这个撸一遍,不重复造轮子了。很详细,然后务必打开评论区,有易错点!!! 3.项目里的一个线程管理的问题 这…

二叉树的序列化---广义表

前言 个人小记 一、代码 #include<stdio.h> #include <stdlib.h> #include <string.h> #include <time.h> #define key(n) (n)?(n->key):(-1) #define MAX_NODE 10typedef struct Node {int key;struct Node* lchild,*rchild; }Node;Node* init_…

常见的cdn运维面试题及答案

1、请简要介绍一下CDN的基本原理和作用。 CDN&#xff08;Content Delivery Network&#xff0c;内容分发网络&#xff09;是一种分布式网络服务&#xff0c;通过在地理位置分布广泛的节点上缓存网站静态资源&#xff08;如图片、视频、CSS、JS等&#xff09;&#xff0c;使用…

设计模式--备忘录模式

备忘录模式是一种行为设计模式&#xff0c;它用于在不破坏封装的前提下&#xff0c;保存一个对象的内部状态&#xff0c;以便以后可以恢复到这个状态。这种模式在许多应用场景中非常有用&#xff0c;例如在实现撤销操作、保存游戏进度、恢复文件备份以及保持工作状态等。 备忘…