[英]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);
您可以使用荷蘭國旗問題的算法
荷蘭國旗問題1是Edsger 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.