Ich mache eine Übung, bei der ich die gerade Zahl innerhalb desselben Arrays wiederholen soll. So zum Beispiel folgendes Array:

[1,2,5,6,8]

Ich sollte bekommen:

[1,2,2,5,6,6,8,8]

Ich denke, ich habe fast die Lösung, aber es gibt zwei Randfälle, in denen sie nicht funktionieren:

[1,2,5,6,8,7,7,7]

Oder

[1,2,5,6,8,8,7,7]

Das ist mein Code:

function repeatEvenNumbers(arr) {
    let end = arr.length -1;
    for(let i = arr.length -1; i > 0; i--){
      end = i;
      if(arr[i] % 2 === 0){
        if(i === arr.length -1){
          end+=2;
          arr[end] = arr[i];
          end+=1;
          arr[end] = arr[i];
        }else{
          end+=1;
          arr[end] = arr[i];
          if(i - 1 !== 0){
            end+=1;
            arr[end] = arr[i];
          }
        }
      }else{
        end+=1;
        arr[end] = arr[i];
      }
    }
    return arr;
}
// console.log(repeatEvenNumbers([1,2,3])) // [1,2,2,3]
console.log(repeatEvenNumbers([1,2,5,6,8])) // [1,2,2,5,6,6,8,8]
-2
alex 7 Feb. 2020 im 21:51

5 Antworten

Beste Antwort

In Kommentaren wurde klargestellt, dass dieses Problem folgende Einschränkungen aufweist:

  • Keine anderen Arrays erstellen
  • Keine Array-Helfer oder integrierten Funktionen

Ihre aktuelle Lösung funktioniert nicht, da Ihr Code absolut keine Ahnung hat, wie groß das Array am Ende der Dinge sein wird. Was ist, wenn es sich um ein Array mit 5 geraden Zahlen handelt, sodass die letzte Zahl im neuen Array um 5 Leerzeichen nach vorne verschoben werden muss? Es gibt keinen Grund, der das erklärt, Sie werden höchstens 2 Felder vorwärts verschieben.

Ich schlage zwei Durchgänge vor, einen, um gerade Zahlen zu zählen, und einen, um die Elemente genau um die erforderliche Anzahl von Positionen zu versetzen.

function repeatEvenNumbers(arr) {
    let offset = 0;
    for(let i = 0; i < arr.length; i++)
      if(arr[i]%2 === 0)
        offset++;
    for(let i = arr.length-1; i > 0; i--) {
      if(arr[i] % 2 === 0) //for even numbers, set an additional element
        arr[i+offset--] = arr[i]; //and decrement offset going forward
      arr[i+offset] = arr[i];
    }
    return arr;
}
console.log(repeatEvenNumbers([1,2,5,6,8,8,7,7]))

Auf diese Weise können Sie in O(2n) zur richtigen Antwort gelangen, anstatt eine zusätzliche Schleife zum Verschieben aller Elemente zu benötigen, die O(n^2) wäre.

2
Klaycon 7 Feb. 2020 im 20:18

Ihre aktuelle Lösung ist ziemlich kompliziert und kann so umgeschrieben werden, wie es Ihnen bereits andere gezeigt haben.

Also kannst du es mit reduceRight machen:

const repeatEven = arr => {
  return arr.reduceRight((acc, val, index) => {
    if (val % 2 === 0) acc.splice(index, 0, val)
    return acc
  }, arr)
}

console.log(repeatEven([1,2,5,8,7]))
console.log(repeatEven([1,2,5,6,8,7,7,7]))
console.log(repeatEven([1,2,5,6,8,8,7,7]))

Oder noch besser, wie Scott Sauyet vorschlug:

const repeatEven = arr => {
   return arr.flatMap(n => n % 2 ? n : [n, n])
}

console.log(repeatEven([1,2,5,8,7]))
console.log(repeatEven([1,2,5,6,8,7,7,7]))
console.log(repeatEven([1,2,5,6,8,8,7,7]))
3
Max 7 Feb. 2020 im 19:30

Sie können ein anderes temporäres Array verwenden, die alten Werte und Doppelwerte speichern und die indexbezogenen Werte auf das ursprüngliche Array zurücksetzen.

function doubleEven(array) {
    var temp = [];
    
    for (var i = 0, l = array.length; i < l; i++) {
        temp.push(array[i]);
        if (array[i] % 2 === 0) temp.push(array[i]);
        array[i] = temp[i];
    }

    for (; i < temp.length; i++) array[i] = temp[i];

    return array;
}

console.log(...doubleEven([1, 2, 5, 6, 8, 7, 7, 7]));
0
Nina Scholz 7 Feb. 2020 im 19:06

Mit arr.splice ("Index zum Einfügen in Array", "Anzahl der zu löschenden Elemente", "Wert zum Einfügen") können Sie einen neuen Wert an der gewünschten Position einfügen. In diesem Fall vereinfacht es Ihre Aufgabe erheblich.

function repeatEvenNumbers(arr) {
    let end = arr.length -1;
    for(let i = end; i > 0; i--){
      if(arr[i] % 2 === 0){
        arr.splice(i, 0, arr[i]);
      }
    }
    return arr;
}
// console.log(repeatEvenNumbers([1,2,3])) // [1,2,2,3]
console.log(repeatEvenNumbers([1,2,5,6,8])) // [1,2,2,5,6,6,8,8]
4
Nuno 7 Feb. 2020 im 19:05

Dies ähnelt der Antwort von Nuno, ersetzt jedoch den Aufruf splice durch eine zusätzliche Schleife, um die zusätzliche Anforderung zu erfüllen, dass keine der Methoden von Array.prototype verwendet wird.

const dupEvens = (ns) => {
  for (let i = ns.length ; i > 0 ; i--) {
    if (ns[i] % 2 == 0) {
      for (let j = ns.length ; j > i ; j-- )  {
        ns[j] = ns[j - 1]
      }
    }
  }
  return ns
}

console.log(dupEvens([1,2,5,8,7]))
console.log(dupEvens([1,2,5,6,8,7,7,7]))
console.log(dupEvens([1,2,5,6,8,8,7,7]))

Ich würde niemals vorschlagen, Code auf diese Weise ohne einen sehr guten Grund zu schreiben. Die Antwort von Max (mit oder ohne meine Verfeinerung) scheint eine viel bessere Lösung zu sein, um die geraden Zahlen in einem Array zu duplizieren.

Wenn Sie jedoch auch auf die Array.prototype -Methoden verzichten und das ursprüngliche Array mutieren müssen, anstatt ein neues zu erstellen, funktioniert dies.

Wenn mich jedoch ein Unternehmen in einem Interview darum bitten würde, würde ich einige sehr scharfe Fragen zu ihren Entwicklungspraktiken stellen!

1
Scott Sauyet 7 Feb. 2020 im 20:09