题目

206. Reverse Linked List

Reverse a singly linked list.

Example:

Input: 1->2->3->4->5->NULL
Output: 5->4->3->2->1->NULL

Follow up:

A linked list can be reversed either iteratively or recursively. Could you implement both?

自定义链表

为了打印链表信息,笔者组装了链表

package common;public class ListNode {public int val;public  ListNode next;public ListNode(int val) {this.val = val;}static public ListNode listNodeWithIntArray(int[] input) {ListNode head = new ListNode(0);ListNode node = head;for (int i: input) {ListNode newNode = new ListNode(i);node.next = newNode;node = node.next;}return head.next;}@Overridepublic String toString() {StringBuilder sb = new StringBuilder();ListNode node = this;while (node != null) {sb.append(node.val).append("-->");node = node.next;}return sb.append("Null").toString();}@Overridepublic boolean equals(Object obj) {if (this == obj) {return true;}return false;}
}

1. 迭代解决(顺序思维,人类思维)

假设我们有链表1 → 2 → 3 → Ø,我们想将其更改为Ø ← 1 ← 2 ← 3

在遍历列表时,更改当前节点的下一个指针以指向其上一个元素。由于一个节点没有对其先前节点的引用,因此必须预先存储其先前元素。在更改引用之前,您还需要另一个指针来存储下一个节点。不要忘了最后返回新的主要参考!

复杂度分析

时间复杂度: 上)O (n )。假使,假设ññ 是列表的长度,时间复杂度是 上)O (n )。

空间复杂度: O(1)O (1 )。

package linkedlist;import common.ListNode;// https://leetcode.com/problems/reverse-linked-list/
public class ReverseLinkedList {public ListNode reverseList(ListNode head) {// check edgeif (head == null || head.next == null) {return head;}ListNode slow = head;ListNode fast = head.next;slow.next = null;ListNode temp;while (fast != null) {temp = fast.next;fast.next = slow;slow = fast;fast = temp;}return slow;}}

2. 递归解决(逆向思维,机器思维)

就是把上面的while 循环部分,改为递归实现.
递归注意先写退出条件:if (fast == null) return slow;.

package linkedlist;import common.ListNode;// https://leetcode.com/problems/reverse-linked-list/
public class ReverseLinkedList {public ListNode reverseListWithRecursive(ListNode head) {// check edgeif (head == null || head.next == null) {return head;}ListNode slow = head;ListNode fast = head.next;slow.next = null;return reverseList(fast, slow);}private ListNode reverseList(ListNode fast, ListNode slow) {if (fast == null) {return slow;}ListNode temp = fast.next;fast.next = slow;slow = fast;fast = temp;return reverseList(fast, slow);}
}

3. 递归实现 (不需要辅助方法)

递归版本有些棘手,关键是向后工作。假设列表的其余部分已经被撤消,那么我该如何撤回前面的部分?假设列表为:n1 → … → nk-1 → nk → nk+1 → … → nm → Ø

假设从节点n k + 1到n m已反转,并且您在节点n k处。

n1 → … → nk-1 → nk → nk+1 ← … ← nm

我们希望n k + 1的下一个节点指向n k。

所以,

nk.next.next = nk;

要非常小心,n 1的下一个必须指向Ø。如果您忘记了这一点,则您的链表中会有一个循环。如果您使用大小为2的链表测试代码,则可能会捕获此错误。

复杂度分析

时间复杂度: 上)O (n )。假使,假设ññ 是列表的长度,时间复杂度是 上)O (n )。

空间复杂度: 上)O (n )。由于递归,额外的空间来自隐式堆栈空间。递归可以上升到ññ 水平深。

package linkedlist;import common.ListNode;// https://leetcode.com/problems/reverse-linked-list/
public class ReverseLinkedList {public ListNode reverseListWithRecursiveClean(ListNode head) {// check edgeif (head == null || head.next == null) {return head;}ListNode result = reverseListWithRecursiveClean(head.next);head.next.next = head;head.next = null;return result;}public static void main(String[] args) {ReverseLinkedList obj = new ReverseLinkedList();int[] input = {1, 2, 3, 4, 5};ListNode head = ListNode.listNodeWithIntArray(input);System.out.println("init ListNode");System.out.println(head.toString());//ListNode result = obj.reverseList(head);//ListNode result = obj.reverseListWithRecursive(head);ListNode result = obj.reverseListWithRecursiveClean(head);System.out.println("result ListNode");System.out.println(result.toString());}
}

4. 最终结果打印输出

package linkedlist;import common.ListNode;// https://leetcode.com/problems/reverse-linked-list/
public class ReverseLinkedList {public static void main(String[] args) {ReverseLinkedList obj = new ReverseLinkedList();int[] input = {1, 2, 3, 4, 5};ListNode head = ListNode.listNodeWithIntArray(input);System.out.println("init ListNode");System.out.println(head.toString());//ListNode result = obj.reverseList(head);//ListNode result = obj.reverseListWithRecursive(head);ListNode result = obj.reverseListWithRecursiveClean(head);System.out.println("result ListNode");System.out.println(result.toString());}
}

控制台输出

init ListNode
1-->2-->3-->4-->5-->Null
result ListNode
5-->4-->3-->2-->1-->Null

算法:翻转链表 Reverse Linked List 三种方法实现,迭代解决人类思维,递归解决机器思维 reverse node相关推荐

