链表总结---读labuladong

21.合并两个有序链表(简单)一文搞懂单链表的六大解题套路 :: labuladong的算法小抄    

21.合并两个有序链表(简单)

思路:

常规解法,两两比较

23.合并K个升序链表(困难)

思路:优先级队列主要方法——插入和删除(两个方法都自带重排序功能)

合并 k 个有序链表的逻辑类似合并两个有序链表,难点在于,如何快速得到 k 个节点中的最小节点,接到结果链表上?

这里我们就要用到 优先级队列(二叉堆) 这种数据结构,把链表节点放入一个最小堆,就可以每次获得 k 个节点中的最小节点;

876.链表的中间结点(简单)

思路:快慢指针

快指针是慢指针的速度的两倍,快指针走完了,慢指针的位置就是中间点(如果链表长度是偶数,则命中后面的节点)

19.删除链表的倒数第 N 个结点(中等)

思路:双指针

两个指针(速度相同),第一个指针先出发k步,然后第二个指针开始出发,和第一个指针同步前进,第一个指针到达终点,此时第二个指针的位置就是我们要的

141.环形链表(简单)

思路:快慢指针相遇

142.环形链表 II(中等)找出链表的环起点

思路:快慢指针前期辅助,双指针相遇
通过选定合理的时机和地点,制造两指针距离目标点相同,于是两指针相遇

160.相交链表(简单)返回相交链表节点

思路:制造环,双指针相遇

通过选定合理的时机和地点,制造两指针距离目标点相同,于是两指针相遇

92.反转链表II(中等)

思路:递归

递归思想_yufanhui的博客-CSDN博客_递归思想

ListNode reverse(ListNode head)

{

if (head.next == null) return head;

ListNode last = reverse(head.next);

head.next.next = head; head.next = null;

return last;

}

升级版本:反转链表的前N个节点

思路:递归

/**
 * 进阶:反转链表前N个节点,并返回反转后的头节点--递归反转
 */
ListNode reversen(ListNode head, int n) {
    //递归的停止条件
    if (1 == n) return head;
    //递归方法
    ListNode last = reversen(head.next, n - 1);
    //方法里的动作
    ListNode otherhead = head.next.next;
    head.next.next = head;
    head.next = otherhead;
    return last;
}

验证:

@Test
public void reversenTest() {
    ListNode head = new ListNode(1);
    ListNode node2 = new ListNode(2);
    ListNode node3 = new ListNode(3);
    ListNode node4 = new ListNode(4);
    ListNode node5 = new ListNode(5);
    ListNode node6 = new ListNode(6);
    ListNode node7 = new ListNode(7);
    ListNode node8 = new ListNode(8);
    node7.next = node8;
    node6.next = node7;
    node5.next = node6;
    node4.next = node5;
    node3.next = node4;
    node2.next = node3;
    head.next = node2;

    ListNode p = head;
    while (null != p.next) {
        Integer pval = p.val;
        logger.info(pval.toString());
        p = p.next;
    }

    ListNode last = reversen(head, 5);

    p = last;
    while (null != p.next) {
        Integer pval = p.val;
        logger.info(pval.toString());
        p = p.next;
    }
}

升级版本:反转链表的前(M,N)个节点

思路:递归

ListNode reverseBetween(ListNode head, int m, int n) {
    // base case
    if (m == 1) {
        return reverseN(head, n);
    }
    // 前进到反转的起点触发 base case
    head.next = reverseBetween(head.next, m - 1, n - 1);
    return head;
}

总结:

递归的思想相对迭代思想,稍微有点难以理解,处理的技巧是:不要跳进递归,而是利用明确的定义来实现算法逻辑。

处理看起来比较困难的问题,可以尝试化整为零,把一些简单的解法进行修改,解决困难的问题。

值得一提的是,递归操作链表并不高效。和迭代解法相比,虽然时间复杂度都是 O(N),但是迭代解法的空间复杂度是 O(1),而递归解法需要堆栈,空间复杂度是 O(N)。所以递归操作链表可以作为对递归算法的练习或者拿去和小伙伴装逼,但是考虑效率的话还是使用迭代算法更好。

234.回文链表(简单)

思想:寻找回文串(或回文序列)的核心思想是从中心向两端扩展

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值