请告知在这两种情况下Big-O会是什么。我理解基本情况是常量O(1)
,但我很困惑如何计算其余部分和递归。
public ListNode reverse1(ListNode list) {
if (list == null || list.next == null) {
return list;
}
ListNode after = reverse(list.next);
list.next.next = list;
list.next = null;
return after;
}
public ListNode reverse2(ListNode list) {
if (list == null || list.next == null) {
return list;
}
ListNode after = reverse2(list.next);
ListNode temp = after;
while (temp.next != null) {
temp = temp.next;
}
temp.next = list;
list.next = null;
return after;
}
答案 0 :(得分:2)
在第一种情况下递归给出:
T(n) = T(n-1) + c
其中T(n)
是n个节点的总体步骤,为了反转n
个节点,只需在n-1
中反转T(n-1)
并通过执行常量操作添加第n个节点费用c
(常数值无关紧要)。
上述递归关系很容易看出导致:
T(n) = T(n-1) + c = T(n-2) + 2c =...= nc = O(n)
在第二种情况下递归给出:
T(n) = T(n-1) + n + c
那是因为为了反转n个节点,你在n-1
中反转T(n-1)
并遍历列表,以便将节点置于最终成本为n且成本不变的运算成本最多c(c并不重要)。
上述递归关系很容易看出导致:
T(n) = T(n-1) + n +c = T(n-2) + n + (n-1) + 2c =...= n(n-1)/2 +nc = O(n^2)
答案 1 :(得分:0)
案例#1a (不是答案)
对于那些想要查看(一个版本)干净的递归列表反转的人。 特别是没有next.next。
public ListNode reverse1a(ListNode list) {
return reverse1rec(list, null);
}
/**
* Recursive reversal.
* Following the technique of shifting (to-do part, done part).
* @param list to be reversed (to-do).
* @param reversed already reversed earlier (done).
*/
public ListNode reverse1rec(ListNode list, ListNode reversed) {
if (list == null) {
return reversed;
}
ListNode remaining = list.next;
list.next = reversed;
reversed = list; // For clarity.
return reverse1rec(remaining, reversed);
}