2017-07-14 225 views
-2

配列を分割したい(例えば[1,2,3,4,5,6,7,8])、最初のパーティションは偶数の値、2番目の奇数の値(例の結果:[2,4,6,8,1,3,5,7])を保持する必要があります。整数の配列を偶数と奇数に分割する方法は?

私はこの問題を組み込みのArray.prototypeメソッドで2回解決することができました。第1の解決策は、mapおよびsortを使用し、次はsortです。

ソートアルゴリズムを使用する3番目のソリューションを作成したいと思いますが、リストをパーティション化するためにどのアルゴリズムが使用されているのかわかりません。私はバブルの並べ替えについて考えていますが、私はそれが私の2番目の解決策(array.sort((el1, el2)=>(el1 % 2 - el2 % 2)))で使用されていると思います... quicksortを見ましたが、整数が偶数か奇数ならチェックをどこに適用するのかわかりません...

要素の順序を維持したままそのようなタスクを実行する最適なアルゴリズム(配列が成長する直線的スケーリング)は何ですか?

+1

どのような並べ替えも最高 'O(nlogn)'なので、線形スケーリングが必要な場合、それらは最良のオプションではありません – frozen

+2

'sort' ??? 'filter'を使ってみましたか? – Bergi

+2

なぜインプレースですか?それはどんな目的に役立ちますか? –

答えて

0

簡単かつ効率的に、2つの指標を用いて、アレイの両側から実行し、必要に応じてスワップを達成することができる代わりに、些細な標準return [arr.filter(predicate), arr.filter(notPredicate)]アプローチのインプレースアプローチを主張している場合:

function partitionInplace(arr, predicate) { 
    var i=0, j=arr.length; 
    while (i<j) { 
     while (predicate(arr[i]) && ++i<j); 
     if (i==j) break; 
     while (i<--j && !predicate(arr[j])); 
     if (i==j) break; 
     [arr[i], arr[j]] = [arr[j], arr[i]]; 
     i++; 
    } 
    return i; // the index of the first element not to fulfil the predicate 
} 
+1

これは私の答えと同じ論理ではありませんか?これは、パーティション内のアイテムの相対的な順序を変更しませんか?つまり、[1,3,2,4]と指定すると、結果の配列は[4,2,3,1]になりますか? –

+0

@JimMischelはい、それは同じ考えです。私の実装が任意の述語で動作し、配列が分割された位置を返すので、はるかに複雑なコードがあります:-)実際にスワップは相対的な順序を変更しますが、 'O(n)'時間と 'O(1)'空間の複雑さにおいて安定した並べ替えを達成するアルゴリズムがないことは確かです。 – Bergi

+0

安定したO(n)、O(1)ソリューションがないというのはあなたが正しいと思います。冗談を思い出させる(?):速い、安い、良い:2つを選ぶ。 –

-1
let evens = arr.filter(i=> i%2==0); 
let odds = arr.filter(i=> i%2==1); 
let result = evens.concat(odds); 

私はそれがO(n)だと信じています。楽しむ。

EDIT: それとも、本当に効率を気にしている場合:あなたはかなり簡単にO(n)の時間でその場でこれを行うことができます

let evens, odds = [] 
arr.forEach(i=> { 
if(i%2==0) evens.push(i); else odds.push(i); 
}); 
let result = evens.concat(odds); 
+0

Meh、私たちはそのオーバーヘッドの半分を削減することができます。 (これはインプレースではなく、答えの終わりを参照してください。) –

+0

edit @ T.J.Crowder – frozen

+2

質問は明らかに必要なので、まだインプレースではありません。 3番目の最終的な配列に加えて、2つの一時配列を生成します。 *(私のDVDではなく、理解していますが、それはしません)* –

-2
Array.prototype.getEvenOdd= function (arr) { 
    var result = {even:[],odd:[]}; 
    if(arr.length){ 
     for(var i = 0; i < arr.length; i++){ 
     if(arr[i] % 2 = 0) 
      result.odd.push(arr[i]); 
     else 
      result.even.push(arr[i]); 
     } 
    } 
    return result ; 
}; 
1

。正面インデックスを開始し、背面の奇数インデックスを開始します。次に、偶数番号の最初のブロックをスキップして配列を調べます。

奇数番号を押すと、最後から逆方向に移動して最初の偶数番号を見つけます。次に、偶数と奇数を入れ替えます。

var i; 
var odd = n-1; 
for(i = 0; i < odd; i++) 
{ 
    if(arr[i] % 2 == 1) 
    { 
     // move the odd index backwards until you find the first even number. 
     while (odd > i && arr[odd] % 2 == 1) 
     { 
      odd--; 
     } 
     if (odd > i) 
     { 
      var temp = arr[i]; 
      arr[i] = arr[odd]; 
      arr[odd] = temp; 
     } 
    } 
} 

恩赦構文エラー:

のコードは次のようになります。 Javascriptは私の強い訴訟ではありません。

これは同じ相対順序を保持しないことに注意してください。つまり、配列[1,2,7,3,6,8]を指定すると、結果は[8,2,6,3,7,1]になります。配列は分割されていますが、奇数は元の配列と同じ相対順序ではありません。

+1

これは効率的ですが、目的の一部は、出力が各パーティション内の入力と同じ順序を維持するという例で指定されたOPのため、安定したパーティションにすることだと考えました。 –

+1

@PatrickRoberts:出力が安定しているとOPが具体的に言っている場所はわかりません。彼の例は安定した配置を示していますが、安定していなければならないということは何もありません。しかし、これは安定していません。私はその情報で私の答えを更新します。 –

+0

@PatrickRoberts、ありがとう、あなたは言うようにパーティションの順序を保つ必要があります。申し訳ありませんジム私は明示的にそれを書いていません。 – Marecky

関連する問題