我GitHub上的:剑指offer题解
反转链表
输入一个链表,反转链表后,输出链表的所有元素。
先定义一个结点类
public class ListNode {
int val;
ListNode next = null;
public ListNode(int val) {
this.val = val;
}
}
思路一:递归反转法
采用递归的方法:在反转当前结点时,先反转后续所有结点。这样从头结点开始,层层深入直至尾结点才开始反转指针域的指向。
public static ListNode reverseList1(ListNode head) {
if (head == null || head.next == null) {
return head;
}
ListNode next = head.next;
head.next = null;
ListNode newHead = reverseList1(next);
next.next = head;
return newHead;
}
思路二:遍历反转法
遍历反转法:从前往后对当前结点进行反转。利用三个指针进行反转:一个指针指向当前结点;一个指针指向当前结点的下一个结点;最后一个指针指向新链表表头从而保存结果
public static ListNode reverseList2(ListNode head) {
if (head == null || head.next == null) {
return head;
}
ListNode current = head;
ListNode next = null;
ListNode newHead = null;
while(current != null){
//保存当前结点的下一个结点
next = current.next;
current.next = newHead;//将原来的链表断链,将current的下一个结点指向新链表的头结点
newHead = current;//将current设为新表头
current = next; //将之前保存的next设为当前结点
}
return newHead;
}
测试函数:
public static void main(String[] args) {
ListNode listNode1 = new ListNode(1);
ListNode listNode2 = new ListNode(2);
ListNode listNode3 = new ListNode(3);
ListNode listNode4 = new ListNode(4);
ListNode listNode5 = new ListNode(5);
listNode1.next = listNode2;
listNode2.next = listNode3;
listNode3.next = listNode4;
listNode4.next = listNode5;
//打印前的链表
ListNode head = listNode1;
while (head != null) {
System.out.print(head.val + " ");
head = head.next;
}
ListNode newList = reverseList2(listNode1);
System.out.println("");
//打印后的链表
ListNode h = newList;
while (h != null) {
System.out.print(h.val + " ");
h = h.next;
}