簡體   English   中英

您可以使用 JavaScript 中的對象在 O(N)(線性)時間內對正整數進行排序嗎?

[英]Can you sort positive integers in O(N) (linear) time using an object in JavaScript?

我需要對一個正整數數組進行排序。 通過 JavaScript 的排序方法在 O(N * log(N)) 中很容易做到:

let a = [4, 1, 3, 9, 7, 19, 11];
a.sort((a,b) => a - b);
return a;

// returns [1, 3, 4, 7, 9, 11, 19]

但是,似乎可以使用 JavaScript 對象在 O(N) 中完成? 循環遍歷數組以將整數添加到對象中是 O(N),然后從該對象中獲取值也是 O(N)。 (或者,抓住鑰匙並轉換回數字)。

let o = {};
let a = [4, 1, 3, 9, 7, 19, 11];

a.forEach(integer => { o[integer] = integer });

return Object.values(o);

// returns [1, 3, 4, 7, 9, 11, 19]

刪除常量,我們正在考慮對 O(N) 中的正整數進行排序(犧牲額外的 O(N) 空間)。 從我讀過的所有內容來看,這應該是不可能的。 我在這里缺少什么?

用於設置和檢索密鑰的內部代碼取決於實現。 輸出(和順序)是有保證的(對於所有屬性枚舉方法,從ES2020 開始),但機制取決於實現者。 您必須查看引擎源代碼。

我不知道不同 Javascript 引擎在后台運行的代碼,但是如果您知道數組中數字的上限,那么這在O(n)可能的(或更准確地說, O(n + k)其中k是一個常數 - 上限)通過使用計數排序:創建一個鍵的映射(類似於您正在做的,但包括每個項目出現的次數),然后從 0 迭代到上限綁定,檢查被迭代的數字是否包含在鍵中。 如果是這樣,推送到數組:

 let o = {}; let a = [4, 1, 3, 9, 7, 19, 11]; // O(n) for (const num of a) { if (!o[num]) { o[num] = []; } o[num].push(num); } // O(n). This part isn't strictly necessary, but the alternative makes the code uglier const max = Math.max(...a); const result = []; // O(k) for (let i = 0; i <= max; i++) { if (o[i]) { // total of O(n) items pushed over the whole loop result.push(...o[i]); } } console.log(result);

如果像您的示例一樣,沒有重復的數字,則代碼要容易得多:

 let o = {}; let a = [4, 1, 3, 9, 7, 19, 11]; for (const num of a) { o[num] = true; } // O(n) const max = Math.max(...a); const result = []; // O(k) for (let i = 0; i <= max; i++) { if (o[i]) { // total of O(n) items pushed over the whole loop result.push(i); } } console.log(result);

暫無
暫無

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

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