题目
反转一个单链表。
示例:
输入: 1->2->3->4->5->NULL
输出: 5->4->3->2->1->NULL
进阶:
- 你可以迭代或递归地反转链表。你能否用两种方法解决这道题?
方法一——暴力解法
建立一个新链表,新链表是采用头插法建立的。
时间复杂度与空间复杂度都是O(n)
public class ReverseList {
//Definition for singly-linked list.
public static class ListNode{
int val;
ListNode next;
ListNode(){
}
ListNode(int x){
this.val = x;
}
ListNode(int x, ListNode next){
this.val = x;
this.next = next;
}
}
//思路一头插法(无头结点)
public static ListNode reverseList(ListNode head) {
if(head == null || head.next == null) return head;
ListNode list = head,p = head.next, q;
list.next = null;
//头插法,没有头结点
while(p != null){
q = p.next;
p.next = list;
list = p;
p = q;
}
return list;
}
public static void main(String[] args) {
ListNode list = new ListNode(1, new ListNode(2, new ListNode(3, new ListNode(4, new ListNode(5, null)))));
ListNode ret = ReverseList.reverseList(list);
//System.out.println(ret.next);
while(ret!= null) {
System.out.print(ret.val + " ");
ret = ret.next;
}
}
}
方法二——迭代方法
降低空间复杂度为O(1) ,将链表指针原地反转,本质上依然是头插法。
class Solution {
public ListNode reverseList(ListNode head) {
if(head == null || head.next == null) return head;
ListNode pre,cur, pro;
pre = head;
cur = head.next;
pre.next = null;
while(cur != null){
pro = cur.next;
cur.next = pre;
pre = cur;
cur = pro;
}
return pre;
}
}
方法三——递归
递归包括递归表达式和递归终止条件。
public ListNode reverseList(ListNode head) {
if(head == null || head.next == null) return head;
ListNode p = reverseList(head.next);//递归表达式
//p 和当前结点关系,以4->5为例,head = 4, head.next = 5,
//head.next.next = head也就是 5.next = 4;地址值唯一
head.next.next = head;//此时循环了
head.next = null;//防止循环
return p;
}