7.<tag-链表和反转, 求中间结点, 合并有序链表>lt.143-重排链表

lt.143-重排链表

[案例需求]
在这里插入图片描述

[思路分析一, ]

  • 把链表中的结点通过index来访问, 这不是想怎么排就怎么排呀
  • 所以把链表中的结点放入到list(数组因为不知道链表长度所以不考虑), 再通过一层for循环设置排序的规则即可解决.
  • 你问我怎么排? 看图呗, 设list中的索引变量为i, 总的size为list.size(), 由示例图可知, i与size-i(我们设为j))是交替排序的,
  • 所以使用一个while循环, 当i < j时, 设置i处的结点的next为j处的结点, i++; 同时也设置j出结点的next为i;
  • 害, 这不就是左右双指针嘛
  • 注意噢! 在 i==j时, 循环退出, 我们需要把i的next设置为null, 不然就会存在环咯, 比如1,2,3,4,5 中设置结点3的next为null, 变为了1,5,2,4,3

[代码实现]

/**
 * 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) {
        //使用list存储, 通过下标访问
        List<ListNode> list = new ArrayList<>();

        ListNode temp = head;
        while(temp != null){
            list.add(temp);
            temp = temp.next;
        }
        
        //通过索引连接
        int i = 0, j = list.size() - 1;
        while(i < j){
            list.get(i).next = list.get(j);
            i++;

            if(i == j)break;

            list.get(j).next = list.get(i);
            j--;
        }

        list.get(i).next = null;
    }
}
  • 复杂度分析
  • 时间复杂度:O(N),其中 N 是链表中的节点数。
  • 空间复杂度:O(N),其中 N 是链表中的节点数。主要为线性表的开销。

[思路分析二, ]

    1. 找到中间结点;
    1. 反转后半部分;
    1. 两链表合并;
      在这里插入图片描述
class Solution {
    public void reorderList(ListNode head) {
        if (head == null) {
            return;
        }
        ListNode mid = middleNode(head);
        ListNode l1 = head;
        ListNode l2 = mid.next;
        mid.next = null;
        l2 = reverseList(l2);
        mergeList(l1, l2);
    }

    public ListNode middleNode(ListNode head) {
        ListNode slow = head;
        ListNode fast = head;
        while (fast.next != null && fast.next.next != null) {
            slow = slow.next;
            fast = fast.next.next;
        }
        return slow;
    }

    public 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;
    }

    public void mergeList(ListNode l1, ListNode l2) {
        ListNode l1_tmp;
        ListNode l2_tmp;
        while (l1 != null && l2 != null) {
            l1_tmp = l1.next;
            l2_tmp = l2.next;

            l1.next = l2;
            l1 = l1_tmp;

            l2.next = l1;
            l2 = l2_tmp;
        }
    }
}
posted @ 2022-05-26 20:29  青松城  阅读(31)  评论(0)    收藏  举报