1. 输入两个链表,找出它们的第一个公共结点。
1>. 判断两个链表是否有公共节点
2.>先分别求出两个链表的长度lenA和lenB,定义两个引用longer=headA和shorter=headB
3>.定义一个引用diff=两个链表的长度差,
4>.让较长的longer先走diff步,然后两个链表一起开始走
5>.判断longer是否等于shorter,不等于则没有公共节点,否则有公共节点。
主要代码:
class ListNode {
public int val;
public ListNode next;
//构造方法
public ListNode(int val, ListNode next) {
this.val = val;
this.next = next;
}
public ListNode(int val) {
this(val, null);
}
}
public class Solution {
//获取链表长度方法
private int getLength(ListNode head) {
int len = 0;
for (ListNode c = head; c != null; c = c.next) {
len++;
}
return len;
}
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
int lenA = getLength(headA);
int lenB = getLength(headB);
//获取链表长度,并求取长度差
ListNode longer = headA;
ListNode shorter = headB;
int diff = lenA - lenB;
if (lenA < lenB) {
longer = headB;
shorter = headA;
diff = lenB - lenA;
}
//让longer先走长度差步
for (int i = 0; i < diff; i++) {
longer = longer.next;
}
//判断是否右公共节点
while (longer != shorter) {
longer = longer.next;
shorter = shorter.next;
}
return longer;
}
}
10. 给定一个链表,判断链表中是否有环,并返回链表开始入环的第一个节点。 如果链表无环,则返回 NULL
1>.快慢指针,快的走两步,慢的走一步,(快的不可以比慢的多走超过一步)fast 遇到 null,表示不带环,返回 null, fast == slow,表示遇到相遇点了
2.>找环的入口: 1.把环转化转为相交问题,2.一个引用从起点出发,一个引用从相遇点出发,一定会在环的入口点相遇
3.>证明: 1.满引用走L+C 2.快引用走的距离L+C+(n+1)R 3.快引用走的距离2(L+C)
2和3相等,可证
4.>相遇点的距离到入口点的距离和起点到入口点的距离相等。
主要代码:
class ListNode {
public int val;
public ListNode next;
//构造方法
public ListNode(int val, ListNode next) {
this.val = val;
this.next = next;
}
public ListNode(int val) {
this(val, null);
}
}
public class Solution {
public ListNode detectCycle(ListNode head) {
ListNode fast = head;
ListNode slow = head;
// fast 遇到 null,表示不带环,返回 null
// fast == slow,表示遇到相遇点了
do {
if (fast == null) {
return null;
}
fast = fast.next;
if (fast == null) {
return null;
}
fast = fast.next;
slow = slow.next;
} while (fast != slow);
// 求相遇点
// 如果快的遇到 null,表示没有环,直接返回 null
// 相遇点出发 + 起点出发,最终相遇
ListNode p = head; //记录起点
ListNode q = slow; //记录相遇点
while (p != q) {
p = p.next;
q = q.next;
}
return q;
}
3. 给定一个链表,每个节点包含一个额外增加的随机指针,该指针可以指向链表中的任何节点或空节点。要求返回这个链表的深度拷贝
1.先复制所有的节点
1.1 用p1遍历原链表的所有节点,把p2插入到p1的后面
1.2 定义一个引用p1=head,如果head不为null,新建一个引用p2,使其完全等于p1,然后让p2尾插到p1后面,即p2.next = p1.next;p1.next = p2;p1 = p2.next;
1.3 p1=p1.next,继续执行,直到将原链表的所有节点复制完并且均插入到原链表的后面
2.处理random的指向
2.1 原来的链表的random的指向为1==>3,2==>1,3==>3,4==>null,复制之后的新链表也要是1==>3,2==>1,3==>3,4==>null
2.2 如果p1!=null,让p1=head(改变之后的链表的head)p2=p1.next;注意到p2.random所指的节点一直在p1.random的后一个节点,所以p2.random = p1.random.next;
2.3 p1 = p2.next;继续循环,知道所有rsndom的指向处理完毕技术循环
3.将链表分离
3.1 改变链表的指向即可。
完整代码:
class CNode {
public int val;
public CNode next = null;
public CNode random = null;
public CNode(int val) {
this.val = val;
}
}
public class Solution5{
//复制所有节点
//定义一个引用p1=head,如果head不为null,新建一个引用p2,使其完全等于p1,然后让p2尾插到p1后面,即p2.next = p1.next;p1.next = p2;p1 = p2.next;
//p1=p1.next,继续执行,直到将原链表的所有节点复制完并且均插入到原链表的后面
//
public CNode complexCopy(CNode head) {
if (head == null) {
return null;
}
//复制并插入到原链表的后面
CNode p1 = head;
while (p1 != null) {
CNode p2 = new CNode(p1.val);
p2.next = p1.next;
p1.next = p2;
p1 = p2.next;
}
//处理random的指向
//原来的链表的random的指向为1==>3,2==>1,3==>3,4==>null,复制之后的新链表也要是1==>3,2==>1,3==>3,4==>null
//如果p1!=null,让p1=head(改变之后的链表的head)p2=p1.next;注意到p2.random所指的节点一直在p1.random的后一个节点,所以p2.random = p1.random.next;
//p1 = p2.next;继续循环,知道所有rsndom的指向处理完毕技术循环
p1 = head;
while (p1 != null) {
CNode p2 = p1.next;
if (p1.random != null) {
p2.random = p1.random.next;
}
p1 = p2.next;
}
//分离链表
//改变链表的指向即可
p1 = head; //回复p1的指向
CNode newHead = head.next; //保存新链表的head
while (p1 != null) {
CNode p2 = p1.next;
p1.next = p2.next;
if (p2.next != null) {
p2.next = p2.next.next;
}
p1 = p1.next;
}
return newHead;
}
//深度拷贝的创建链表
private static void testComplexCopy(Solution5 solution) {
CNode n1 = new CNode(1);
CNode n2 = new CNode(2);
CNode n3 = new CNode(3);
CNode n4 = new CNode(4);
n1.random = n3; n2.random = n1; n3.random = n3;
n1.next = n2; n2.next = n3; n3.next = n4;
CNode result = solution.complexCopy(n1);
while(result!=null){
System.out.println(result.val);
result=result.next;
}
System.out.println("成功");
}
public static void main(String[] args) {
Solution5 solution = new Solution5();
testComplexCopy(solution);
}
}
结果: