Algorithm 当从单个数字生成阵列时,计算子阵列中的1数

Algorithm 当从单个数字生成阵列时,计算子阵列中的1数,algorithm,recursion,divide-and-conquer,Algorithm,Recursion,Divide And Conquer,我正在研究这个编码问题: 对于给定的数字n,形成一个列表,并在列表中的相同位置依次插入以下模式: {楼层(n/2),n%2,楼层(n/2)} …直到列表中的每个元素都是1或0。现在,计算从l到r(1索引)范围内的1数 解释 从n开始。然后用以下三个元素制作一个列表:{floor(n/2),n%2,floor(n/2)}。现在展开--就地--这两个外部元素,考虑到新的n是楼层(n/2) 此过程将继续,直到n的值降至1或0。因此,它将基本上形成一棵树,从根上的1个节点(n)开始,每层的每个节点都有3

我正在研究这个编码问题:

对于给定的数字n,形成一个列表,并在列表中的相同位置依次插入以下模式:

{楼层(n/2),n%2,楼层(n/2)}

…直到列表中的每个元素都是1或0。现在,计算从l到r(1索引)范围内的1数

解释 从n开始。然后用以下三个元素制作一个列表:
{floor(n/2),n%2,floor(n/2)}
。现在展开--就地--这两个外部元素,考虑到新的n是
楼层(n/2)

此过程将继续,直到n的值降至1或0。因此,它将基本上形成一棵树,从根上的1个节点(n)开始,每层的每个节点都有3个分支

输入格式 三个整数:n,l,r

约束条件
0 ≤ N  该数组可以看作是二叉树的顺序序列,如果应用简单的算法,二叉树也是递归树

该二叉树具有以下属性:

  • 是的

  • 其高度h对应于表示n所需的二进制位数。所以在9(0b1001)的情况下,h=4

  • 它有2h-1个节点,也是数组表示中的元素数

  • 树的深度i处的节点都具有相同的值,并对应于n的第i个最低有效位。我们把这个位叫做ni,i在[1,h]中

  • 因此,所有节点的总值等于[1,h]中i的2i-1ni之和,即n

  • 深度i处节点的左(或右)子树将对应于为楼层(n/2i)生成的树

要查找与索引j相对应的节点(当基于1时),您可以使用精确的h个二进制数字(如果需要,请加上“0”)获取j的二进制表示,然后 只要表示中有多个“1”,当最左边的数字为“0”时,选择左分支,否则选择右分支。然后删除该数字并重复

然后,我们可以确定在向右移动时忽略的每个左子树的值,将1包含在节点本身中,并获取这些值的总和。 该总数表示索引j左侧的1个值的数量。 这反过来又可以用来知道任何范围内1个值的总和

如果将其转换为算法,您将得到如下代码片段。您可以运行它,输入n、i、j的值并查看结果总和:

函数sumtween(n,i,j){ 如果(j>=1;i>0&&bitMask>0;位掩码>>=1){ 让goRight=i&bitMask;//从i中提取一位 让nodeValue=n%2;//在二叉树的当前节点上获取值 n>>=1;//在树中向下一级 if(goRight)sum+=nodeValue+n;//在省略的左子树中添加节点值和值 i-=goRight;//清除i中的位 } 回报金额; } //I/O处理 让输入=document.querySelectorAll(“输入”); 让结果=document.querySelector(“span”); 文件。添加的文件列表器(“输入”,刷新); 函数刷新(){ 设[n,i,j]=Array.from(inputs,input=>input.value).map(Number); 设sum=sum(n,i,j); result.textContent=总和; } 刷新()
input{width:4em}
n:
i:
j:
总和: