2017-08-12 198 views
0

我試圖解決一個問題:分組號JS算法

問題:

給定的正重複號的數組。輸出 應該得到具有排序右側賠率的陣列和脣上上 左側(沒有特定的順序)

輸入:[4,1,2,3,4]

輸出:[4,2 ,3,1]

在原地解決並且不使用額外空間和O(N)運行時。

代碼:

/* 
* Algorithm is simple, have two pointers one on the left and another on the right. 
* Note: We are sorting all evens on the left and odds on the right 
* If you see even on left, move on else swap. 
*/ 

function groupNumbers(intArr) { 

    if(intArr.length == 0 || intArr.length == 1){ 
     return intArr; 
    } 

    for(let i=0, j =intArr.length-1; i<intArr.length; i++){ 
     if(j>=i){ //elements should not overlap 
      let start = intArr[i]; 
      let end = intArr[j]; 


      if(start%2 == 0){ //Even 
       i++; 
      } else { 
       [start, end] = [end, start]; //swap 
      } 


      if(end%2 == 1){ 
       j--; 
      } else { 
       [start, end] = [end, start]; //swap 
      } 

     } //if-ends 

    }//for-ends 

    return intArr; 
} 

我不知道我要去哪裏錯了。我錯過了一些東西。我得到與輸出相同的排序數組。

條件: **解決它INPLACE和不使用額外的空間**(優選在一個迭代)

+1

雖然這是一個完全合法的問題,這種事情應該j *關於*從未*在JavaScript中完成。 'Array.prototype.sort'在C++中實現,即使傳入一個自定義的排序函數,它的速度幾乎肯定會比你寫的任何東西都要快。 –

+0

你能解釋一下嗎?爲什麼?當我沒有對任何東西進行排序時,只需使用兩個指針來交換東西。 @JaredSmith在這種情況下請賜教。我想了解更多 – TechnoCorner

+0

有很多稱爲「腳本」語言的語言,但JavaScript真的是*:它是爲了編寫主機環境的腳本。因此,運行JavaScript時會涉及很多開銷,即使它看起來像C:有邊界檢查,原始裝箱/拆箱,與運行時間接口等。並且在某些情況下直接改變數組可能會比*慢製作一個新的,因爲它可以反覆改變「形狀」造成一堆內存分配,而不是可能只是一個來保存新陣列。然後你會遇到大小問題:對於長度爲n的數組,您... –

回答

1

我不確定我要去哪裏錯。我錯過了一些東西。我得到與輸出相同的排序數組。

幾件事情:

let start = intArr[i]; 
let end = intArr[j]; 
... 
[start, end] = [end, start]; 

這確實交換價值的變量startend,但不是在數組的索引。

然後你有兩個i++在增加左指針的同一個循環中。

if(start%2 == 0){ //Even 
    i++; 
} else { 
    [start, end] = [end, start]; //swap 
} 

這裏你交換的物品當左指針指向奇數值,但沒有檢查右指針也指向偶數值。你可能只需在這裏交換兩個奇數值。正確的指針相同。

const isEven = v => (v&1) === 0; 
 
const isOdd = v => (v&1) === 1; 
 

 
function groupNumbers(arr){ 
 
    var left = 0, right = arr.length-1; 
 
    while(left < right){ 
 
    //move the left pointer to find the next odd value on the left 
 
    while(left < right && isEven(arr[left])) ++left; 
 

 
    //move the right pointer to find the next even value on the right 
 
    while(left < right && isOdd(arr[right])) --right; 
 

 
    //checking that the two pointer didn't pass each other 
 
    if(left < right) { 
 
     console.log("swapping %i and %i", arr[left], arr[right]); 
 
     //at this point I know for sure that I have an odd value at the left pointer 
 
     //and an even value at the right pointer 
 

 
     //swap the items 
 
     var tmp = arr[left]; 
 
     arr[left] = arr[right]; 
 
     arr[right] = tmp; 
 
    } 
 
    } 
 
    return arr; 
 
} 
 

 

 
[ 
 
    [1,2,3,4], 
 
    [1,2,3,4,5,6,7,8,9,0], 
 
    [1,3,5,7], 
 
    [2,4,1,3], 
 
    [5,4,3,2,1], 
 
].forEach(sequence => { 
 
    console.log("\ninput: " + sequence); 
 
    console.log("output: " + groupNumbers(sequence)); 
 
});
.as-console-wrapper{top:0;max-height:100%!important}


由@JaredSmith建議,同樣的事情,只是使用排序功能:)

function sortEvenLeftOddRight(a,b){ 
 
    return (a&1) - (b&1); 
 
    //return (a&1) - (b&1) || a-b; //to additionally sort by value 
 
} 
 

 
[ 
 
    [1,2,3,4], 
 
    [1,2,3,4,5,6,7,8,9,0], 
 
    [1,3,5,7], 
 
    [2,4,1,3], 
 
    [5,4,3,2,1], 
 
].forEach(sequence => { 
 
    console.log("\ninput: " + sequence); 
 
    sequence.sort(sortEvenLeftOddRight); 
 
    console.log("output: " + sequence); 
 
});
.as-console-wrapper{top:0;max-height:100%!important}

+0

非常感謝!這真太了不起了! – TechnoCorner

+0

你能解釋一下你的意思嗎? '這實際上是交換變量開始和結束的值,但不是數組中的指數,Isn; t [a,b] = [b,a]與你寫的交換代碼一樣好?通過交換指數是什麼意思?對不起,我在這裏不是很清楚。 – TechnoCorner

+0

@TechnoCorner a = arr [i],b = arr [j]'「將數組中的值複製到兩個變量中。如果你現在做'[a,b] = [b,a]',它會切換這些變量的值,但不是在數組中。因爲你從不做任何事情來將這些改變存儲回數組,比如'arr [i] = a,arr [j] = b',交換是毫無意義的。 – Thomas

0

一個非常簡潔的方法來解決,這將是使用reduce

const out = arr.reduce((p, c) => { 

    // if the value is divisible by 2 add it 
    // to the start of the array, otherwise push it to the end 
    c % 2 === 0 ? p.unshift(c) : p.push(c) 
    return p; 
}, []); 

OUT

[4,2,4,1,3] 

DEMO

+0

我們可以解決這個沒有額外的空間?即創建新陣列。請保留此解決方案,我想閱讀並理解它,但我更喜歡解決方案INPLACE,並且沒有額外的空間。 – TechnoCorner