輸入一個鏈表的頭結點,將這個鏈表反轉並輸出它的新的頭結點
/*
public class ListNode {
int val;
ListNode next = null;
ListNode(int val) {
this.val = val;
}
}*/
//方法一:
public class Solution {
public ListNode ReverseList(ListNode head) {
if(head==null) return null;
if(head.next==null)return head;
ListNode h1 = head;//h1指向初始頭結點,最後將初始頭結點的next域置空
ListNode p = null;//作爲h2的下一個節點,保證未被旋轉的後續節點,引用的存在
ListNode h2 = head.next; //h2總是指向下一個要被旋轉的節點
while(h2.next!=null){
p =h2.next;//p指向h2的下一個節點,保證未被旋轉的節點臨時頭結點的存在
h2.next = head;//當前旋轉節點的next指向已經旋轉完畢的頭結點位置
head = h2;//當前頭結點旋轉完畢,head重新指向新的頭結點
h2 = p;//h2指向下一個未被旋轉的臨時頭結點
if(h2.next==null){//如果此時h2的next域爲null,說明已經到原始鏈表尾部,不能在進行while循環
h2.next = head;//循環到最後一個節點時,不滿足循環條件,會跳出循環,所以加了一個if
head = h2;
break;
}
}
h1.next = null;
return head;
}
}
//方法二:**(其實我寫的這兩個差不多,爲什麼要寫相似的兩個?因爲我要學習區別使用p和p.next的區別)**
public class Solution {
public ListNode ReverseList(ListNode head) {
if(head==null)return null;
if(head.next==null) return head;
ListNode p = head.next;
ListNode q = null;
boolean flag = true;
while(p!=null){//判斷p是否爲空
q = p.next;//注意q可能爲空
p.next = head;//將新節點接入到反轉的列表中
if(flag) {head.next=null;flag = false;}//把第一次頭結點指向第二個節點的next域清空
head = p;//將頭結點移向新接入的節點上
p = q;//將q指向未加入反轉列表的臨時頭節點引用
// flag = false;//將標示量變爲false,後續不需要將next域置空,爲了優化程序把它挪到上邊if中去
}
return head;//返回頭結點
}
}