Java中反转LinkedList的大好时机

Java中反转LinkedList的大好时机,java,big-o,Java,Big O,请告知在这两种情况下,最大的问题是什么。我知道基本情况是常量O(1),但我不知道如何计算其余部分和递归。 案例1 公共ListNode反向1(ListNode列表){ if(list==null | | list.next==null){ 退货清单; } ListNode after=反向(list.next); list.next.next=列表; list.next=null; 返回后; } 案例2 public ListNode reverse2(ListNode列表){ if(lis

请告知在这两种情况下,最大的问题是什么。我知道基本情况是常量
O(1)
,但我不知道如何计算其余部分和递归。

案例1
公共ListNode反向1(ListNode列表){
if(list==null | | list.next==null){
退货清单;
}
ListNode after=反向(list.next);
list.next.next=列表;
list.next=null;
返回后;
}
案例2
public ListNode reverse2(ListNode列表){
if(list==null | | list.next==null){
退货清单;
}
ListNode after=reverse2(list.next);
ListNode温度=之后;
while(temp.next!=null){
温度=下一个温度;
}
temp.next=列表;
list.next=null;
返回后;
}

在第一种情况下递归给出:

T(n) = T(n-1) + c 
T(n) = T(n-1) + n + c 
其中
T(n)
是n个节点的总体步骤,为了反转
n
节点,您只需在
T(n-1)
中反转
n-1
,并通过执行成本
c
的常量操作添加第n个节点(常量值无关紧要)

上述递归关系很容易看出,导致:

T(n) = T(n-1) + c = T(n-2) + 2c =...= nc = O(n)
T(n) = T(n-1) + n +c = T(n-2) + n + (n-1) + 2c =...= n(n-1)/2 +nc = O(n^2)
在第二种情况下递归给出:

T(n) = T(n-1) + c 
T(n) = T(n-1) + n + c 
这是因为,为了反转n个节点,您在
T(n-1)
中反转
n-1
,然后遍历列表,以便将节点放在末尾,该节点花费n,而常量操作花费最多c(c不重要)

上述递归关系很容易看出,导致:

T(n) = T(n-1) + c = T(n-2) + 2c =...= nc = O(n)
T(n) = T(n-1) + n +c = T(n-2) + n + (n-1) + 2c =...= n(n-1)/2 +nc = O(n^2)
案例#1a(不是答案)

对于那些希望看到(一个版本的)干净的递归列表反转的人。 尤其是没有下一个,下一个

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

案例#1是不正确的,但是O(n)作为反向访问列表中的每个节点,函数本身只做O(1)件事情。案例2每次遍历部分列表(n/2),O(n²)也是如此。当然,在O(n)中可以正确地进行反转。非常感谢你,弗兰克!这是非常有帮助的。我很难理解T(…)和O(…)之间的区别/关系,如何得出这样的计算结果。你介意澄清一下是否有一种简单的方式来思考这个问题吗?再次感谢再次感谢你!在第二种情况下,如果只给出两个选择:T(N)=T(N-1)+O(1)或T(N)=T(N-1)+O(N),您会选择哪一个?当然,我们使用T(…)表示总步骤(使用您想要的任何字母,但通常使用T)。只有通过练习才能找到T(N),例如,如果您有一个循环,可能很容易,如果你有一个递归关系,比如你的问题T(n)等于用于子问题的T,例如T(n-1)+T(n-2)(如果你把你的问题分解成用n-1,n-2计算),或者它可以是基于你递归计算的子问题的任何东西,并且为了找到T(n),在每个步骤中添加你所做的任何操作,例如:T(n)=T(n-1)+c意味着你在计算T(n-1)和一些常数运算时,你的问题被打破了…(待续)这就是为了求T(n)通常应该如何思考…现在求大O取决于你已经找到的T(n)。如果你有一个递归关系T(n),你可能会发现
主定理
有助于找到大O,在你的特殊情况下,这是很容易的,因为
T(n)=T(n-1)+c
可以很容易地手工计算。。。一般来说,大O用来表示渐近行为,这就是为什么常数不重要。对于你的第二个问题,我肯定会选择
t(N)=t(N-1)+O(N)
,因为你需要解释的O(N)个步骤,我在我的解释中写道:
t(N)=t(N-1)+N+c
,可以写成
t(N)=t(N-1)+O(N)<代码> <代码> n+c是O(n)< /代码>,如果我的答案解决了你的问题,考虑接受它,很乐意帮助!!