剑指offer(十五)——反转链表
题目描述
输入一个链表,反转链表后,输出新链表的表头。
题解
简单一点的思路就是将该链表的值用数组或栈存储下来,然后用一条新链表存储下来即可实现反转。但是这种方法会消耗额外的空间,不是好方法。
一解:
public static ListNode ReverseList(ListNode head) {
if (head == null) {
return head;
}
Stack<Integer> tempStack = new Stack<>();
while (head != null) {
tempStack.push(head.val);
head = head.next;
}
ListNode resultList = new ListNode(tempStack.pop());
ListNode resultHead = resultList;
while(!tempStack.isEmpty()) {
ListNode tempList = new ListNode(tempStack.pop());
resultList.next = tempList;
resultList = tempList;
}
return resultHead;
}
二解:
第二种就是把原链表解开进行反转链接,这种做法的时间复杂度为O(n),只需要有三个指针就可以实现。
public static ListNode ReverseList(ListNode head) {
if (head == null || head.next == null) {
return head;
}
ListNode postNode = null;
ListNode preNode = null;
while(head != null) {
postNode = head.next;
head.next = preNode;
preNode = head;
head = postNode;
}
return preNode;
}
下面用图来讲解一下如何操作的。
- 首先两个指针pre和post,pre指向当前结点的前一个结点,post指向当前结点的后一个结点,一个指针head指向当前结点。
- 当判断到当前结点a不为空时,post指向结点b,并使结点a指向pre。
- 然后再移动pre到当前结点a,并移动head到下一个结点。(因为post在结点a时就已经指向b,因此head=post即可移动head到下一个结点)
- 直到当前结点为空时,返回pre指针即可。