用于在Java中反转LinkedList的BIg-Oh

时间:2017-10-29 23:52:29

标签: java big-o

请告知在这两种情况下Big-O会是什么。我理解基本情况是常量O(1),但我很困惑如何计算其余部分和递归。

案例#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;
}

案例#2

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;
}

2 个答案:

答案 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);
}