剑指OFFER24-反转链表
定义一个函数,输入一个链表的头节点,反转该链表并输出反转后链表的头节点。
示例:
输入: 1->2->3->4->5->NULL
输出: 5->4->3->2->1->NULL
限制:
0 <= 节点个数 <= 5000
方法一:使用栈
public class ListNode {
int val;
ListNode next;
ListNode(int x) {
val = x;
}
}
public ListNode reverseList(ListNode head) {
//方法一:用栈来解决
Stack<ListNode> stack = new Stack();
//将节点全部放到栈中
while (head != null) {
stack.push(head);
head = head.next;
}
//如果栈为空,返回null
if (stack.isEmpty()) {
return null;
}
//取出反转后的头节点
ListNode node = stack.pop();
//保留下来最后返回
ListNode endHead = node;
//当栈不为空时,取出节点
while (!stack.isEmpty()) {
ListNode tempNode = stack.pop();
//连接下个节点
node.next = tempNode;
//将指针后移
node = node.next;
}
//遍历完以后将最后节点的next指向null
node.next = null;
return endHead;
}
方法二:双链表
public ListNode reverseList(ListNode head) {
//方法二:双链表解决
//new一个新的链表头节点
ListNode newHead = null;
while (head != null) {
//首先保存访问节点的下一个节点
ListNode temp = head.next;
head.next = newHead;
//更新新链表的头节点
newHead = head;
head = temp;
}
return newHead;
}
方法三:递归
public ListNode reverseList(ListNode head) {
//方法三:递归解决
//终止条件是链表为空或者没有尾节点
if (head == null || head.next == null) {
return head;
}
//首先保存下一个节点
// ListNode next = head.next;
//反转完之后,next是链表的尾节点,把head放在尾节点之后,
//优化
ListNode reverse = reverseList(head.next);
head.next.next = head;
head.next = null;
return reverse;
}
public ListNode reverseList4(ListNode head) {
//方法四:尾递归
return reverseListInt(head, null);
}
private ListNode reverseListInt(ListNode head, ListNode newHead) {
if (head == null)
return newHead;
ListNode next = head.next;
head.next = newHead;
return reverseListInt(next, head);
}