【问题标题】:Reversing an array without 'reverse' or duplicating an array反转数组而不“反转”或复制数组
【发布时间】:2018-02-09 20:03:45
【问题描述】:

我正在尝试解决以下练习:

不使用 reverse 方法反转数组,不使用 第二个数组,并且不重复任何值。

我考虑过让数组成为对象,然后从头到尾更新数组,但我认为您也可以更新它。

尝试了一些简单的方法,例如:

function reverseArray(array) {
  for (var i = 0; i < array.length; i++) {
    // var elem = array.shift();
    var elem = array.shift()
    array.push(elem)
  }
  return array
}

array = ['a', 'b','c','d','e'];

reverseArray(array);

但这并没有真正改变它。有关如何执行此操作的任何建议或解释?

【问题讨论】:

标签: javascript arrays algorithm array-algorithms


【解决方案1】:

使用 ES6 语法,您不需要将值复制到临时变量中(这是最后一个要求的内容吗?)。

function reverse(arr) {
    for(let i = 0, j = arr.length-1; i < j; i++, j--)
        [arr[i], arr[j]] = [arr[j], arr[i]];
}

const arr = ['a','b','c','d','e'];
reverse(arr);
console.log(arr);

有人可能会争辩说这里创建了数组(如果引擎不优化它),就像splice 也创建了一个数组(作为它的返回值)。

【讨论】:

    【解决方案2】:

    array = ['a', 'b', 'c', 'd', 'e'];
    console.log(array);
    
    for (var i = 0; i < Math.floor(array.length / 2); i++) {
      var item = array[i];
      array[i] = array[array.length - i - 1];
      array[array.length - i - 1] = item;
    }
    console.log(array);

    【讨论】:

    • 恭喜...你是唯一一个在想的人,只走了一半。
    【解决方案3】:

    这是一个最小的方法。给定var arr = [1,2,3,4],这个循环将把arr 变异为[4,3,2,1]

    for (var i = 0; i < arr.length - 1; i++) {
        arr.splice(i, 0, arr.pop());
    }
    

    【讨论】:

      【解决方案4】:

      以下将在不使用reverse 方法的情况下反转数组。它的工作原理是交换第一个和最后一个元素,然后是倒数第二个和倒数第二个元素,然后是倒数第三个和倒数第三个元素,等等,直到 i 不再小于 (&lt;) 而不是 @ 987654324@.

      function reverse(arr) {
        for(var i = 0, j = arr.length-1; i < j; i++, j--) {
          var tmp = arr[i];
          arr[i] = arr[j];
          arr[j] = tmp;
        }
        return arr;
      };
      
      var reversed = reverse(['a','b','c','d','e']);
      console.log(reversed);

      【讨论】:

      • 这通过交换第一个和最后一个元素,然后是第二个和倒数第二个元素,然后是第三个和倒数第三个元素等来实现。
      【解决方案5】:

      https://jsfiddle.net/pa2fqa8n/1/

      a = ['a', 'b', 'c', 'd', 'e'];
      for(var i = 0; i < a.length-1; i++){
        for(var j = 0; j < a.length-i-1; j++){
          var k = a[j];
          a[j] = a[j+1];
          a[j+1] = k;
        }
      }
      

      内部循环的第一次迭代将第一个元素移动到末尾,其余元素向前移动一次。接下来的每次迭代都做同样的事情,但比上一次迭代少 1。

      【讨论】:

      • 添加了说明,但我个人更喜欢 jsfiddle 而不是 sn-ps。
      【解决方案6】:

      我必须使用交换变量,这是否违反“不复制任何值”?

      var test1 = [2, '5', 6, 'a', 'Z'];
      var test2 = [2, '5', false, 'a', 'Z', {a: 'whatevs'}];
      
      console.log('test1 before', JSON.stringify(test1));
      console.log('test2 before', JSON.stringify(test2));
      
      reversarooni(test1);
      reversarooni(test2);
      
      console.log('test1 after', JSON.stringify(test1));
      console.log('test2 after', JSON.stringify(test2));
      
      function reversarooni(inputArray) {
        var index = 0;
        var len = inputArray.length;
        
        for(; index < len / 2; index++) {
          var swap = inputArray[index];
          inputArray[index] = inputArray[(len - 1) - index];
          inputArray[(len - 1) - index] = swap;
        }
      }

      【讨论】:

        【解决方案7】:

        这里是如何在没有副本、临时数组或变量来保存值,或者使用Array.reverse().修改数组的地方

        function reverseArray(array) {
          var len = array.length;
          for (var i=len,j=-1; j++,i--;)  array.unshift( array[len-1-i+(j)] );
          array.length = len;
        }
        
        var array = ['a', 'b','c','d','e'];
        
        reverseArray(array);
        console.log(array);

        它将值向后插入到数组的开头,将旧值推到末尾,然后在迭代完成后通过重置数组长度将它们切片。

        【讨论】:

        • 这会复制数组中的所有元素。另外,追加而不是前置不是更有效吗?
        • @Dukeling - 任何解决方案都会“复制”这些元素,而移动它们的正是这些元素。如果我附加了这些值,我必须对数组进行切片,这将创建一个新数组,使用length 切割数组只有在新值位于开头时才有效。
        • 这需要 O(n) 额外空间,通过复制数组中的每个元素(在我看来,这显然违反了“不复制任何值”),其中this,例如,似乎(基于我有限的 JS 知识)只占用 O(1) 额外空间。
        • @Dukeling - 这是解构,它实际上只是语法糖。它比仅使用临时变量要慢,但它确实避免在代码中实际声明该变量。这也可以,但使用unshift 会更慢。
        【解决方案8】:

        您可以使用spread syntax ...rest parameters ... 并通过递归和函数式方法返回交换的项目。

        const
            _ = (...a) => a,
            rev = (a, ...rest) => rest.length ? _(...rev(...rest), a) : _(a),
            reverseArray = array => rev(...array);
        
        console.log(reverseArray(['a', 'b', 'c', 'd', 'e']));
        console.log(reverseArray(['a']));
        console.log(reverseArray(['a', 'b']));
        .as-console-wrapper { max-height: 100% !important; top: 0; }

        【讨论】:

          【解决方案9】:

          function reverseArray(a) {
          
              const halfLength = a.length / 2;
          for (let i = 0; i< halfLength; i++){
          const start = a[i]
          a[i] = a[a.length-i-1]
          a[a.length-i-1] = start
          }
             
          
          return a;
          }

          【讨论】:

            【解决方案10】:

            function printReverse(array) {
              for (i = array.length-1; i > -1; i--) {
                console.log(array[i]); //4,3,2,1
              }
            }
            
            printReverse([1, 2, 3, 4]);

            这对我有用。

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2013-01-11
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2021-08-11
              • 1970-01-01
              相关资源
              最近更新 更多