toString 时间和 space 复杂度
toString time and space complexity
给定以下方法:
public String toString()
{
if (_head == null)
return "";
String S="";
WordNode currentNode = _head;
while (currentNode != null)
{
S+=currentNode.getWord()+" ";
currentNode = currentNode.getNext();
}
return S;
}
什么是时间和 space 复杂性?
在 Java 中,String 是不可变对象。它如何影响复杂性?
谢谢
时间复杂度为 O(n),其中 n 是节点数,因为您对每个节点迭代一次。 Space 复杂度实际上是 O(n*m),其中 n 是节点数,m 是您将创建的最大字符串的长度(这是包含所有单词的最后一个字符串)。这是因为您创建了 n 个字符串,并且在 java 中创建的字符串的内存使用量与字符串中的字符数成正比(在您的情况下是最大 m)。如果您想准确查看创建字符串使用了多少内存,请参阅此 link:http://www.javamex.com/tutorials/memory/string_memory_usage.shtml.
顺便说一句,您实际上并不需要在函数的开头进行 if 检查,因为如果 head 为 null,您的 while 循环将不会进行任何迭代,并且您将 return 无论如何都是一个空字符串。去掉这个条件将使你的时间性能提高一个常数因子(但时间复杂度当然是一样的)。
时间复杂度为O(L*N)
,其中N
是节点数,L
是结果字符串的长度:
如果除第一个节点以外的所有节点都包含一个长度为 1 的字符串,并且第一个节点包含一个字符串 L-2*(N-1)-1
。然后存储在 S
中的字符串在循环迭代中的长度为
L-2*(N-1)
L-2*(N-2)
L-2*(N-3)
...
L
这些值的总和在 O(L*N)
中。由于分配字符串所花费的时间与字符串大小成正比,因此该算法的时间复杂度为 O(N*L)
.
space 复杂度为 O(L)
,因为存储在 S
中的字符串的长度在 O(L)
中,并且垃圾收集器可以回收先前迭代的中间结果作为一旦 S
被覆盖。
您可以使用 StringBuilder
.
将其改进为 space 和时间复杂度 O(L)
public String toString()
{
if (_head == null)
return "";
StringBuilder S=new StringBuilder();
WordNode currentNode = _head;
while (currentNode != null)
{
S.append(currentNode.getWord()).append(" ");
currentNode = currentNode.getNext();
}
return S.toString();
}
每个迭代 n 项的循环的时间复杂度为 O(n)。当你在另一个循环中嵌套循环时
while(...) {
while(...) {
...
}
}
它变成了 O(n^2) 等等。
由于您只使用一个循环,因此您的方法时间复杂度为 O(n)。
给定以下方法:
public String toString()
{
if (_head == null)
return "";
String S="";
WordNode currentNode = _head;
while (currentNode != null)
{
S+=currentNode.getWord()+" ";
currentNode = currentNode.getNext();
}
return S;
}
什么是时间和 space 复杂性? 在 Java 中,String 是不可变对象。它如何影响复杂性? 谢谢
时间复杂度为 O(n),其中 n 是节点数,因为您对每个节点迭代一次。 Space 复杂度实际上是 O(n*m),其中 n 是节点数,m 是您将创建的最大字符串的长度(这是包含所有单词的最后一个字符串)。这是因为您创建了 n 个字符串,并且在 java 中创建的字符串的内存使用量与字符串中的字符数成正比(在您的情况下是最大 m)。如果您想准确查看创建字符串使用了多少内存,请参阅此 link:http://www.javamex.com/tutorials/memory/string_memory_usage.shtml.
顺便说一句,您实际上并不需要在函数的开头进行 if 检查,因为如果 head 为 null,您的 while 循环将不会进行任何迭代,并且您将 return 无论如何都是一个空字符串。去掉这个条件将使你的时间性能提高一个常数因子(但时间复杂度当然是一样的)。
时间复杂度为O(L*N)
,其中N
是节点数,L
是结果字符串的长度:
如果除第一个节点以外的所有节点都包含一个长度为 1 的字符串,并且第一个节点包含一个字符串 L-2*(N-1)-1
。然后存储在 S
中的字符串在循环迭代中的长度为
L-2*(N-1)
L-2*(N-2)
L-2*(N-3)
...
L
这些值的总和在 O(L*N)
中。由于分配字符串所花费的时间与字符串大小成正比,因此该算法的时间复杂度为 O(N*L)
.
space 复杂度为 O(L)
,因为存储在 S
中的字符串的长度在 O(L)
中,并且垃圾收集器可以回收先前迭代的中间结果作为一旦 S
被覆盖。
您可以使用 StringBuilder
.
O(L)
public String toString()
{
if (_head == null)
return "";
StringBuilder S=new StringBuilder();
WordNode currentNode = _head;
while (currentNode != null)
{
S.append(currentNode.getWord()).append(" ");
currentNode = currentNode.getNext();
}
return S.toString();
}
每个迭代 n 项的循环的时间复杂度为 O(n)。当你在另一个循环中嵌套循环时
while(...) {
while(...) {
...
}
}
它变成了 O(n^2) 等等。
由于您只使用一个循环,因此您的方法时间复杂度为 O(n)。