两个链表相交的一系列问题
2016-07-26 17:47
141 查看
程序员代码面试指南(左程云)读书笔记
第二章
两个链表相交的一系列问题
在本题中单链表可能有环,也可能没有环。给定连个单链表的头节点,head1和head2,这连个链表可能相交,也可能不相交。
请实现一个函数,如果两个链表相交,请返回相交的第一个节点,如果不相交,返回null;
要求:
如果链表1的长度为N,链表2的长的为W,时间复杂度问O(N+W),额外空间复杂度为O(1)
本题可以拆分为三个问题,
一:如何判断一个链表是否有环,相交则返回第一个进入环的节点,没有则返回null;
二: 如何判断两个无环链表是否相交,相交则返回第一个相交节点,没有则返回null;
三: 如何判断两个有环链表是否相交,相交则返回第一个相交节点,没有则返回null;
package com.chen.homework;
import java.io.ObjectInputStream.GetField;
public class NOLoop {
//两个链表是否相交
public static void main(String[] args) {
Node no1=new Node(2);
Node no2=new Node(3);
Node no3=new Node(4);
no1.next=no2;
no2.next=no3;
no3.next=no1;
Node no= criclNode(no1);
System.out.println(no.value);
}
public static Node noloop(Node head1,Node head2){
if(head1==null||head2==null){
return null;
}
Node cur1=head1;
Node cur2=head2;
int n=0;
while(cur1.next!=null){
n++;
cur1=cur1.next;
}
while(cur2.next!=null){
n--;
cur2=cur2.next;
}
if(cur1!=cur2){
return null;
}
cur1=n>0?head1:head2;
cur2=cur1==head1?head2:head1;
n=Math.abs(n);
while(n!=0){
n--;
cur1=cur1.next;
cur2=cur2.next;
}
return cur1;
}
//判断两个有环链表是否相交
public static Node bothLooop(Node head1,Node head2,Node loop1,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==cur2){
return loop1;
}
cur1=cur1.next;
}
return null;
}
}
public static Node getIntersectNode(Node head1,Node head2){
if(head1 == null|| head2==null){
return null;
}
CrilcNode c=new CrilcNode();
Node loop1=c.criclNode(head1);
Node loop2=c.criclNode(head2);
if(loop1==null && loop2 ==null){
return noloop(head1, head2);
}
if(loop1!=null && loop2 !=null){
return bothLooop(head1, head2, loop1, loop2);
}
return null;
}
public static Node criclNode(Node head){
if(head==null||head.next==null||head.next.next==null){
return null;
}
Node n1=head.next;//慢指针,一次走一步
Node n2=head.next.next;//快指针,一次走两步
while(n1!=n2){
if(n2.next==null||n2.next.next==null){
System.out.println("链表没有环");
return null;
}
n2=n2.next.next;
n1=n1.next;
}
n2=head;//n2从头节点开始重新走一遍
while(n1!=n2){
n1=n1.next;
n2=n2.next;
}
System.out.println("链表有环,第一个入环节点为"+n1.value);
return n1;
}
}
第二章
两个链表相交的一系列问题
在本题中单链表可能有环,也可能没有环。给定连个单链表的头节点,head1和head2,这连个链表可能相交,也可能不相交。
请实现一个函数,如果两个链表相交,请返回相交的第一个节点,如果不相交,返回null;
要求:
如果链表1的长度为N,链表2的长的为W,时间复杂度问O(N+W),额外空间复杂度为O(1)
本题可以拆分为三个问题,
一:如何判断一个链表是否有环,相交则返回第一个进入环的节点,没有则返回null;
二: 如何判断两个无环链表是否相交,相交则返回第一个相交节点,没有则返回null;
三: 如何判断两个有环链表是否相交,相交则返回第一个相交节点,没有则返回null;
package com.chen.homework;
import java.io.ObjectInputStream.GetField;
public class NOLoop {
//两个链表是否相交
public static void main(String[] args) {
Node no1=new Node(2);
Node no2=new Node(3);
Node no3=new Node(4);
no1.next=no2;
no2.next=no3;
no3.next=no1;
Node no= criclNode(no1);
System.out.println(no.value);
}
public static Node noloop(Node head1,Node head2){
if(head1==null||head2==null){
return null;
}
Node cur1=head1;
Node cur2=head2;
int n=0;
while(cur1.next!=null){
n++;
cur1=cur1.next;
}
while(cur2.next!=null){
n--;
cur2=cur2.next;
}
if(cur1!=cur2){
return null;
}
cur1=n>0?head1:head2;
cur2=cur1==head1?head2:head1;
n=Math.abs(n);
while(n!=0){
n--;
cur1=cur1.next;
cur2=cur2.next;
}
return cur1;
}
//判断两个有环链表是否相交
public static Node bothLooop(Node head1,Node head2,Node loop1,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==cur2){
return loop1;
}
cur1=cur1.next;
}
return null;
}
}
public static Node getIntersectNode(Node head1,Node head2){
if(head1 == null|| head2==null){
return null;
}
CrilcNode c=new CrilcNode();
Node loop1=c.criclNode(head1);
Node loop2=c.criclNode(head2);
if(loop1==null && loop2 ==null){
return noloop(head1, head2);
}
if(loop1!=null && loop2 !=null){
return bothLooop(head1, head2, loop1, loop2);
}
return null;
}
public static Node criclNode(Node head){
if(head==null||head.next==null||head.next.next==null){
return null;
}
Node n1=head.next;//慢指针,一次走一步
Node n2=head.next.next;//快指针,一次走两步
while(n1!=n2){
if(n2.next==null||n2.next.next==null){
System.out.println("链表没有环");
return null;
}
n2=n2.next.next;
n1=n1.next;
}
n2=head;//n2从头节点开始重新走一遍
while(n1!=n2){
n1=n1.next;
n2=n2.next;
}
System.out.println("链表有环,第一个入环节点为"+n1.value);
return n1;
}
}
相关文章推荐
- Xcode log输出中文
- Leetcode 152. Maximum Product Subarray (Medium) (cpp)
- PHP 设置调试工具XDebug PHPStorm IDE
- leetcode 264. Ugly Number II
- JMS 消息机制
- Android ImageView自适应属性
- HDU 4907 Task schedule(工作表之外的任务)
- 通过系统调用nice改变进程优先级
- nvl函数
- iOS之懒加载
- android----Spinner下拉列表控件
- light oj 1062 二分
- HDU 1429 胜利大逃亡(续)(BFS+状态压缩)
- ftp操作方法整理
- 测试网站访问速度的5个方法
- 匈牙利算法求二分图的最大匹配/匈牙利算法模板
- [shell基础]——if/for/while/until/case 语句
- AngularJS 模块
- Nginx入门指导
- linux基础知识简单命令