[leetcode] Reverse Linked List
Posted Lin.B
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[leetcode] Reverse Linked List相关的知识,希望对你有一定的参考价值。
1、Reverse Linked ListⅠ
Reverse a singly linked list.
Example:
Input: 1->2->3->4->5->NULL Output: 5->4->3->2->1->NULL
Follow up:
A linked list can be reversed either iteratively or recursively. Could you implement both?
分析:链表的翻转,时链表类题目里最基础的了,和判断链表是否有环一样。是链表里面必须掌握的两个方法。
用栈来做当然也是可以的,不过空间复杂度高了。所以用时间复杂度为O(n)空间复杂度为O(1)的方法。思路也比较清晰,用三个指针,从前向后遍历链表。
根据上面的思路,得到代码如下:
1 class Solution { 2 public ListNode reverseList(ListNode head) { 3 ListNode p,q,ptr; 4 p = head; 5 q = null; 6 while( p != null ){ 7 ptr = p.next; 8 p.next = q; 9 q=p; 10 p = ptr; 11 } 12 return q; 13 } 14 }
运行时间0ms。
2、Reverse Linked List II
Reverse a linked list from position m to n. Do it in one-pass.
Note: 1 ≤ m ≤ n ≤ length of list.
Example:
Input: 1->2->3->4->5->NULL, m = 2, n = 4 Output: 1->4->3->2->5->NULL
分析:第二个问题也是翻转链表,但是要求m—n位置翻转,其余位置不变。其实思路还是上面的思路,只是可以增加一个累加表示访问到的位置。
这个问题可以分为三段来考虑,比如1->2->3->4->5->null,翻转2到4位置,就分成三段,1->null,2->3->4,5->null,这里标红要注意不能空指。
步骤其实很简单,我们主要的工作还是翻转中间那段,变成:2<-3<-4。然后,1指到4,2指到5。这样就完成了链表的翻转。
由此可见我们需要四个指针,第一个指针first0指向第一段最后一个节点,first1指向要翻转的那段第一个节点,q指向要翻转的那段最后一个节点,ptr指向最后一段第一个节点。
这里一定要注意将三段拼接起来的时候要注意分类讨论:第一种情况是从开头到最后全部翻转,第二种情况是从开头开始翻转到中间某个位置,第三种情况是从中间某个位置反转到最后,第四种情况是从中间某个位置到中间某个位置翻转。因为不同的情况,指针指向的位置是不同的。
还是看代码比较清晰:
1 class Solution { 2 public ListNode reverseBetween(ListNode head, int m, int n) { 3 if ( m >= n ) return head; 4 ListNode p,q,ptr = null; 5 ListNode first0 = head,first1; 6 p = head; 7 q = null; 8 int count = 1; 9 while ( count < m ){ 10 first0 = p; 11 p = p.next; 12 count++; 13 } 14 //此时,p指针指向第一个要变动的位置,first0指针指向最后一个不变的元素。 15 first1 = p; 16 while ( count <= n ){ 17 ptr = p.next; 18 p.next = q; 19 q = p; 20 p = ptr; 21 count ++; 22 } 23 //此时完成m—n位置的翻转,然后拼接上三段 24 //注意这里分类讨论。第一种情况是全部翻转,第二种情况是从开头开始翻转到中间某个位置,第三种情况是从中间某个位置反转到最后,第四种情况是从中间某个位置到中间某个位置翻转。 25 if ( ptr == null && first0 == first1) { 26 return q; 27 } 28 if ( ptr == null ){ 29 first0.next = q; 30 return head; 31 } 32 if ( first0 == first1 ){ 33 first1.next = ptr; 34 return q; 35 } 36 first1.next = ptr; 37 first0.next = q; 38 return head; 39 } 40 }
运行时间2ms,基本上应该是最快的解法了。时间复杂度O(n),空间复杂度O(1)。
以上是关于[leetcode] Reverse Linked List的主要内容,如果未能解决你的问题,请参考以下文章
LeetCode 92. Reverse Linked List II
#Leetcode# 92. Reverse Linked List II
Leetcode 206 Reverse Linked List 链表