【发布时间】:2019-05-05 03:42:49
【问题描述】:
我有一个问题,需要通过将其初始值的副本附加到自身来将字符串转换为另一个字符串。该问题允许在某些地方删除单个字符。
解释
let x = "abba"; // First string
let y = "aba" // Second initial string
y("aba") => remove last "a" => y("ab") => y+initialY = "ab"+"aba" =>
y("ababa") => remove char at index 2 => y("abba") => y == x => sucess
我的算法成功解决了问题:
let x = "abbbbcccaaac"
let y = "abc"
let xArr = x.split('')
let yArr = y.split('')
let count = 0;
for (let i = 0; i < xArr.length; i++) {
if(yArr[i] == undefined) {
yArr = yArr.concat(y.split(''));
count++;
}
if(xArr[i] != yArr[i]) {
yArr.splice(i, 1);
i--;
}
}
console.log("Output is:", yArr.join(''))
console.log("Appends in order to transform:", count)
该算法按预期工作,但是,我不确定它的时间和空间复杂性,最重要的是效率。
这个算法是否在
O(n)的时间复杂度中,其中n 是x的长度?如果不是
O(n),问题能在O(n)的时间内解决吗?.concat()、.splice()或.split()是否会以某种方式改变时间复杂度,因为它们嵌套在 for 循环中?如果不是,它们是否仍然会改变算法的时间复杂度?改变多少?鉴于这个问题的规律,这是一种有效的解决方法吗?
这个算法的空间复杂度是多少?
【问题讨论】:
-
其实,如果我们真的知道 splice、split 或 concat 的时间复杂度,那么它显然会影响你算法的整体时间复杂度。但是由于我们不这样做,我们会将它们视为恒定操作,O(1),这实际上将循环操作保持在 O(N) - 最坏的情况。空间复杂度为 O(1),因为我们没有为每个循环操作创建新的存储(在本例中为计数),而只是更新它。 IMO,这是一个公平的解决方案,因为我不知道您给定问题的限制是什么。
-
@CalebLucas “但既然我们不这样做,我们会认为它们是一个持续的操作”——我们应该这样做吗?在那种情况下,这个问题仍然有意义吗?此外,ECMA 规范提供了关于它们是什么的提示。
-
@meowgoesthedog “我们应该吗?” - 我觉得这取决于一个人的目标。这些函数在运行时由 javascript 引擎优化。如果目标是真正深入研究每个功能的细节及其在给定场景中的应用,那么考虑到它们的时间复杂性当然是最重要的。
-
@CalebLucas 你是对的 split() ,concat() 等已经被JS引擎优化。然而,这并不意味着这些操作没有时间/空间复杂性。根据问题的意图,有2个答案。如果这是为了面试,那么我们需要考虑这些方法的时间和空间复杂性。如果是应用程序,您无需担心。看问题,这似乎是面试问题,因为那个 OP 需要考虑这些事情,因为下一个问题将是这个算法的复杂性
标签: javascript time-complexity big-o complexity-theory space-complexity