Code前端首页关于Code前端联系我们

腾讯算法常见题:重新排列链表

terry 2年前 (2023-09-27) 阅读数 67 #数据结构与算法

给定一个单链表 L 的头节点,单链表 L 表示为:

L0 → L1 → … → Ln - 1 → Ln

重新排列为:

L0 → Ln → L1 → Ln - 1 → L2 → Ln - 2 → …

输入: 输出:

[1,4,2,3]

想法:

如果是数组就太好了,哈哈,因为数组可以通过订阅者直接访问,回答这个问题很简单。但这是一个链表。 链接列表不支持订阅访问。 我们不能随机访问链表中任意位置的元素。我们应该做什么?

我们可以先遍历一下,用数组按顺序存储链表的元素,然后再以数组的形式访问,对吧?最后,重建链表。

ArrayList的底层是一个数组。我们只是先用它来存储链表,如下:

 List<ListNode> list = new ArrayList<ListNode>();
 ListNode node = head;
 while (node != null) {
    list.add(node);
    node = node.next;
}

有了数组结构的链表后如何重建链表?如果你回顾一下这些例子,你会很容易发现一个小规律:首先是第一个,然后是从底部开始的第一个,然后是第二个,然后是从底部开始的第二个。这个规则显而易见,代码也比较容易实现:

int i = 0;
int 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;

完整的实现代码如下:

class Solution {
    public void reorderList(ListNode head) {
        if (head == null) {
            return;
        }
        List<ListNode> list = new ArrayList<ListNode>();
        ListNode node = head;
        while (node != null) {
            list.add(node);
            node = node.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;
    }
}

版权声明

本文仅代表作者观点,不代表Code前端网立场。
本文系作者Code前端网发表,如需转载,请注明页面地址。

热门