Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/429.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 给出一个原始数组和一个新数组,每个元素';s值表示左侧较大的元素数_Javascript_Arrays_Algorithm_Performance - Fatal编程技术网

Javascript 给出一个原始数组和一个新数组,每个元素';s值表示左侧较大的元素数

Javascript 给出一个原始数组和一个新数组,每个元素';s值表示左侧较大的元素数,javascript,arrays,algorithm,performance,Javascript,Arrays,Algorithm,Performance,给出一个数组,比如[4,2,1,3,5],基于这个数组,我们有了一个新的数组,每个数字都显示其左边大于自身的元素数,即[0,1,2,1,0]。现在编写一个给定输入为[0,1,2,1,0]的函数,返回原始数组。数组的范围为1~n(n是数组的大小,如果排序,可以假定原始数组中的所有数字都是连续的) 现在,为了恢复原始数组,我尝试了一种解决问题的方法,从数组的末端到前端进行迭代,如下所示: 1. At any ith index, say the number in array(not the ori

给出一个数组,比如[4,2,1,3,5],基于这个数组,我们有了一个新的数组,每个数字都显示其左边大于自身的元素数,即[0,1,2,1,0]。现在编写一个给定输入为[0,1,2,1,0]的函数,返回原始数组。数组的范围为1~n(n是数组的大小,如果排序,可以假定原始数组中的所有数字都是连续的)

现在,为了恢复原始数组,我尝试了一种解决问题的方法,从数组的末端到前端进行迭代,如下所示:

1. At any ith index, say the number in array(not the originial array) is j
2. Search the number which is at (i-j)th position in your AVL tree(This can be done in O(logn) time. Comment if you need more explanation on this)
3. The element in the AVL tree is your required element. Delete that element from AVL tree.(O(logn))
我的做法:

假设范围为1~5,如果排序,原始数组将为[1,2,3,4,5]。从结尾到结尾迭代

因此,首先5,没有任何元素可以大于5,因此其较大元素的最大计数为0,然后4将有1作为其较大元素的最大计数,3到2,以此类推。将键值对存储到对象中

现在从后面到前面迭代输入

  • 0->5
  • 1->可以是4、3或2
  • 2->可以是3、2或1
  • 1->任何大于第一个的数字
  • 0->(可以是任何值,因为取了5,所以可以是1、2、3或4)

  • 仅仅将输入的每个元素作为值从映射映射到其键是不够的。什么是一种直观的方法来达到最佳性能?(如果可能,避免O(n^2)。

    首先从数字1到n创建一个AVL树

    从后面开始,即在第n个索引处(考虑1个索引)

    现在,算法的高级别大纲应该如下所示:

    1. At any ith index, say the number in array(not the originial array) is j
    2. Search the number which is at (i-j)th position in your AVL tree(This can be done in O(logn) time. Comment if you need more explanation on this)
    3. The element in the AVL tree is your required element. Delete that element from AVL tree.(O(logn))
    
    所以总的复杂度是O(nlogn)

    演练

    最初,树将包含所有5个元素

  • 从索引5(基于1的索引)开始。元素为0,即i=5,j=0。第五大元素是5

  • 现在,树包含四个元素1、2、3和4。i=4,j=1。所以4-1,即第三大元素,在这种情况下是3

  • i=3,j=2。(3-2)rd最大元素是1,因为树包含(1,2,4)

  • 等等

    使用树查找第i个最大数字

    我们可以通过将左子树中的节点数存储在根节点上来实现这一点。因此考虑一棵树,有1, 2、3、4和5的元素,树结构如下:

            4(3)
          /     \
         3(1)   5(0)
         /   \
        1(0)  2(0)
    
    在根目录下,数字4是值,圆括号中的数字是左子树中的节点数

    在构造(插入和删除)树时,我们可以保持计数

    现在,为了找到第i个节点,假设我们想要给定树中的第3个节点。我们从根开始,它说它有3个元素比它左边小,所以我们移到左边。现在根,即3,有一个较小的左元素,小于3(第i个元素),所以我们移到它的右边。从3中减去1(左计数)+1(根本身)。现在根是2,我们想要第一个元素,左边的计数是0。因此,以2为根的子树的第一个元素是2

    基本伪代码如下:

    while(true){
      count  = root->leftCount;
      if((count+1)<i){
         //move to right
         i-=(count+1);
         root = root->right;
      }
      else if(i==(count+1)){
         //root is the ith node
         break;
      } else{
         //move to the levft
         root=root->left
    
      }
    }
    
    while(true){
    计数=根->左计数;
    如果((计数+1)正确;
    }
    否则如果(i==(计数+1)){
    //根是第i个节点
    打破
    }否则{
    //移到左边
    根=根->左
    }
    }
    
    首先从数字1到n创建一个AVL树

    从后面开始,即在第n个索引处(考虑1个索引)

    现在,算法的高级别大纲应该如下所示:

    1. At any ith index, say the number in array(not the originial array) is j
    2. Search the number which is at (i-j)th position in your AVL tree(This can be done in O(logn) time. Comment if you need more explanation on this)
    3. The element in the AVL tree is your required element. Delete that element from AVL tree.(O(logn))
    
    所以总的复杂度是O(nlogn)

    演练

    最初,树将包含所有5个元素

  • 从索引5开始(基于1的索引)。元素是0,即i=5,j=0。所以第五大元素是5

  • 现在,树包含四个元素1,2,3和4。i=4,j=1。所以4-1,即第三大元素,在本例中为3

  • i=3,j=2。(3-2)第三个最大元素是1,因为树包含(1,2,4)

  • 等等

    使用树查找第i个最大数字

    我们可以在根节点中存储左子树中节点数的计数,因此考虑树,元素1, 2、3、4和5和树结构如下:

            4(3)
          /     \
         3(1)   5(0)
         /   \
        1(0)  2(0)
    
    在根目录下,数字4是值,圆括号中的数字是左子树中的节点数

    在构造(插入和删除)树时,我们可以保持计数

    现在,为了找到第i个节点,假设我们想要给定树中的第3个节点。我们从根开始,它说它有3个元素比它小,所以我们向左移动。现在根,即3有一个小的左元素,它比3(第i个元素)小,所以我们向右移动。减去1(左计数)+1(根本身)现在根是2,我们需要第一个元素,左边的计数是0。因此,在2根的子树的第一个元素是2

    基本伪代码如下:

    while(true){
      count  = root->leftCount;
      if((count+1)<i){
         //move to right
         i-=(count+1);
         root = root->right;
      }
      else if(i==(count+1)){
         //root is the ith node
         break;
      } else{
         //move to the levft
         root=root->left
    
      }
    }
    
    while(true){
    计数=根->左计数;
    如果((计数+1)正确;
    }
    否则如果(i==(计数+1)){
    //根是第i个节点
    打破
    }否则{
    //移到左边
    根=根->左
    }
    }
    
    您可以使用该值作为负索引来生成原始数组

    var数组=[1,2,3,4,5],
    countLeft=[0,1,2,1,0],
    结果=countLeft.reduceRight(函数(r,a){
    返回数组.拼接(数组.长度-1-a,1).concat(r);
    }, []);
    console.log(result);
    您可以使用该值作为负索引来生成原始数组

    var数组=[1,2,3,4,5],
    countLeft=[0,1,2,1,0],
    结果=countLeft.reduceRight(函数(r,a){
    返回数组.拼接(数组.长度-1-a,1).concat(r);
    }, []);
    
    console.log(result);
    这里是一个可能的解决方案。请参阅内联注释以获取对