美文网首页
链表交叉重排(Leetcode143)

链表交叉重排(Leetcode143)

作者: zhouwaiqiang | 来源:发表于2018-11-09 16:51 被阅读0次

题目

  • 给定一个单链表从L0->L1->...->Ln-1->Ln将其重新排列为L0->Ln->L1->Ln-1->L2->Ln-2->...
  • 举例:输入1->2->3->4, 重排为 1->4->2->3.

解法一(采用压栈的方式)

  • 首先这个链表肯定是分段为两部分,从中间断开,而后面的是按照逆序插入到前半部分中的,如果是直接遍历索引我们是无法做逆序插入的,链表只能从前往后索引不能从后往前
  • 就可以采用入栈的方式,将所有的链表压入栈,此时栈顶元素就是链表最后一个节点,依次就可以取得第n n-1 n-2个数
  • 然后我们从head.next开始遍历,从head节点开始插入,每次从栈中取出一个元素插入到head链表中,然后再从head.next的前链表中取出一个元素插入,完成整个链表的重排

栈的代码实现

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */
class Solution {
    public void reorderList(ListNode head) {
        if (head == null) return;
        Stack<ListNode> stack = new Stack<>();
        ListNode index = head.next;
        while (index != null) {
            stack.push(index);
            index = index.next;
        }
        index = head.next;
        ListNode p = head;
        int count = 0;
        while (count < stack.size()) {
        //每一次count+1, stack-1整体变化为2
            p.next = stack.pop();
            p = p.next;
            p.next = index;
            index = index.next;
            p = p.next;
            count++;
        }
        p.next = null;
    }
}

解法二(快慢双指针)

  • 解法三部曲
  • slow和fast分别从head开始遍历,slow每次移动一个next,fast移动两个next,当fast到达null结束循环时,此时slow就是我们需要的第一个分段的最后一个数据。
  • 将此时slow之后的片段2进行逆序重排比如1->2->3->4重排为1->2->4->3,因为此时slow是指向2的。
  • 第三步,把数据按照前后交叉整合,即可得到最后的结果1->4->2->3
  • 空间复杂度O(1),时间复杂度O(n)

代码二

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */
class Solution {
    public void reorderList(ListNode head) {
        if (head == null) return;
        ListNode slow = head, fast = head;
        //找到前半部分链表
        while (fast.next != null && fast.next.next != null) {
            slow = slow.next;
            fast = fast.next.next;
        }
        //后半段头插法改变链表顺序
        ListNode index = slow.next;
        slow.next = null;
        while (index != null) {
            ListNode temp = index;
            index = index.next;
            temp.next = slow.next;
            slow.next = temp;
        }
        //前后交叉合并为一个链表
        ListNode pre = head;
        index = slow.next;
        while (pre != slow) {
            slow.next = index.next;
            index.next = pre.next;
            pre.next = index;
            pre = index.next;
            index = slow.next;
        }
    }
}

参考链接

https://www.cnblogs.com/woainifanfan/p/6511943.html

相关文章

  • 链表交叉重排(Leetcode143)

    题目 给定一个单链表从L0->L1->...->Ln-1->Ln将其重新排列为L0->Ln->L1->Ln-1->...

  • 143. 重排链表

    143. 重排链表

  • 单向链表-获取链表交叉节点

    今天学习的算法是获取链表交叉节点。 题目介绍 给定两个链表,若链表没有交叉则输出null,若链表交叉则返回交叉节点...

  • 重排链表

    形如L1->L2->...->Ln的链表,编写函数将链表重新排列成L1->Ln->L2->Ln-1->...,要求...

  • 判断两个单链表是否交叉

    利用两个链表交叉的性质,若两个链表交叉,从链表的交叉点到链表尾部,都是相同的节点,因此,链表形状是Y型。 具体做法...

  • All for PAT秋考 | 1132 - 1135

    涉及知识1132 sscanf(),浮点错误1133 链表重排(cmp函数、假装重排= =)1134 图的点覆盖(...

  • Redis数据结构学习-链表(二)

    链表 链表提供了高效的节点重排能力, 及顺序性节点访问方式, Redis构建了自己的链表实现 链表和链表节点的实现...

  • leetcode链表之重排链表

    143、重排链表[https://leetcode-cn.com/problems/reorder-list/] ...

  • LintCode 重排链表

    题目 给定一个单链表L: L0→L1→…→Ln-1→Ln, 重新排列后为:L0→Ln→L1→Ln-1→L2→Ln-...

  • 链表重排序

    题目要求:对于链表如L1->L2->L3->L4->L5->L6->L7重新排列为L1->L7->L2->L6->...

网友评论

      本文标题:链表交叉重排(Leetcode143)

      本文链接:https://www.haomeiwen.com/subject/yemoxqtx.html