  1. C语言实现不带头结点的单链表逆置的三种方法

    C语言实现不带头结点的单链表逆置的三种方法 直接循环 头插法 递归法 END! 直接循环 图片解释 ListNode* ReverseList1(ListNode *head) {if(head == ...

  2. 算法导论中求解时间复杂度的三种方法

    这一章讲的是递归式(recurrence),递归式是一组等式或不等式,它所描述的函数是用在更小的输入下该函数的值来定义的. 本章讲了三种方法来解递归式,分别是代换法,递归树方法,主方法. 1.代换法( ...

  3. 链表的反转的三种方法

    链表反转的三种方法 普通链表反转法 思想:借助三个Node变量进行节点的移动,促成next指向变化,从而使链表反转 递归链表反转法 思想:想像一个反转成功的链表与剩下的头节点的反转,思考如何进行,只要 ...

  4. 单链表实现反转的三种方法

    单链表的操作是面试中经常会遇到的问题,今天总结一下反转的几种方案: 1 ,两两对换 2, 放入数组,倒置数组 3, 递归实现 代码如下: #include<stdio.h> #includ ...

  5. python list是数组还是链表实现的_python 数据结构 list和链表实现栈的三种方法

    MAX_SIZE = 100 classMyStack1(object):"""模拟栈""" def __init__(self): sel ...

  6. python中pca算法_Python使用三种方法实现PCA算法

    主成分分析(PCA) vs 多元判别式分析(MDA) PCA和MDA都是线性变换的方法,二者关系密切.在PCA中,我们寻找数据集中最大化方差的成分,在MDA中,我们对类间最大散布的方向更感兴趣. 一句 ...

  7. C语言求幂的三种方法

    用三种方法求幂值 一. 暴力递归 直接对x乘y次 int result(int x,int y) {int num=1;for (int i=1; i<=y; i++) {num*=x;}ret ...

  8. C语言实现strlen的三种方法

    目录 1.strlen介绍 strlen --- 求字符串长度 2.如何使用strlen库函数 3.三种方法实现strlen 计数器法: 递归法: 指针-指针法: 4.关于strlen返回值 1.st ...

  9. 链表逆置(三种方法详解)

    @Achievek 6-1 单链表逆转 (20 point(s)) 本题要求实现一个函数,将给定的单链表逆转. ##函数接口定义: List Reverse( List L ); 其中List结构定义 ...

  10. js实现阶乘算法的三种方法

    js实现阶乘算法的三种方法 // 非递归写法 function f(n) {if (0 === n) {return 1;}let res = 1;for (let i = 1; i <= n; ...

最新文章

  1. 从语言、模型和规模三个维度,打造下一代AI
  2. Hadoop Map/Reduce教程
  3. Java Date 日期 时间 相关方法
  4. [系统安全] 十.Windows漏洞利用之SMBv3服务远程代码执行漏洞(CVE-2020-0796)及防御详解
  5. 浅谈PHP面向对象编程(九)
  6. SNF快速开发平台MVC-自由排序组件
  7. 计算机专业毕业ppt怎么弄,计算机专业毕业生如何书写毕业论文.ppt
  8. 如何获取HTML元素所对应的javascript对象?
  9. sqlalchemy query函数可用参数有哪些?
  10. Java实现面向对象编程
  11. 如何实现一个高速文件下载器
  12. 最新Oreo支付系统平台完整源码+已全开源
  13. 跟父亲一样伟大的程序员,请一定要照顾好自己!
  14. SublimeText-win10光标跟随问题
  15. 团队作业9——项目验收与总结
  16. BZOJ 4198 [Noi2015 D2T1] 荷马史诗
  17. 经验分享:如何快速上手公司的项目代码
  18. 用链接法实现散列表构造和查找
  19. Java开发微信公众号初体验
  20. 布朗大学计算机专业怎么样,布朗大学计算机专业怎么样?过来人告诉你

热门文章

  1. javq接口_java中什么是接口?接口的作用是什么?
  2. jquery常用方法收藏 .
  3. 回发或回调参数无效。在配置中使用 或在页面中使用 启用了事件验证....
  4. 克隆虚拟主机后的主机如何联网!!!!
  5. scala访问MySQL数据库
  6. 公共云存储服务的可扩展性和性能
  7. Windows 10部署与管理指南(1)之环境准备篇
  8. Java中CountDownLatch的使用和求多线程的运行时间
  9. Spring的bean管理(xml方式)之Bean实例化的方式
  10. java实训---------双色球彩票管理系统(LotterySystem)