前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >重排链表

重排链表

作者头像
栋先生
发布2019-12-10 17:54:24
5660
发布2019-12-10 17:54:24
举报
文章被收录于专栏:Java成长之路

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。

本文链接:https://cloud.tencent.com/developer/article/1551773

此题为抖音现场面试的算法题,比较经典。

解题思路

代码语言:javascript
复制
给定链表 1->2->3->4->5, 重新排列为 1->5->2->4->3.

通过观察,可以将重排链表分解为以下三个步骤:

  1. 首先重新排列后,链表的中心节点会变为最后一个节点。所以需要先找到链表的中心节点:876. 链表的中间结点
  2. 可以按照中心节点将原始链表划分为左右两个链表。 2.1. 按照中心节点将原始链表划分为左右两个链表,左链表:1->2->3 右链表:4->5。 2.2. 将右链表反转,就正好是重排链表交换的顺序,右链表反转:5->4。反转链表:206. 反转链表
  3. 合并两个链表,将右链表插入到左链表,即可重新排列成:1->5->2->4->3.

代码

代码语言:javascript
复制
class Solution {
    public void reorderList(ListNode head) {
        if(head == null){
            return ;
        }
        //1. 使用快慢指针,找出链表的中心节点。
        // 1->2->3->4->5,中心节点为3
        ListNode middle = middleNode(head);

        //2. 将原始链表按照中心链表分割为两个链表,并将右链表反转
        //2.1 原始链表:1->2->3->4->5 左链表:1->2->3 右链表:4->5
        ListNode left = head;
        ListNode right = middle.next;
        middle.next = null;

        //2.2 反转右链表
        //原始右链表:4->5 反转后:5->4
        right = reverse(right);

        //3. 合并两个链表,将右链表插入到左链表
        //左链表:1->2->3 右链表:4->5 合并后:1->5->2->4->3
        merge(left,right);
    }

    //1. 使用快慢指针,找出链表的中心节点
    public ListNode middleNode(ListNode head) {
        ListNode slow = head;
        ListNode fast = head;

        while (fast != null && fast.next != null) {
            slow = slow.next;
            fast = fast.next.next;
        }
        return slow;
    }

    //2. 通过递归反转链表
    public ListNode reverse(ListNode head) {
        if (head == null || head.next == null) {
            return head;
        }
        ListNode last = reverse(head.next);
        head.next.next = head;
        head.next = null;
        return last;
    }

    //3. 合并两个链表,将右链表插入到左链表
    public void merge(ListNode left, ListNode right){
        ListNode leftTemp;
        ListNode rightTemp;
        while (left.next != null && right!= null) {
            //1. 保存next节点
            leftTemp = left.next;
            rightTemp = right.next;

            //2. 将右链表的第一个节点插入到左链表中
            // 左链表:1->2->3 右链表:5->4 
            // 合并后的左链表:1->5->2->3 
            left.next = right;
            right.next = leftTemp;

            //3. 移动left和right指针
            //左链表变为:2->3 右链表变为:4
            left = leftTemp;
            right = rightTemp;
        }
    }
}
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2019/12/08 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 解题思路
  • 代码
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档