题目
定义一个函数,输入一个链表的头结点,反转该链表并输出反转后的链表。
解题思路
1 暴力法
借助外部空间实现。这里可以将单链表节点储存到链表中,然后按照链表的索引逆序进行反转。
package Arithmetic;
import java.util.ArrayList;
import java.util.List;
public class ReverseListNode {
class ListNode {
private int val;//节点值
private ListNode next;//下一个节点
public ListNode(int val) {
this.val = val;
}
//从头到尾打印链表节点
@Override
public String toString() {
String result = "";//保存结果
ListNode head = this;//当前结点
while (head != null) {
result += head.val;
if (head.next != null)
result += "-->";
head = head.next;
}
return result;
}
}
//暴力法
public static ListNode ReverseListNode(ListNode head) {
if (head == null)
return null;
List<ListNode> listNodes = new ArrayList<>();//用来保存链表节点
while (head != null) {
listNodes.add(head);//保存节点
head = head.next;
}
for (int i = listNodes.size() - 1; i >= 0; i--) {//从后往前遍历
ListNode listNode = listNodes.get(i);
if (i == 0) {
listNode.next = null;
} else {
listNode.next = listNodes.get(i - 1);
}
}
head = listNodes.get(listNodes.size() - 1);//现在的头结点为链表的尾结点
return head;
}
public static void main(String[] args) {
ReverseListNode reverseListNode = new ReverseListNode();
ListNode listNode1 = reverseListNode.new ListNode(1);
ListNode listNode2 = reverseListNode.new ListNode(2);
ListNode listNode3 = reverseListNode.new ListNode(3);
listNode1.next = listNode2;
listNode2.next = listNode3;
System.out.print("链表反转前:");
System.out.println(listNode1);
System.out.print("链表反转后:");
System.out.println(ReverseListNode(listNode1));
}
}
2 递归
原地反转,不借助外部空间,在O(n)的时间复杂度内完成。
package Arithmetic;
public class ReverseListNode {
class ListNode {
private int val;//节点值
private ListNode next;//下一个节点
public ListNode(int val) {
this.val = val;
}
//从头到尾打印链表节点
@Override
public String toString() {
String result = "";//保存结果
ListNode head = this;//当前结点
while (head != null) {
result += head.val;
if (head.next != null)
result += "-->";
head = head.next;
}
return result;
}
}
//递归
public static ListNode ReverseListNode(ListNode head) {
if (head == null || head.next == null)
return head;
ListNode next = head.next;//保存头节点的next
head.next = null;//将头节点与链表断开
ListNode neWHead = ReverseListNode(next);//递归
next.next = head;//后一个节点指向前一个结点
return neWHead;
}
public static void main(String[] args) {
ReverseListNode reverseListNode = new ReverseListNode();
ListNode listNode1 = reverseListNode.new ListNode(1);
ListNode listNode2 = reverseListNode.new ListNode(2);
ListNode listNode3 = reverseListNode.new ListNode(3);
listNode1.next = listNode2;
listNode2.next = listNode3;
System.out.print("链表反转前:");
System.out.println(listNode1);
System.out.print("链表反转后:");
System.out.println(ReverseListNode(listNode1));
}
}
3.迭代
创建辅助节点,从前往后依次取链表节点插入到辅助节点的后面(头插法)
package Arithmetic;
public class ReverseListNode {
class ListNode {
private int val;//节点值
private ListNode next;//下一个节点
public ListNode(int val) {
this.val = val;
}
//从头到尾打印链表节点
@Override
public String toString() {
String result = "";//保存结果
ListNode head = this;//当前结点
while (head != null) {
result += head.val;
if (head.next != null)
result += "-->";
head = head.next;
}
return result;
}
}
//迭代-头插法
public static ListNode ReverseListNode(ListNode head) {
ListNode newList = new ReverseListNode().new ListNode(-1);//辅助结点
while (head != null){
ListNode next = head.next;//取头节点作为待插入结点
head.next = newList.next;//头节点指向辅助结点的next
newList.next = head;//辅助结点指向头节点
head = next;//将头节点后移
}
return newList.next;
}
public static void main(String[] args) {
ReverseListNode reverseListNode = new ReverseListNode();
ListNode listNode1 = reverseListNode.new ListNode(1);
ListNode listNode2 = reverseListNode.new ListNode(2);
ListNode listNode3 = reverseListNode.new ListNode(3);
listNode1.next = listNode2;
listNode2.next = listNode3;
System.out.print("链表反转前:");
System.out.println(listNode1);
System.out.print("链表反转后:");
System.out.println(ReverseListNode(listNode1));
}
}