【LeetCode笔记】143. 重排链表(Java、链表、栈、快慢指针)

题目描述

  • 一看题目反序:用栈
  • 更新:O(1) 空间复杂度
    在这里插入图片描述

思路 & 代码

  • 先快慢指针,找到需要入栈的起点,然后逐个入栈
  • 然后逐个出栈,进行重排即可
  • 注意1:记得对重排后的链表结尾进行 Last.next = null 处理,防止成环
  • 注意2:奇偶情况要进行处理,可见代码注释
  • 时间复杂度 O(n) ,空间复杂度 O(n)
/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode() {}
 *     ListNode(int val) { this.val = val; }
 *     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
 * }
 */
class Solution {
    public void reorderList(ListNode head) {
        // 快慢指针
        ListNode now = head;
        // 走到需要进行入栈的位置
        now = head;
        ListNode pre = head;
        while(now.next != null && now.next.next != null){
            pre = pre.next;
            now = now.next.next;
        }
        // 偶数处理
        if(now.next != null){
            pre = pre.next;
        }
        now = pre.next;
        // 末尾处理,防止死循环
        pre.next = null;
        
        // 入栈
        Stack<ListNode> myStack = new Stack<>();
        while(now != null){
            myStack.push(now);
            now = now.next;
        }
        // 重排
        now = head;
        while(!myStack.isEmpty()){
            ListNode temp = myStack.pop();
            ListNode nextLoop = now.next;
            temp.next = now.next;
            now.next = temp;
            now = nextLoop;
        }
    }
}

更新版:快慢指针 + 翻转链表

class Solution {
    public void reorderList(ListNode head) {
        // 0. 特殊情况
        if(head == null || head.next == null) {
            return;
        }

        // 1. 快慢指针,划分出两段(注意第一段结尾的 next 置空,用 slowPre
        ListNode slow = head, fast = head;
        ListNode slowPre = null;
        while(fast != null && fast.next != null) {
            slowPre = slow;
            slow = slow.next;
            fast = fast.next.next;
        }
        // 奇数,slow 为中间节点(奇偶情况处理)
        if(fast != null) {
            slowPre = slow;
            slow = slow.next;
        }

        // 2. 第二段的翻转
        slowPre.next = null;
        ListNode pre = null;
        while(slow != null) {
            ListNode nextNode = slow.next;
            slow.next = pre;
            pre = slow;
            slow = nextNode;
        }

        // 3. 合并两段链表
        fast = head;
        while(pre != null) {
            ListNode temp1 = fast.next;
            ListNode temp2 = pre.next;
            fast.next = pre;
            pre.next = temp1;
            fast = temp1;
            pre = temp2;
        }
    }
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值