当前位置:   article > 正文

LeetCode 206. 反转链表 java版 多种简单方式,总有一款适合你!超级简单易懂的反转链表 java_反转链表 java leetcode

反转链表 java leetcode

1. 官方链接

. - 力扣(LeetCode)

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一个对象

  1. package com.nami.algorithm.study.chain2;
  2. /**
  3. * 描述: 反转链表
  4. * <p>
  5. * 构造一个新链表,从旧链表依次拿到每个节点,创建新节点添加至新链表头部,完成后新链表即是倒序的
  6. *
  7. * @Author: lbc
  8. * @Date: 2024-04-16 18:39
  9. * @email: 594599620@qq.com
  10. * @Description: keep coding
  11. */
  12. public class ChainTest {
  13. /**
  14. * 每次新增一个node 将 next 指向上一个节点。
  15. *
  16. * @param node
  17. * @return
  18. */
  19. public static ListNode reverse(ListNode node) {
  20. ListNode head = null;
  21. ListNode cur = node;
  22. while (cur != null) {
  23. // new一个新节点,将老的放到新节点next
  24. ListNode o1 = new ListNode(cur.value, head);
  25. head = o1;
  26. cur = cur.next;
  27. }
  28. return head;
  29. }
  30. public static void main(String[] args) {
  31. ListNode n5 = new ListNode(5, null);
  32. ListNode n4 = new ListNode(4, n5);
  33. ListNode n3 = new ListNode(3, n4);
  34. ListNode n2 = new ListNode(2, n3);
  35. ListNode n1 = new ListNode(1, n2);
  36. ListNode reverse = reverse(n1);
  37. while (reverse != null) {
  38. System.out.println(reverse.value);
  39. reverse = reverse.next;
  40. }
  41. }
  42. static class ListNode {
  43. protected int value;
  44. protected ListNode next;
  45. public ListNode(int value, ListNode next) {
  46. this.value = value;
  47. this.next = next;
  48. }
  49. }
  50. }

  方法2:

               使用自定义容器类,链表放入容器类。使用容器方法removeFirst, addFirst 将老链表数据转换新容器对象内

  1. package com.nami.algorithm.study.chain3;
  2. /**
  3. * 描述:
  4. * 单项链表反转
  5. *
  6. * @Author: lbc
  7. * @Date: 2024-04-16 20:49
  8. * @email: 594599620@qq.com
  9. * @Description: keep coding
  10. */
  11. public class ChainTest {
  12. /**
  13. * 构造一个新链表,从旧链表头部移除节点,添加到新链表头部,完成后新链表是倒序的,
  14. * 使用两个自定义容器,容器内有移除与新增方法
  15. *
  16. * @param node
  17. * @return
  18. */
  19. public static ListNode reverse(ListNode node) {
  20. ChainList result = new ChainList(null);
  21. ChainList list = new ChainList(node);
  22. while (true) {
  23. ListNode listNode = list.removeFirst();
  24. if (listNode == null) {
  25. break;
  26. }
  27. result.addFirst(listNode);
  28. }
  29. return result.head;
  30. }
  31. public static void main(String[] args) {
  32. ListNode n5 = new ListNode(5, null);
  33. ListNode n4 = new ListNode(4, n5);
  34. ListNode n3 = new ListNode(3, n4);
  35. ListNode n2 = new ListNode(2, n3);
  36. ListNode n1 = new ListNode(1, n2);
  37. ListNode node = reverse(n1);
  38. while (node != null) {
  39. System.out.println(node.value);
  40. node = node.next;
  41. }
  42. }
  43. /**
  44. * 容器类
  45. * 核心 removeFirst
  46. * addFirst
  47. */
  48. static class ChainList {
  49. private ListNode head;
  50. public ChainList(ListNode head) {
  51. this.head = head;
  52. }
  53. public void addFirst(ListNode node) {
  54. node.next = head;
  55. head = node;
  56. }
  57. public ListNode removeFirst() {
  58. if (head == null) {
  59. return null;
  60. }
  61. ListNode first = head;
  62. head = head.next;
  63. return first;
  64. }
  65. }
  66. static class ListNode {
  67. protected int value;
  68. protected ListNode next;
  69. public ListNode(int value, ListNode next) {
  70. this.value = value;
  71. this.next = next;
  72. }
  73. }
  74. }

