Leetcode143. 重排链表--线性表/哈希表

1.题目

2.思路 --时间O(n) , 空间O(n)

仔细读题呀!!!!!!!!思路最重要,先不要着急写代码!!!

一开始想错了,以为是位置0 和 n- 1换位置, 1 和 n - 2 换位置.....

然后发现报错,一直都有环,才发现是题意理解错了(我想的问题更复杂,因为头和尾节点更复杂),题目明明写的是 0 和 1 之间插入倒数第一个节点n - 1,1 和 2 之间插入倒数第二个链表节点n - 2,以此类推.可以发现:

n = 0, 不需要交换节点

n = 1, 不需要交换节点

n = 2, 不需要交换节点

n = 3, 需要交换一个节点

n = 4, 需要交换一个节点

n = 5, 需要交换两个节点: 0,4 1,3,2

n = 6, 2;

n = 7, 3;

...

已经发现规律了,n >= 3,的等差数列.

那么问题来了,如何在两个节点中插入一个节点呢?--修改下一个指针即可,需要定义一个中间节点ListNode temp 来保存节点位置,跟swap两个值很像.

那么问题又来了,如何让每次插入的节点都是从末尾倒叙呢?链表是不支持顺序索引的.

我想的是用空间换时间,定义一个哈希表记录每一个节点的前驱节点,这样先移动tail指针到末尾,然后获取前驱节点,就可以倒叙遍历了.Map<ListNode, ListNode>

官方题解一用的是线性表来存储节点,也是可以的.List<ListNode>list = new ArrayList();

/**
 * 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) {
        // if(head.next == null)return ;

        ListNode tail = head;
        ListNode head2 = head;
        Map<ListNode, ListNode>map = new HashMap();
        int n = 1;
        while(tail.next != null){
            map.put(tail.next, tail); // 位置i, 前一个节点
            tail = tail.next;
            n++;
        }
        if(n < 3)return ;
        int temp = 3;
        // System.out.println(n +">>" + map.get(head.next));
        while(temp <= n ){
            ListNode node = head2.next;
            head2.next = tail;
            tail.next = node;

            // System.out.println(head2.val +">>"+ tail.val);
            head2 = head2.next.next;
            tail = map.get(tail);
            tail.next = null;

            temp += 2;
        }

        return ;
    }

    
}

3.结果

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值