[英]Time Space Complexity of k smallest of unsorted array
I solved this problem given to me in an interview, but I do not know what the Time Space complexity is.我在面试中解决了这个问题,但我不知道时空复杂度是什么。
What is the Time Space complexity of the following solution?以下解决方案的时空复杂度是多少?
// Ordered Map Method
function orderedMapFrequency(array) {
const map = {};
for (let i = 0; i < array.length; i++) {
if (!map[array[i]]) {
map[array[i]] = 1;
} else {
map[array[i]]++;
}
}
return map;
}
function kSmallest(arr, k) {
let map = orderedMapFrequency(arr);
let frequencies = 0;
for (const [key, val] of Object.entries(map)) {
frequencies = frequencies + val;
if (frequencies >= k) {
return key;
}
}
}
// variables
let input;
let k;
input = [7, 10, 4, 3, 20, 15];
k = 3;
console.log(kSmallest(input, k)); // 7
input = [7, 10, 4, 3, 20, 15];
k = 4;
console.log(kSmallest(input, k)); // 10
input = [12, 3, 5, 7, 19];
k = 2;
console.log(kSmallest(input, k)); // 5
input = [7, 0, 25, 6, 16, 17, 0];
k = 3;
console.log(kSmallest(input, k)); // 6
I think it might be O(log(n)) or is it simple O(n)?我认为它可能是 O(log(n)) 还是简单的 O(n)?
Space Complexity空间复杂度
O(N)在)
Time Complexity时间复杂度
O(NlogN) O(NlogN)
Insertion of an entry into an ordered map is O(logN), therefore to create such an ordered map from an array is O(NlogN).将条目插入有序映射是 O(logN),因此从数组创建这样的有序映射是 O(NlogN)。 Your
orderedMapFrequency
is thus O(NlogN).因此,您的
orderedMapFrequency
是O(NlogN)。 Find the kth smallest element by iterating over the ordered map is O(k), which is dominated by the creation of the ordered map.通过遍历有序映射找到第 k 个最小元素是 O(k),这取决于有序映射的创建。 Therefore the overall time complexity is O(NlogN).
因此总的时间复杂度是 O(NlogN)。
Appendix附录
You can check here to find solutions with better time complexity.您可以在此处查看以找到具有更好时间复杂度的解决方案。
It is interesting that the Object {}
in Javascript acts as an ordered map for integer keys, see Does ES6 introduce a well-defined order of enumeration for object properties?有趣的是,Javascript 中的 Object
{}
充当整数键的有序映射,请参阅ES6 是否为对象属性引入了定义良好的枚举顺序? : :
Integer indices (if applicable), in ascending order.
整数索引(如果适用),按升序排列。
Your solution uses a characteristic of JavaScript objects: keys that are decimal representations of indexes will be iterated in sorted order when calling functions like Object.entries
.您的解决方案使用 JavaScript 对象的一个特性:在调用
Object.entries
函数时,索引的十进制表示键将按排序顺序迭代。
From the specification we can only learn that setting and getting object properties must have sub-linear time complexity (see Javascript ES6 computational/time complexity of collections ), so it is not an absolute requirement of the language that these operations run in constant time.从规范中我们只能了解到设置和获取对象属性必须具有亚线性时间复杂度(参见Javascript ES6 计算/集合时间复杂度),因此这些操作在恒定时间内运行并不是语言的绝对要求。
If these were constant in time, and iteration over these properties would take linear time, then we would have found a method to sort numbers in linear time, which is not possible unless some restrictions apply which would allow for a non-comparative sorting algorithm such as radix sorting algorithms .如果这些在时间上是恒定的,并且对这些属性的迭代将花费线性时间,那么我们将找到一种在线性时间内对数字进行排序的方法,这是不可能的,除非应用一些限制,这将允许非比较排序算法,例如作为基数排序算法。
And there are restrictions here: object keys are only iterated in their numerical order when these numbers are integers in the range 0 to 2 31 -1.并且这里有一些限制:对象键仅在这些数字是 0 到 2 31 -1 范围内的整数时才按其数字顺序迭代。 So this does not apply for:
所以这不适用于:
Such keys will be iterated after other numbers, in the order they were inserted (which is what also happens with keys that are not numeric representations at all).这些键将按照插入的顺序在其他数字之后迭代(对于根本不是数字表示的键也会发生这种情况)。 So your solution can produce wrong results when such cases occur.
因此,当发生此类情况时,您的解决方案可能会产生错误的结果。
Here is a run of your code on slightly adapted inputs that violate one of the above conditions:这是在稍微修改的输入上运行的代码,这些输入违反了上述条件之一:
let input, k; input = [7, 10, 4, -3, 20, 15]; // Notice -3 console.log(kSmallest(input, 3)); // 10 (should be 7) input = [7, 10, 4, 3.1, 20, 15]; // Notice 3.1 console.log(kSmallest(input, 4)); // 15 (should be 10) input = [12000000000, 3000000000, 5000000000, 7000000000, 19000000000]; // Big numbers console.log(kSmallest(input, 2)); // 12000000000 (should be 5000000000) // Your functions (unchanged) function orderedMapFrequency(array) { const map = {}; for (let i = 0; i < array.length; i++) { if (!map[array[i]]) { map[array[i]] = 1; } else { map[array[i]]++; } } return map; } function kSmallest(arr, k) { let map = orderedMapFrequency(arr); let frequencies = 0; for (const [key, val] of Object.entries(map)) { frequencies = frequencies + val; if (frequencies >= k) { return key; } } }
As you can see, the outputs are not the k -smallest that you would have expected.如您所见,输出并不是您所期望的k -smallest。
If the aim is for the algorithm to work also in those cases, then you can no longer rely on this specific behaviour of JavaScript objects and the property iteration order of functions like Object.entries
, and you'll have to come up with an explicitly written algorithm (like for example using a heap data structure), which will have O(nlogk) time complexity if well done.如果目标是让算法在这些情况下也能正常工作,那么您就不能再依赖 JavaScript 对象的这种特定行为以及
Object.entries
等函数的属性迭代顺序,您将不得不提出一个明确的编写的算法(例如使用堆数据结构),如果做得好,它将具有 O(nlogk) 时间复杂度。
As to the time complexity of your algorithm: it depends on the JavaScript engine, but it seems many do a good job in providing near constant time complexity for the get/set operations on object key collections.至于算法的时间复杂度:它取决于 JavaScript 引擎,但在为对象键集合上的 get/set 操作提供接近恒定的时间复杂度方面,似乎很多都做得很好。 So that would mean your solution provides a O(n) time complexity in practice.
所以这意味着您的解决方案在实践中提供了 O(n) 时间复杂度。 But:
但:
The space complexity is trivial: O(n).空间复杂度是微不足道的:O(n)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.