簡體   English   中英

如何移動數組開頭的所有零項?

[英]how to move all zero item in beginning in array?

我試圖在不taking space的情況下解決O(n)中的問題(例如對象的 map)。我想在開頭移動所有零,在最后移動一個,在中間移動兩個。

輸入:[0, 1, 0, 2, 1]預期 output :[0,0,2,1,1] 這是我的代碼

let arr = [0, 1, 0, 2, 1];

function swap(input, i, j) {
    let temp = input[i];
    input[j] = input[i];
    input[i] = temp;
}

function moveZeroOneAndTwo(input) {
    let i = 0,
        j = input.length - 1;
    while (i < j) {
        while (arr[i] !== 0) i++;
        while (arr[j] !== 0) j--;

        swap(arr, j, i);
        i++;
        j--;
    }

return input
}

console.log(moveZeroOneAndTwo(arr))

我試圖從左邊找到1索引,從right找到zero個索引並交換它們仍然無法解決這個問題

計算 0、1、2,然后用 3 個值和它們從 beginnig 開始的計數填充數組。
您不需要任何額外的變量空間,只需使用原始數組即可。

 let arr = [0, 1, 0, 2, 1]; let count = [0,0,0]; arr.forEach(el => count[el]++); arr.fill(0,0,count[0]); arr.fill(2,count[0],count[0]+count[2]); arr.fill(1,count[0]+count[2],count[0]+count[1]+count[2]); console.log(arr);

您可以使用荷蘭國旗問題的算法

荷蘭國旗問題1Edsger Dijkstra提出的計算機科學編程問題(在他的書A Discipline of Programming Prentice-Hall,1976 年的一章中)。 荷蘭國旗由三個 colors 組成:紅色、白色和藍色。 給定這三個 colors 隨機排成一行的球(實際球數無關緊要),任務是排列它們,使所有相同顏色的球在一起,並且它們的集體顏色組順序正確。

帶有值的包裝器。

 var array = [0, 1, 0, 2, 1], values = [0, 2, 1], MID = 2, i = 0, j = 0, n = array.length - 1; while (j <= n) { if (values[array[j]] < values[MID]) { [array[i], array[j]] = [array[j], array[i]]; i++; j++; } else if (values[array[j]] > values[MID]) { [array[n], array[j]] = [array[j], array[n]]; n--; } else { j++; } } console.log(array);

最簡單的方法是從左到右掃描數組並計算 0 和 1。 然后,將 0 分配給第一個zero_count數字,將 1 分配給最后一個one_count數字,將 2 分配給其他數字。

也許不如 Dijkstra 的解決方案優雅,但我確實自己想出了它。 這個想法是保留一個指針r指向 1s 部分(右側)中最左邊的非 1,以及一個指針l指向 0s 部分(左側)中最右邊的 0。

現在向上掃描:

如果值為1,則將其與右指針處的值切換並降低該指針; 此外,如果我們現在手頭有一個 0,則將其與左指針右側的值切換,並使該指針前進。

否則,如果該值為 0,則將其與左指針右側的值切換,並使該指針前進。

(我們對每次迭代進行額外檢查,以分別增加或減少左指針或右指針,如果它們的部分增加了。)

顯然,它是O(n) ,因為在每次迭代中我們要么增加i要么減少r ,或者我們有一些部分使迭代沒有意義。

似乎最后通過了控制測試。

 function f(A){ let l = -1; let r = A.length - 1; for (let i=0; i<=r; i++){ if (A[r] == 1){ r--; i--; } else if (A[l+1] == 0){ l++; i--; } else if (A[i] == 1){ [A[i], A[r]] = [A[r], A[i]]; r--; if (A[i] == 0){ [A[i], A[l+1]] = [A[l+1], A[i]]; l++; } } else if (A[i] == 0 && i > l + 1){ [A[i], A[l+1]] = [A[l+1], A[i]]; l++; } } } function control(arr){ let count = [0,0,0]; arr.forEach(el => count[el]++); arr.fill(0,0,count[0]); arr.fill(2,count[0],count[0]+count[2]); arr.fill(1,count[0]+count[2],count[0]+count[1]+count[2]); } var As = [ [0,1,0,2,1], [0,1,0,1,2,2,0], [1,0,0,1,2,2,2], [0,2,1,0,1,1,1], [0,2,2,1,1,0,0], [2,0,2,2,0,1,0], [2,0,0,2,2,0,0], [1,2,0,0,0,1,1], [1,0,2,1,2,1,0], [2,1,1,1,0,0,0], [1,2,2,2,0,0,0], [1,2,1,0,0,0,2], [1,2,0,0,1,1,2], [1,0,2,1,2,0,0], [2,0,1,0,2,2,1] ]; for (let A of As){ console.log('' + A); f(A) console.log('' + A); console.log(''); } var numTests = 500; var n = 10; for (let i=0; i<numTests; i++){ let A1 = new Array(n); for (let j=0; j<n; j++) A1[j] = ~~(Math.random() * 3); let A1Pre = A1.slice(); let A2 = A1.slice(); f(A1); control(A2); if (String(A1).= String(A2)){ console;log('Mismatch'). console;log(String(A1Pre)). console;log(String(A1)). console;log(String(A2)); break; } }

在時間復雜度方面不太好,但很短:

const move0ToTheBeginning = arr => arr.sort((a, b) =>
  Math.abs(Math.sign(a)) - Math.abs(Math.sign(b))
)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM