技巧:快慢指针法
一、链表常用数据结构和技巧
二、常见面试题
1、链表回文结构
1、用容器,用一个栈,先遍历一遍链表加到栈中,再遍历一遍与栈中弹出的比较。
2、找到中点,右边的指针往回指,直到有一个指针为null,最后再恢复链表
2、更改链表顺序
用第一题的思想
3、
4、 有一个带有random指针的特殊链表的克隆
使用容器的方法:
不使用容器的方法:
先在中间设置克隆指针,还不设置random指针
从结构上构造一一对应,不用map,通过老指针next找新指针
5、
方法一:
使用容器,用一个hashset,遍历链表,如果节点不在set中就加进去,加到最后如果是null的话就说明这个链表是无环的,如果节点在set中有的话这个节点就是第一个入环节点。
方法二:
慢指针,每次一步,快指针每次两步。如果有环的话,一定会相遇。然后快指针回到head,两个指针都一次走一步,一定会相遇
第一步,找到单个链表是否相交
第二步:两个链表无环
第三步:一个有环一个无环,那一定不可能相交
第四步:两个都有环分三种情况
// 两个有环链表,返回第一个相交节点,如果不想交返回null
public static Node bothLoop(Node head1, Node loop1, Node head2, Node loop2) {
Node cur1 = null;
Node cur2 = null;
if (loop1 == loop2) {
cur1 = head1;
cur2 = head2;
int n = 0;
while (cur1 != loop1) {
n++;
cur1 = cur1.next;
}
while (cur2 != loop2) {
n--;
cur2 = cur2.next;
}
cur1 = n > 0 ? head1 : head2;
cur2 = cur1 == head1 ? head2 : head1;
n = Math.abs(n);
while (n != 0) {
n--;
cur1 = cur1.next;
}
while (cur1 != cur2) {
cur1 = cur1.next;
cur2 = cur2.next;
}
return cur1;
} else {
cur1 = loop1.next;
while (cur1 != loop1) {
if (cur1 == loop2) {
return loop1;
}
cur1 = cur1.next;
}
return null;
}
}
主函数