Skip to content

Commit e1441d2

Browse files
authored
Update Readme.md
1 parent 7df9ff3 commit e1441d2

File tree

1 file changed

+8
-2
lines changed
  • Segment_Tree/3721.Longest-Balanced-Subarray-II

1 file changed

+8
-2
lines changed

Segment_Tree/3721.Longest-Balanced-Subarray-II/Readme.md

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,12 @@
22

33
既然是求区间,那么不妨考虑“前缀之差”。根据经验,我们需要记录每个前缀里“unique even numbers与unique odd numbers的个数之差”。任何两个差相同的前缀,意味着一个符合条件的区间,即“unique even numbers与unique odd numbers的个数相等”。
44

5-
对于一个nums[0:i]的前缀,如何表达“unique even numbers与unique odd numbers的个数之差”呢?我们只需要关心每个unique number最后一次出现的位置。记作lastPos[x]。比如偶数4最后一次出现在了a这个位置,那么我们就记录array[a]=1;假设奇数7最后一次出现在了b这个位置,那么我们就记录array[b]=-1.可见,只要计算这个01数组array[0:i]的前缀和,就可以知道nums[0:i]里“unique even numbers与unique odd numbers的个数之差”。
5+
对于一个nums[0:i]的前缀,如何表达“unique even numbers与unique odd numbers的个数之差”呢?因为每个unique number可能出现在很多位置,为了便于分析,我们约定只关心每个unique number最后一次出现的位置。记作lastPos[x]。比如偶数4最后一次出现在了a这个位置,那么我们就记录array[a]=1;假设奇数7最后一次出现在了b这个位置,那么我们就记录array[b]=-1.可见,只要计算这个01数组array[0:i]的前缀和,就可以知道nums[0:i]里“unique even numbers与unique odd numbers的个数之差”。
66

7-
所以我们需要构造一棵线段树seg,其中节点seg[i]表示array[0:i]的前缀和。如果seg[i]与之前的某个seg[j]相同,那么就意味着[j:i]是一个符合条件的区间。
7+
所以我们需要构造一棵线段树seg,其中节点seg[i]表示array[0:i]的前缀和。如果seg[i]与之前的某个seg[j]相同,那么就意味着[j:i]是一个符合条件的区间。注意对于线段树,是可以支持log(n)时间去实现`find_first_equal`的操作。这个我们后面再提。
8+
9+
现在,我们需要理解为什么必须用线段树而不是普通的数组来记录上面的seg[i]呢?因为随着i的增大,lastPos[]会改变(比如,最新的x=nums[i]会导致`lastPos[x]=i`的更新)。这继而会造成array[]也会改变(显然,array[i]会是一个非零值,而之前x所在的位置的array值会置零)。这继而又会造成array的前缀和,即seg[i]的改变。对于一个mutable的数组,想用log的时间实现`find_first_equal`是不可能的。
10+
11+
接下来我们思考,随着前缀下标i的增大,这棵线段树该怎么更新。当前缀移动到i位置时,记x=nums[i],原先的lastPos[x]=j。这就意味着:原来的array[j]从1(或者-1)要变成0,而array[i]要填充为1(或者-1)。对于array的前缀和而言,下标从j到i-1的前缀和(即seg[j]到seg[i-1])都需要撤回1(或者增加1);而最新的seg[i]就是在seg[i-1]的基础上加上array[i]的影响。可见,对于线段树而言,上述的操作本质就是树上的区间更新。
12+
13+
解决了线段树怎么更新,接下来讲`find_first_equal`的实现。这里有一套模板操作:我们对于线段树的每个节点(提醒:对应array的一个前缀和)都维护最大值和最小值两个val。

0 commit comments

Comments
 (0)