【发布时间】:2021-02-13 08:52:19
【问题描述】:
在我完成一个 Leetcode 问题后,我总是尝试同时确定渐近时间复杂度,以进行练习。
我现在正在查看问题26. Remove Duplicates from Sorted Array:
给定一个排序数组nums,就地删除重复项,使得 每个元素只出现一次并返回新的长度。
不要为另一个数组分配额外的空间,你必须这样做 使用 O(1) 额外内存就地修改输入数组。
澄清:
困惑为什么返回的值是一个整数,但你的答案是 数组?
注意输入数组是通过reference传入的,这意味着一个 调用者也将知道对输入数组的修改。
在内部你可以这样想:
// nums is passed in by reference. (i.e., without making a copy) int len = removeDuplicates(nums); // any modification to nums in your function would be known by the caller. // using the length returned by your function, it prints the first len elements. for (int i = 0; i < len; i++) { print(nums[i]); }示例 1:
输入:
nums = [1,1,2]
输出:2, nums = [1,2]
解释: 你的 函数应返回长度 = 2,其中 nums 的前两个元素 分别为 1 和 2。你留下什么并不重要 返回的长度。
我的代码:
/**
* @param {number[]} nums
* @return {number}
*/
var removeDuplicates = function(nums) {
nums.forEach((num,i) => {
if(nums[i+1] !== null && nums[i+1] == nums[i] ){
nums.splice(i, 1);
console.log(nums)
removeDuplicates(nums)
}
})
return nums.length;
};
对于这个问题,我从我的研究中得到了 O(log n)。每次运行时执行时间减半。有人可以验证或确定我是否错了?
所有的递归函数都是天生的O(logn)吗?即使有多个循环?
【问题讨论】:
-
您的数组中是否需要文字
null? -
为什么是递归的?我没有看到这里的优势。
-
这可能是 O(n),但是您的解决方案更糟糕,因为它会重新检查递归调用中的所有元素。
-
"所有的递归函数本质上都是 O(long) 吗?即使有多个循环"(假设您的意思是
log n)- 不是。不可能所有递归函数都具有这种性能特征。len = (list, count = 0) => list.length === 0 ? count : len(count.slice(1), count + 1)将只是O(n)并且不能是其他任何东西。 一些递归函数将是O(log n),如树遍历或二分搜索。但是,有些会具有更高的复杂性,例如查找所有排列或斐波那契数。 -
我认为你的算法是 O(n²) 最坏情况和 O(n) 最好情况,平均情况介于两者之间。 (实际回答您的问题)
标签: javascript algorithm recursion duplicates