目录
题目
定义一个函数,输入一个链表的头节点,反转该链表并输出反转后链表的头节点。
示例:
输入: 1->2->3->4->5->NULL 输出: 5->4->3->2->1->NULL
限制:
0 <= 节点个数 <= 5000
解题思路
可以瞬间想起来的思路有两个:
- 如果不想新建链表,那么便可以使用一个数组保存链表的每一个结点的数据域,最后从数组尾部开始反向填充原链表即可。
- 如果追求算法的效率,那么使用头插法创建链表是一个不错的选择。(给定一个数据序列,当使用尾插法创建链表时,链表数据域序列和数据序列相同;当使用头插法创建链表时,链表数据域序列和数据序列相反)
下面是一个使用头插法反转链表的示意图:
该算法的时间复杂度主要体现在循环操作上,循环次数为链表的结点数,因此一般情况下(结点个数多于2个),时间复杂度为O(N),其中N为链表的结点数量;由于没有借助任何辅助数组,因此空间复杂度为O(1)。
题解1
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public ListNode reverseList(ListNode head) {
//链表的长度
int size = 0;
//链表的数据
int[] value = new int[5000];
//填充
ListNode temp = head;
while(temp != null){
value[size++] = temp.val;
temp = temp.next;
}
//反向填充原链表
temp = head;
for(int i = size - 1;i >= 0;i--){
temp.val = value[i];
temp = temp.next;
}
return head;
}
}
题解2
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public ListNode reverseList(ListNode head) {
//空结点或者只有一个结点,反不反转都是自己
if(head == null || head.next == null){
return head;
}
//结点数量多余两个时,利用头插法反转
ListNode NewHead = null;
ListNode temp = null;
while(head != null){
NewHead = head;
head = head.next;
NewHead.next = temp;
temp = NewHead;
}
return NewHead;
}
}