【*E】leetcode-206. 反转链表【递归】

本文详细介绍了如何使用迭代和递归两种方法来反转单链表。在迭代法中,通过三指针法实现链表的翻转;而在递归法中,通过递归操作反转链表的剩余部分,然后连接头节点和新的头节点。两种方法的时间复杂度均为O(n),但递归法的空间复杂度稍高,为O(n)。
摘要由CSDN通过智能技术生成
package com.leetcode.easy;

import java.security.DrbgParameters.Reseed;

/*
 * 206. 反转链表
给你单链表的头节点 head ,请你反转链表,并返回反转后的链表。

 

示例 1:

输入:head = [1,2,3,4,5]
输出:[5,4,3,2,1]

示例 2:

输入:head = [1,2]
输出:[2,1]

示例 3:

输入:head = []
输出:[]

 

提示:

    链表中节点的数目范围是 [0, 5000]
    -5000 <= Node.val <= 5000

 

进阶:链表可以选用迭代或递归方式完成反转。你能否用两种方法解决这道题?
	 * 作者:LeetCode-Solution
	 * 链接:https://leetcode.cn/problems/reverse-linked-list
	 * biao-by-leetcode-solution-d1k2/ 来源:力扣(LeetCode)
	 * 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
 */
public class Hot206_reverseList {
	// -----------------------------------Solution1:迭代----------------------------------
	/*
	 * 三指针法。 假设链表为 1→2→3→∅1 ,我们想要把它改成 ∅←1←2←3
	 * 
	 * 在遍历链表时,将当前节点的 next 指针改为指向前一个节点。由于节点没有引用其前一个节点,因此必须事先存储其前一个节点。
	 * 在更改引用之前,还需要存储后一个节点。最后返回新的头引用。
	 * 
	 * 时间复杂度:O(n),其中 n 是链表的长度。需要遍历链表一次。
	 * 
	 * 空间复杂度:O(1)
	 */
	public static ListNode reverseList(ListNode head) {
		if (head == null || head.next == null)
			return head;
		// 三指针
		ListNode next = head.next, prev = null, cur = head;
		while (cur != null) {
			next = cur.next;
			cur.next = prev;
			prev = cur;
			cur = next;
		}
		return prev;
	}

	// -----------------------------------Solution2:递归----------------------------------
	/*
	 * 递归版本稍微复杂一些,其关键在于反向工作。假设链表的其余部分已经被反转,现在应该如何反转它前面的部分?
	 * 
	 * 假设链表为:
	 * 
	 * n1→…→nk−1→nk→nk+1→…→nm→∅
	 * 
	 * 若从节点 nk+1​ 到 nm 已经被反转,而我们正处于 nk。
	 * 
	 * n1→…→nk−1→nk→nk+1←…←nm​
	 * 
	 * 我们希望 nk+1​ 的下一个节点指向 nk​。
	 * 
	 * 所以,nk.next.next=nk​。
	 * 
	 * 需要注意的是 n1​ 的下一个节点必须指向 ∅。如果忽略了这一点,链表中可能会产生环。
	 * 
	 * 时间复杂度:O(n),其中 n 是链表的长度。需要对链表的每个节点进行反转操作。
	 * 
	 * 空间复杂度:O(n),其中 n 是链表的长度。空间复杂度主要取决于递归调用的栈空间,最多为 n 层。
	 * 
	 */
	public static ListNode reverseList2(ListNode head) {
		// BASE CASE 链表只有1-个节点
		if (head == null || head.next == null)
			return head;

		// CASE1: 链表有 2+个节点
		ListNode newHead = reverseList2(head.next);
		head.next.next = head;
		// 防止形成环
		head.next = null;

		return newHead;
	}

	// -----------------------------------main----------------------------------
	public static void main(String[] args) {
		ListNode head = new ListNode(1);
		head.next = new ListNode(2);
		head.next.next = new ListNode(3);
		head.next.next.next = new ListNode(4);
		head.next.next.next.next = new ListNode(5);
		ListNode.print(head);
		head = reverseList(head);
		ListNode.print(head);
	}
}

package com.leetcode.easy;

/**
 * Definition for singly-linked list.
 * 
 * @description:
 * @author:1252319301
 * @version:
 * @date: 2022年5月15日
 */

class ListNode {
	int val;
	ListNode next;

	ListNode() {
	}

	ListNode(int val) {
		this.val = val;
	}

	ListNode(int val, ListNode next) {
		this.val = val;
		this.next = next;
	}

	public static void print(ListNode head) {
		while (head != null) {
			System.out.print(head.val + " ");
			head = head.next;
		}
		System.out.println();
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值