方法3:

        图解:看一遍就理解,图解单链表反转 - 掘金

        头插法

  1. package com.nami.algorithm.study.chain;
  2. /**
  3. * 描述: 反转链表
  4. * 头插法
  5. *
  6. * @Author: lbc
  7. * @Date: 2024-04-17 9:38
  8. * @email: 594599620@qq.com
  9. * @Description: keep coding
  10. */
  11. public class ChainTest {
  12. public static ListNode reverseNode(ListNode head) {
  13. ListNode prev = null;
  14. ListNode cur = head;
  15. while (cur != null) {
  16. // 这样好理解 ==! 但是感觉跟方法一 差不多
  17. ListNode node = new ListNode(cur.value, cur.next);
  18. node.next = prev;
  19. prev = node;
  20. // 循环
  21. cur = cur.next;
  22. }
  23. return prev;
  24. }
  25. public static ListNode reverseNode2(ListNode head) {
  26. // 最终节点
  27. ListNode prev = null;
  28. // 当前节点
  29. ListNode cur = head;
  30. while (cur != null) {
  31. // 想想上面的reverseNode() 方法不难,主要是解决一个 ”引用问题“
  32. // 相当于将cur = cur.next; 放在第一行。拿出next节点。防止cur.next 这个循环条件被污染
  33. // 建议比较方法1 比较着看
  34. ListNode next = cur.next;
  35. cur.next = prev;
  36. prev = cur;
  37. // 循环
  38. cur = next;
  39. }
  40. return prev;
  41. }
  42. public static void main(String[] args) {
  43. ListNode n1 = new ListNode(1);
  44. ListNode n2 = new ListNode(2);
  45. ListNode n3 = new ListNode(3);
  46. ListNode n4 = new ListNode(4);
  47. ListNode n5 = new ListNode(5);
  48. n1.next = n2;
  49. n2.next = n3;
  50. n3.next = n4;
  51. n4.next = n5;
  52. ListNode listNode = reverseNode2(n1);
  53. while (listNode != null) {
  54. System.out.println(listNode.value);
  55. listNode = listNode.next;
  56. }
  57. }
  58. static class ListNode {
  59. protected int value;
  60. protected ListNode next;
  61. public ListNode(int value) {
  62. this.value = value;
  63. }
  64. public ListNode(int value, ListNode next) {
  65. this.value = value;
  66. this.next = next;
  67. }
  68. }
  69. }

方法4:

          还是使用容器

           采用栈,先进后出思路解决

  1. package com.nami.algorithm.study.chain;
  2. import java.util.Stack;
  3. /**
  4. * 描述: 反转链表
  5. * 头插法
  6. *
  7. * @Author: lbc
  8. * @Date: 2024-04-17 9:38
  9. * @email: 594599620@qq.com
  10. * @Description: keep coding
  11. */
  12. public class ChainTest2 {
  13. public static ListNode reverseNode(ListNode head) {
  14. Stack<ListNode> stack = new Stack<>();
  15. while (head != null) {
  16. stack.push(head);
  17. head = head.next;
  18. }
  19. if (stack.isEmpty()) {
  20. return null;
  21. }
  22. ListNode newHead = stack.pop();
  23. head = newHead;
  24. while (!stack.isEmpty()) {
  25. head.next = stack.pop();
  26. head = head.next;
  27. }
  28. head.next = null;
  29. return newHead;
  30. }
  31. public static void main(String[] args) {
  32. ListNode n1 = new ListNode(1);
  33. ListNode n2 = new ListNode(2);
  34. ListNode n3 = new ListNode(3);
  35. ListNode n4 = new ListNode(4);
  36. ListNode n5 = new ListNode(5);
  37. n1.next = n2;
  38. n2.next = n3;
  39. n3.next = n4;
  40. n4.next = n5;
  41. ListNode listNode = reverseNode(n1);
  42. while (listNode != null) {
  43. System.out.println(listNode.value);
  44. listNode = listNode.next;
  45. }
  46. }
  47. static class ListNode {
  48. protected int value;
  49. protected ListNode next;
  50. public ListNode(int value) {
  51. this.value = value;
  52. }
  53. public ListNode(int value, ListNode next) {
  54. this.value = value;
  55. this.next = next;
  56. }
  57. }
  58. }

方法5:

           递归方式                  

  1. package com.nami.algorithm.study.chain;
  2. /**
  3. * 描述: 反转链表
  4. * 头插法
  5. *
  6. * @Author: lbc
  7. * @Date: 2024-04-17 9:38
  8. * @email: 594599620@qq.com
  9. * @Description: keep coding
  10. */
  11. public class ChainTest3 {
  12. /**
  13. * 递归 注意层数问题,别 stackOverFlow 喽
  14. * 堆栈溢出异常
  15. *
  16. * @param head
  17. * @return
  18. */
  19. public static ListNode reverseNode(ListNode head) {
  20. if (head == null || head.next == null) {
  21. return head;
  22. }
  23. ListNode last = reverseNode(head.next);
  24. head.next.next = head;
  25. head.next = null;
  26. return last;
  27. }
  28. public static void main(String[] args) {
  29. ListNode n1 = new ListNode(1);
  30. ListNode n2 = new ListNode(2);
  31. ListNode n3 = new ListNode(3);
  32. ListNode n4 = new ListNode(4);
  33. ListNode n5 = new ListNode(5);
  34. n1.next = n2;
  35. n2.next = n3;
  36. n3.next = n4;
  37. n4.next = n5;
  38. ListNode listNode = reverseNode(n1);
  39. while (listNode != null) {
  40. System.out.println(listNode.value);
  41. listNode = listNode.next;
  42. }
  43. }
  44. static class ListNode {
  45. protected int value;
  46. protected ListNode next;
  47. public ListNode(int value) {
  48. this.value = value;
  49. }
  50. public ListNode(int value, ListNode next) {
  51. this.value = value;
  52. this.next = next;
  53. }
  54. }
  55. }

最后:

          如果觉得困难 建议debug, 跟下。 多看代码,多思考,相信很快就明白了

声明:本文内容由网友自发贡献,转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号