题目
思路
找到两个链表相交的节点,也就是两个节点的地址相同。最开始想的是要保存每个链表所有的地址,然后来看哪个地址是一样的(太不聪明!),觉得这样有点离谱。就去看了别人的思路,原来是将尾部对齐,因为两个链表相交,后续节点都是同一个地址,因此按尾部对齐的时候,一个个往后比较,遇到地址一样的,那就是第一个相交的节点,如果遍历完也没有节点地址一样的,则表示不存咋交集。
看题解发现一个很有意思的(双指针方法):”只要以相同的速度前进,就一定有机会遇见你”,实际是数学原理,
代码
public class Solution {
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
// 先求出两个链表的长度
ListNode p_A = headA;
int count_A = 0;
int count_B = 0;
ListNode p_B = headB;
while (p_A != null){
p_A = p_A.next;
count_A += 1;
}
p_A = headA;
while (p_B != null){
p_B = p_B.next;
count_B += 1;
}
p_B = headB;
// 将较长的链表指针,向后移以至两个链表尾部对齐
if(count_A > count_B){
for (int i = 0; i < count_A - count_B; i++) {
p_A = p_A.next;
}
}
else {
for (int i = 0; i < count_B - count_A; i++) {
p_B = p_B.next;
}
}
while (p_B != null){
// 地址相等,则表示指向同一节点
if(p_A == p_B){
return p_B;
}
p_A = p_A.next;
p_B = p_B.next;
}
// 两链表没有交集
return null;
}
}
泰裤辣!
public class Solution {
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
ListNode curA = headA;
ListNode curB = headB;
// 要么相遇即节点相等,要么都为空即无缘无分,最终都能跳出感情的死循环。
while(curA != curB){
// 两人以相同的速度(一次一步)沿着各自的路径走,当走完各自的路时,再“跳”至对方的路上。(起点平齐速度相同,终点即为相遇点)
curA = (curA == null? headB:curA.next);
curB = (curB == null? headA:curB.next);
}
return curA;
}
}
题目
思路
使用哈希表,来记录已经遍历过的节点,要是当前节点已经在哈希表中,则表示该点是入环的第一个节点,返回该节点,如果遍历完整个链表时,每个节点都只访问过一次,则表示该链表没有环。
代码
public class Solution {
public ListNode detectCycle(ListNode head) {
ListNode a = head;
Set<ListNode> visted = new HashSet<ListNode>();
while (a != null){
// 如果当前节点已被访问过,则该节点属于环的节点
if (visted.contains(a)){
return a;
}
visted.add(a);
a = a.next;
}
return null;
}
}
文章介绍了两种链表问题的解决方案:一是找到两个链表相交的节点,采用尾部对齐或双指针法;二是检测环形链表,利用哈希表记录已访问节点来找出环的入口。
1334

被折叠的 条评论
为什么被折叠?



