剑指 Offer 24. 反转链表

前两个代码是我自己手敲的,如果有错误欢迎评论指出哦

题目

定义一个函数,输入一个链表的头节点,反转该链表并输出反转后链表的头节点。

示例:

输入: 1->2->3->4->5->NULL
输出: 5->4->3->2->1->NULL

 

限制:

0 <= 节点个数 <= 5000

解题方法一

 /**
     * 借助辅助空间
     * 效率低
     * @param head
     */
    private static ListNode reverseList0(ListNode head) {
        List<Integer> arr = new ArrayList<>();
        while (head != null) {
            arr.add(head.val);
            head = head.next;
        }
        ListNode newHead = new ListNode(arr.get(arr.size() - 1));
        for (int i = arr.size() - 2; i >= 0; i--) {
            ListNode node = new ListNode(arr.get(i));
            newHead.next = node;
            newHead = node;
        }
        return newHead;
    }
    private static ListNode reverseList1(ListNode head) {
        if (head == null) {
            return null;
        }
        ArrayList<ListNode> nodeList = new ArrayList<>();
        while (head != null) {
            nodeList.add(head);
            head = head.next;
        }
        int startIndex = nodeList.size() - 1;
        for (int i = startIndex; i >= 0; i--) {
            ListNode node = nodeList.get(i);
            if (i == 0) {
                node.next = null;
            } else {
                node.next = nodeList.get(i - 1);
            }
        }
        //现在头结点是原来的尾节点
        head = nodeList.get(startIndex);
        return head;
    }

 

解题方法二

 /**
     * 使用指针迭代遍历
     * 时间复杂度 O(N) : 遍历链表使用线性大小时间。
     * 空间复杂度 O(1) : 变量 pre 和 cur 使用常数大小额外空间。
     * @param head
     * @return
     */
    private ListNode reverseList(ListNode head) {
        if (head == null){
            return null;
        }
        ListNode prev = null;  // 当前指针的前一个
        ListNode curr = head;  //当前指针 初始化为头节点
        // 当当前指针走到最后结束
        while (curr != null){
            ListNode temp = curr.next;  //临时节点 指向当前指针的下一个  用于保存链表的地址
            curr.next = prev;  // 将当前指针指向前一个
            // 为下一次循环准备
            prev = curr;  // 向后移动指针
            curr = temp;  // 向后移动指针
        }
        return prev; //当当前指针指向null停止循环后 他的前一个指针就是需要返回的头节点
    }

 

解题方法三

/**
     * 使用递归法遍历链表
     * 时间复杂度 O(N) : 遍历链表使用线性大小时间。
     * 空间复杂度 O(N) : 遍历链表的递归深度达到 N ,系统使用 O(N) 大小额外空间。
     *
     * 使用递归法遍历链表,当越过尾节点后终止递归,在回溯时修改各节点的 next 引用指向。
     *
     * recur(cur, pre) 递归函数:
     * 终止条件:当 cur 为空,则返回尾节点 pre (即反转链表的头节点);
     * 递归后继节点,记录返回值(即反转链表的头节点)为 res ;
     * 修改当前节点 cur 引用指向前驱节点 pre ;
     * 返回反转链表的头节点 res ;
     * reverseList(head) 函数:
     * 调用并返回 recur(head, null) 。传入 null 是因为反转链表后, head 节点指向 null ;
     *
     * @param head
     * @return
     */
    private ListNode reverseLis2(ListNode head) {
        return recur(head, null);    // 调用递归并返回
    }
    private ListNode recur(ListNode cur, ListNode pre) {
        if (cur == null) return pre; // 终止条件
        ListNode res = recur(cur.next, cur);  // 递归后继节点
        cur.next = pre;              // 修改节点引用指向
        return res;                  // 返回反转链表的头节点
    }

 

微信关注

WeChat

本站为非盈利性站点,所有资源、文章等仅供学习参考,并不贩卖软件且不存在任何商业目的及用途,如果您访问和下载某文件,表示您同意只将此文件用于参考、学习而非其他用途。
本站所发布的一切软件资源、文章内容、页面内容可能整理来自于互联网,在此郑重声明本站仅限用于学习和研究目的;并告知用户不得将上述内容用于商业或者非法用途,否则一切后果请用户自负。
如果本站相关内容有侵犯到您的合法权益,请仔细阅读本站公布的投诉指引页相关内容联系我,依法依规进行处理!
作者:理想
链接:https://www.imyjs.cn/archives/538
THE END
二维码
剑指 Offer 24. 反转链表
前两个代码是我自己手敲的,如果有错误欢迎评论指出……
<<上一篇
下一篇>>
文章目录
关闭
目 录