Skip to content

排序奇升偶降链表

约 530 字大约 2 分钟

2025-03-01

1->4->3->2->5 给定一个链表奇数部分递增,偶数部分递减,要求在O(n)时间复杂度内将链表变成递增,5分钟左右

迭代拆分链表

反转偶数位链表,合并两个有序链表。

class Solution {
    public ListNode sortOddEvenList(ListNode head) {
        if (head == null || head.next == null) {
            return head;
        }

        ListNode odd = head; // 奇数位链表的起始节点
        ListNode even = head.next; // 偶数位链表的起始节点
        ListNode evenHead = even; // 保存偶数位链表的头节点,用于后续反转,相当于虚拟节点
        
        // 迭代拆分链表,注意结束条件。even在前面,所以以它为标准。重点。
        while (even != null && even.next != null) {
            odd.next = even.next; // 连接奇数位链表的下一个节点
            odd = odd.next; // 移动到下一个奇数位节点
            
            even.next = odd.next; // 连接偶数位链表的下一个节点
            even = even.next; // 移动到下一个偶数位节点
        }
        odd.next = null;  // 断开奇数链表的最后一个节点,确保链表长度为偶数时不会形成环。重点。

        // 反转偶数位链表
        ListNode reversedEven = reverseList(evenHead);

        // 合并两个有序链表
        return mergeTwoLists(head, reversedEven);
    }

    private ListNode reverseList(ListNode head) {
        ListNode prev = null; // 前一个节点
        ListNode curr = head; // 当前节点
        
        while (curr != null) {
            ListNode nextTemp = curr.next; // 临时保存下一个节点
            
            curr.next = prev; // 反转当前节点的指向
            
            prev = curr; // 移动前一个节点指针
            curr = nextTemp; // 移动当前节点指针
        }
        return prev; // 返回反转后的链表头节点
    }

    private ListNode mergeTwoLists(ListNode l1, ListNode l2) {
        ListNode dummy = new ListNode(0); // 虚拟头节点,简化操作
        ListNode current = dummy; // 当前节点指针
        
        while (l1 != null && l2 != null) {
            if (l1.val < l2.val) { // 比较两个链表的当前节点值
                current.next = l1; // 将较小值节点连接到当前节点
                l1 = l1.next; // 移动l1指针
            } else {
                current.next = l2; // 将较小值节点连接到当前节点
                l2 = l2.next; // 移动l2指针
            }
            current = current.next; // 移动当前节点指针
        }
        current.next = (l1 != null) ? l1 : l2; // 连接剩余的节点
        return dummy.next; // 返回合并后的链表头节点
    }
}