赞
踩
1. 官方链接
2. 题目:
给你单链表的头节点
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
进阶:链表可以选用迭代或递归方式完成反转。你能否用两种方法解决这道题?
3. 方案
解决方式1:
迭代链表,每次new一个节点,并将老节点放入newNode 的next
我认为这种很容易理解,当然缺点就是每次new一个对象
- package com.nami.algorithm.study.chain2;
-
- /**
- * 描述: 反转链表
- * <p>
- * 构造一个新链表,从旧链表依次拿到每个节点,创建新节点添加至新链表头部,完成后新链表即是倒序的
- *
- * @Author: lbc
- * @Date: 2024-04-16 18:39
- * @email: 594599620@qq.com
- * @Description: keep coding
- */
- public class ChainTest {
-
- /**
- * 每次新增一个node 将 next 指向上一个节点。
- *
- * @param node
- * @return
- */
- public static ListNode reverse(ListNode node) {
- ListNode head = null;
- ListNode cur = node;
- while (cur != null) {
- // new一个新节点,将老的放到新节点next
- ListNode o1 = new ListNode(cur.value, head);
- head = o1;
- cur = cur.next;
- }
- return head;
- }
-
- public static void main(String[] args) {
- ListNode n5 = new ListNode(5, null);
- ListNode n4 = new ListNode(4, n5);
- ListNode n3 = new ListNode(3, n4);
- ListNode n2 = new ListNode(2, n3);
- ListNode n1 = new ListNode(1, n2);
-
- ListNode reverse = reverse(n1);
-
- while (reverse != null) {
- System.out.println(reverse.value);
- reverse = reverse.next;
- }
-
- }
-
- static class ListNode {
-
- protected int value;
-
- protected ListNode next;
-
- public ListNode(int value, ListNode next) {
- this.value = value;
- this.next = next;
- }
-
- }
-
- }
方法2:
使用自定义容器类,链表放入容器类。使用容器方法removeFirst, addFirst 将老链表数据转换新容器对象内
- package com.nami.algorithm.study.chain3;
-
- /**
- * 描述:
- * 单项链表反转
- *
- * @Author: lbc
- * @Date: 2024-04-16 20:49
- * @email: 594599620@qq.com
- * @Description: keep coding
- */
- public class ChainTest {
-
- /**
- * 构造一个新链表,从旧链表头部移除节点,添加到新链表头部,完成后新链表是倒序的,
- * 使用两个自定义容器,容器内有移除与新增方法
- *
- * @param node
- * @return
- */
- public static ListNode reverse(ListNode node) {
- ChainList result = new ChainList(null);
- ChainList list = new ChainList(node);
- while (true) {
- ListNode listNode = list.removeFirst();
- if (listNode == null) {
- break;
- }
- result.addFirst(listNode);
- }
-
- return result.head;
- }
-
-
- public static void main(String[] args) {
-
- ListNode n5 = new ListNode(5, null);
- ListNode n4 = new ListNode(4, n5);
- ListNode n3 = new ListNode(3, n4);
- ListNode n2 = new ListNode(2, n3);
- ListNode n1 = new ListNode(1, n2);
-
- ListNode node = reverse(n1);
-
- while (node != null) {
- System.out.println(node.value);
- node = node.next;
- }
- }
-
-
- /**
- * 容器类
- * 核心 removeFirst
- * addFirst
- */
- static class ChainList {
- private ListNode head;
-
- public ChainList(ListNode head) {
- this.head = head;
- }
-
- public void addFirst(ListNode node) {
- node.next = head;
- head = node;
- }
-
- public ListNode removeFirst() {
- if (head == null) {
- return null;
- }
- ListNode first = head;
- head = head.next;
- return first;
- }
-
- }
-
- static class ListNode {
-
- protected int value;
-
- protected ListNode next;
-
- public ListNode(int value, ListNode next) {
- this.value = value;
- this.next = next;
- }
-
- }
-
-
- }
方法3:
头插法
- package com.nami.algorithm.study.chain;
-
- /**
- * 描述: 反转链表
- * 头插法
- *
- * @Author: lbc
- * @Date: 2024-04-17 9:38
- * @email: 594599620@qq.com
- * @Description: keep coding
- */
- public class ChainTest {
-
- public static ListNode reverseNode(ListNode head) {
- ListNode prev = null;
-
- ListNode cur = head;
-
- while (cur != null) {
- // 这样好理解 ==! 但是感觉跟方法一 差不多
- ListNode node = new ListNode(cur.value, cur.next);
- node.next = prev;
- prev = node;
-
- // 循环
- cur = cur.next;
- }
-
- return prev;
- }
-
-
- public static ListNode reverseNode2(ListNode head) {
- // 最终节点
- ListNode prev = null;
- // 当前节点
- ListNode cur = head;
-
- while (cur != null) {
- // 想想上面的reverseNode() 方法不难,主要是解决一个 ”引用问题“
- // 相当于将cur = cur.next; 放在第一行。拿出next节点。防止cur.next 这个循环条件被污染
- // 建议比较方法1 比较着看
- ListNode next = cur.next;
-
- cur.next = prev;
-
- prev = cur;
-
- // 循环
- cur = next;
- }
-
- return prev;
- }
-
-
- public static void main(String[] args) {
-
- ListNode n1 = new ListNode(1);
- ListNode n2 = new ListNode(2);
- ListNode n3 = new ListNode(3);
- ListNode n4 = new ListNode(4);
- ListNode n5 = new ListNode(5);
-
- n1.next = n2;
- n2.next = n3;
- n3.next = n4;
- n4.next = n5;
-
- ListNode listNode = reverseNode2(n1);
-
- while (listNode != null) {
- System.out.println(listNode.value);
- listNode = listNode.next;
- }
-
- }
-
-
- static class ListNode {
-
- protected int value;
-
- protected ListNode next;
-
- public ListNode(int value) {
- this.value = value;
- }
-
- public ListNode(int value, ListNode next) {
- this.value = value;
- this.next = next;
- }
-
- }
-
- }
方法4:
还是使用容器
采用栈,先进后出思路解决
- package com.nami.algorithm.study.chain;
-
- import java.util.Stack;
-
- /**
- * 描述: 反转链表
- * 头插法
- *
- * @Author: lbc
- * @Date: 2024-04-17 9:38
- * @email: 594599620@qq.com
- * @Description: keep coding
- */
- public class ChainTest2 {
-
- public static ListNode reverseNode(ListNode head) {
- Stack<ListNode> stack = new Stack<>();
- while (head != null) {
- stack.push(head);
- head = head.next;
- }
- if (stack.isEmpty()) {
- return null;
- }
- ListNode newHead = stack.pop();
- head = newHead;
- while (!stack.isEmpty()) {
- head.next = stack.pop();
- head = head.next;
- }
- head.next = null;
- return newHead;
- }
-
-
- public static void main(String[] args) {
-
- ListNode n1 = new ListNode(1);
- ListNode n2 = new ListNode(2);
- ListNode n3 = new ListNode(3);
- ListNode n4 = new ListNode(4);
- ListNode n5 = new ListNode(5);
-
- n1.next = n2;
- n2.next = n3;
- n3.next = n4;
- n4.next = n5;
-
- ListNode listNode = reverseNode(n1);
-
- while (listNode != null) {
- System.out.println(listNode.value);
- listNode = listNode.next;
- }
-
- }
-
-
- static class ListNode {
-
- protected int value;
-
- protected ListNode next;
-
- public ListNode(int value) {
- this.value = value;
- }
-
- public ListNode(int value, ListNode next) {
- this.value = value;
- this.next = next;
- }
-
- }
-
- }
方法5:
递归方式
- package com.nami.algorithm.study.chain;
-
- /**
- * 描述: 反转链表
- * 头插法
- *
- * @Author: lbc
- * @Date: 2024-04-17 9:38
- * @email: 594599620@qq.com
- * @Description: keep coding
- */
- public class ChainTest3 {
-
- /**
- * 递归 注意层数问题,别 stackOverFlow 喽
- * 堆栈溢出异常
- *
- * @param head
- * @return
- */
- public static ListNode reverseNode(ListNode head) {
- if (head == null || head.next == null) {
- return head;
- }
-
- ListNode last = reverseNode(head.next);
- head.next.next = head;
- head.next = null;
- return last;
- }
-
-
- public static void main(String[] args) {
-
- ListNode n1 = new ListNode(1);
- ListNode n2 = new ListNode(2);
- ListNode n3 = new ListNode(3);
- ListNode n4 = new ListNode(4);
- ListNode n5 = new ListNode(5);
-
- n1.next = n2;
- n2.next = n3;
- n3.next = n4;
- n4.next = n5;
-
- ListNode listNode = reverseNode(n1);
-
- while (listNode != null) {
- System.out.println(listNode.value);
- listNode = listNode.next;
- }
-
- }
-
-
- static class ListNode {
-
- protected int value;
-
- protected ListNode next;
-
- public ListNode(int value) {
- this.value = value;
- }
-
- public ListNode(int value, ListNode next) {
- this.value = value;
- this.next = next;
- }
-
- }
-
- }
最后:
如果觉得困难 建议debug, 跟下。 多看代码,多思考,相信很快就明白了
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。