鏈表知識回顧
class Node {
private String data; // 節點值
private Node next; // 指針
public Node(String data) {
this.data = data;
}
public void setNext(Node next) { // 設置下一個節點
this.next = next;
}
public Node getNext() { // 返回當前節點的下一個節點
return this.next;
}
public String getData() { // 返回節點的值
return this.data;
}
}
java鏈表相關操作詳細示例(鏈表數據結構,頭插法尾插法建表,插入刪除查找節點,遍歷鏈表)
# 206 反轉鏈表
反轉一個單鏈表。你可以迭代或遞歸地反轉鏈表。
輸入: 1->2->3->4->5->NULL 輸出: 5->4->3->2->1->NULL
方法一:迭代(雙指針)
思路:申請兩個指針,第一個指針叫 pre,最初是指向 null 的。第二個指針 cur 指向 head,然後不斷遍歷 cur。每次迭代到 cur,都將 cur 的 next 指向 pre,然後 pre 和 cur 前進一位。都迭代完了(cur 變成 null 了),pre 就是最後一個節點了。
https://leetcode-cn.com/problems/reverse-linked-list/solution/dong-hua-yan-shi-206-fan-zhuan-lian-biao-by-user74/
// java
public ListNode reverseList(ListNode head) {
ListNode pre = null; // 新生成鏈表尾部null
ListNode cur = head; // 當前節點
while(cur != null){
ListNode temp = cur.next; // 臨時變量指向當前節點的後一個節點
//pre = cur;
cur.next = pre; // 修改指針指向(反轉)
pre = cur; // 移動pre指針到當前位置
cur = temp; // 當前位置後移
}
return pre;
}
/**javaScript
* Definition for singly-linked list.
* function ListNode(val) {
* this.val = val;
* this.next = null;
* }
*/
/**
* @param {ListNode} head
* @return {ListNode}
*/
var reverseList = function(head) {
let [pre, curr] = [null, head];
while(curr){
let temp = curr.next;
curr.next = pre;
pre = curr;
curr = temp;
}
return pre;
};
方法二:遞歸
遞歸的兩個條件:(1)終止條件是當前節點或者下一個節點==null (2)在函數內部,改變節點的指向,也就是 head 的下一個節點指向 head 遞歸函數那句
class Solution {
public ListNode reverseList(ListNode head) {
//遞歸終止條件是當前爲空,或者下一個節點爲空
if(head==null || head.next==null) {
return head;
}
//這裏的cur就是最後一個節點
ListNode cur = reverseList(head.next);
//這裏請配合動畫演示理解
//如果鏈表是 1->2->3->4->5,那麼此時的cur就是5
//而head是4,head的下一個是5,下下一個是空
//所以head.next.next 就是5->4
head.next.next = head;
//防止鏈表循環,需要將head.next設置爲空
head.next = null;
//每層遞歸函數都返回cur,也就是最後一個節點
return cur;
}
}