链表类ListNode
定义
1 | import java.util.Arrays; |
提供了导入导出为数组的内置静态方法。
问题
反转链表
题目描述:输入一个链表,反转链表后,输出新链表的表头。
代码:
1 | /* |
链表有环
题目描述:判断给定的链表中是否有环 扩展:你能给出空间复杂度\(O(1)\)的解法么?
解法: 快慢指针
1 | /** |
合并有序列表
题目描述:将两个有序的链表合并为一个新链表,要求新的链表是通过拼接两个链表的节点来生成的
解法: 类似归并排序的思路
1 | import java.util.Arrays; |
(9.7)删除链表的倒数第n个节点
题目描述:
给定一个链表,删除链表的倒数第n个节点并返回链表的头指针
例如, 给出的链表为:1->2->3->4->5, n= 2. 删除了链表的倒数第n个节点之后,链表变为1->2->3->5.
备注:题目保证n一定是有效的
请给出时间复杂度为 \(O(n)\) 的算法
1 | public static ListNode removeNthFromEnd(ListNode head, int n) { |
(9.7)两个链表生成相加链表
题目描述:
- 假设链表中每一个节点的值都在 0 - 9 之间,那么链表整体就可以代表一个整数。
- 给定两个这种链表,请生成代表两个整数相加值的结果链表。
- 例如:链表 1 为 9->3->7,链表 2 为 6->3,最后生成新的结果链表为 1->0->0->0。
分析:
用到了之前的反转链表,以及数组相加的策略(进位)。链表增加结点需要考虑初始化的情况。最重要的还是确定哪一步同步current和result两个链表。 讨论区反映java卡75%算例,超时。
1 | import java.util.Arrays; |
(9/14) 链表中环的入口节点
题目描述
- 对于一个给定的链表,返回环的入口节点,如果没有环,返回null
解题思路
- 首先用快慢指针判断是否存在环
- 如存在环,假设环前长度为 d , 环长度为 l , 相遇点在环入口后 s 处
\[ d+l+s = 2*(d+s) \] \[ d+s = l \]
- 快指针归零,再走 (l-s)
- 慢指针
\[ d+s+(l-s)=d+l \]
- 快指针
\[ l-s = d\]
- 二者在 d 处相遇
代码
1 | public class NowCoder_DetectCycle { |
(9/14) 两个链表的第一个公共节点
题目描述
- 输入两个链表,找出它们的第一个公共结点。(注意因为传入数据是链表,所以错误测试数据的提示是用其他方式显示的,保证传入数据是正确的)
解题思路1——链表成环
- 两链表应该呈现出 “Y” 形。把第二个链表接到第一个链表尾巴上形成一个环,若存在公共节点,则必形成环。
- 如果保留 p1, 最后的节点 temp -> p2。用 detectCycle(p1) 找出节点 result。再将temp -> p2 断开。返回result。
- 代码如下
1 | public static ListNode FindFirstCommonNode(ListNode pHead1, ListNode pHead2) { |
解题思路2
- 先遍历两链表,分别得出长度
- 较长者截取掉更长的部分,因为共同部分肯定比较短的链表更短
- 然后两链表同时向后遍历直到二者相同
- 代码如下
1 | // 解法:截取长度并依次比较。复杂度O(m+n) |