链表知识回顾
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;
}
}