翻转单链表
问题描述:
原始单链表 1->2->3->4->5
翻转后单链表5->4->3->2->1
问题思路:
第一种解题思路:可创建新链表,创建一个虚拟头节点,遍历原始数组,采用头插法输出即可。
第二种解题思路:不创建新链表,在现有链表的基础上进行翻转。如:
hummyHead->1->2->3->4->5;(原始链表)
f s
hummyHead->2->1->3->4->5;(翻转一次)
f s
hummyHead->3->2->1->4->5;(翻转第二次,将已翻转好的可看作一个整体)
f s
hummyHead->4->3->2->1->5;
f s
hummyHead->5->4->3->2->1.
按照此思路,我们翻转过程中需要三个指针,第一个是固定不变的虚拟头节点hummyHead,第二个是头节点f,第三个是f.next=s,翻转过程中将已翻转好的节点看作整体就是只需要知道f.next即可,s要确保一直在f之后。
核心算法图解:
第一种方法源代码:
class ListNode {
int val;
ListNode next;
ListNode(int x) {
val = x;
}
}
class Solution {
public static ListNode reverseList(ListNode head) {
ListNode fir=new ListNode(-1);//创建新虚拟头节点
for(ListNode temp=head;temp!=null;temp=temp.next){//遍历数组确保以头插法输出的链表长度
//头插法
ListNode newnode=new ListNode(temp.val);
newnode.next=fir.next;
fir.next=newnode;
}
return fir.next;//返回头节点
}
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 prev=reverseList(listNode1);
for(ListNode temp=prev;temp!=null;temp=temp.next){
System.out.print(temp.val+"->");
}
}
}
第二种方法源代码:
class ListNode {
int val;
ListNode next;
ListNode(int x) {
val = x;
}
}
class Solution {
public static ListNode reverseList(ListNode head) {
ListNode dummyHead = new ListNode(-1);//虚拟头节点数据域无意义,可随便定义数字或置为null
dummyHead.next = head;
//若为空链表或只有一个节点,即可直接返回头节点
if (head == null || head.next == null) {
return head;
} else {//大于等于两个节点的链表
ListNode f = dummyHead.next;
ListNode s = f.next;
while (s != null) {//确保翻转次数
f.next = s.next;
s.next = dummyHead.next;
dummyHead.next = s;
s = f.next;
}
}
return dummyHead.next;
}
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 prev=reverseList(listNode1);
for(ListNode temp=prev;temp!=null;temp=temp.next){//链表遍历
System.out.print(temp.val+"->");
}
}
}