数据结构与算法-6

链表问题解题方案

代码库

1. 方法论

  1. 对于笔试,不用太在乎空间复杂度,一切为了时间复杂度
  2. 对于面试,时间复杂度仍是第一位,但一定要找到空间最省的方法

2. 快慢指针

  1. 输入链表头节点,奇数长度返回中点,偶数长度返回上中点
  2. 输入链表头节点,奇数长度返回中点,偶数长度返回下中点
  3. 输入链表头节点,奇数长度返回中点的前一个,偶数长度返回上中点的前一个
  4. 输入链表头节点,奇数长度返回中点前一个,偶数长度返回下中点前一个

3.回文链表

  1. 最简单解法:链表放到栈里,然后依次弹出和原链表对比
  2. 通过上面2.1题求中点的方法,将链表右半部分放入栈中,再重复3.1的方法,可以节省一半空间
  3. 不需要额外空间的解法:把中间的节点的next设为null,右半部的节点reverse,然后最左最右指针向中间节点移动(当任一指针移动到null时结束)并比较,最后调整回原链表,返回头节点

4.常见面试题

1.将单链表按某值划分成左边小、中间相等、右边大 的形式

  • 把链表放到数组中,在数组上做partition(笔试)
  • 分为大中小三部分,再把各部分串起来(面试)
    三个分区,每个分区有头尾两个指针,过程如下图
    在这里插入图片描述

2, 有随机指针的链表的拷贝

  • 使用HashMap<Node, Node>,将原链表节点作为key,其节点的拷贝(value的拷贝)作为value,然后根据原链表的next和rand指针,完成拷贝节点之间的指向连接
  • 无需hashmap法,在每个原节点后面插入该节点的拷贝,然后完成rand的复制,最后把新旧链表分离开
class Node {
	int value;
	Node next;
	Node rand;
}

3. 两个链表相交节点问题
问题描述:给定两个有环也可能无环的单链表,头节点head1和head2,请实现一个函数,如果两个链表相交,请返回相交的第一个节点,如果不相交,返回null。

要求:如果两个链表长度之和为N,时间复杂度请达到O(N),额外空间复杂度请达到O(1)


3.1. 如何求链表是否有环,如果有环返回环上第一个节点?

  • 使用HashSet即可实现(最简单)
  • 快慢指针,当两指针相遇时证明有环,然后,慢指针不动,快指针回到头节点,之后两指针每次移动一个节点,相遇时即为入环节点

3.2. 解决问题3

  • 两无环链表相交(如果相交,相交后的部分必定相同):1. hash表解决; 2. 两个链表最后一个节点是否相同?如果相同,记录长短链表长度length1, length2(此处可优化),长链表先走length1 - length2步后和短链表一起向前走,两节点相同时得到相交处
  • 一个有环,一个无环:肯定不相交
  • 两个链表都有环(共用环):1. 不相交;2. 入环节点相同;3. 入环节点不同
    求两个入环节点是否相同?如果相同,转换为无环的解决方案,如果不同,求第一个入环节点是否在第二个链上即可

4. 能不能不给单链表的头节点,只给想要删除的节点,就能做到在链表上把这个点删掉?

  • 把该节点的下一个节点值赋给该节点 ,删掉该节点的下一个节点即可(有限制,如果节点时服务器就拉胯了,另外是无法删除最后一个节点)
  • 必须给头指针,不然删不了,说清楚为啥就行
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值