一、用反复的方法做(Iteration)
//signature. We need input a head of Linked List and return a new head of
//Linked List.
public ListNode reverse(ListNode head){
//I need to assume if this Linked List is null? or only have one element?
//we just need to return itself.
if(head == null || head.next == null){
return head;
}
//I need three pointers to assign. The head need to point to null.
ListNode prev = null;
ListNode cur = head;
ListNode next = null;
// n1 -> n2 -> n3 -> n4 -> null
//prev cur next
while(cur != null){
next = cur.next;
cur.next = prev;
prev = cur;
cur = next;
}
return prev;
}
Wrong:
1、把return 写错了。本来写的return cur。因为最后cur.next = prev 后,cur还需要往后挪一个,就挪到null了,所以需要返回prev。
2、while循环里写错了。死记硬背了。以后while里需要想一下。
思考:
我们真的需要一个cur去储存吗?不需要。因为我们最后返回的是prev,所以可以直接娜头节点,不需要cur来保存头节点。
//signature is the same as above
public ListNode reverse(ListNode head){
if(head == null || head.next == null){
return head;
}
// n1 -> n2 -> n3 -> n4 -> null
//prev head next
ListNode prev = null;
ListNode next = null;
while(cur != null){
next = head.next;
head.next = prev;
prev = head;
head = next;
}
return prev;
}
-
Time Complexity:O(n)
-
Space Complexity: O(1)
二、用递归的方法做(Recursion)
// n1 -> n2 -> n3 -> n4 -> null
public LitNode reverse(ListNode head){
//base case
if(head == null || head.next == null){
return head;
}
//subProblem
ListNode newNode = reverse(head.next);
head.next.next = head;
head.next = null;
return newNode;
}
Q1:为什么base case是这样写的呀? 是不是把base case 和 corner case结合到一起了?如果我确定我的head != null,是不是base case就可以写成if(head.next == null){return head;} -是的。
Q2:为什么ListNode newNode = reverse(head.next);写到前面?因为写到后面的话head.next就赋给了null,就不对了。所以recursion都是先处理subproblem?就是的因为要先把子问题处理好,才能处理最开始的问题。靠后面问题得到自己的问题。
-
Time complexity: O(n)
-
Space complexity: O(n)