1. 判断链表相交,并找出相交的第一个节点
package org.jyjiao;
import java.util.*;
public class IsLinkCross {
/*
* 实现功能:判断链表相交,并找出相交的第一个节点 算法1: 1.
* 先遍历一个链表,直到尾部,再遍历另外一个链表,如果也可以走到同样的结尾点,则两个链表相交。 2.
* 我们记下两个链表length,再遍历一次,长链表节点先出发前进(lengthMax-lengthMin)步,
* 之后两个链表同时前进,每次一步,相遇的第一点即为两个链表相交的第一个点。
*/
public String isLinkListCross1(LinkedList<String> listA,
LinkedList<String> listB) {
int ret = -1;
int lenA = 0, lenB = 0;
Iterator<String> itA = listA.iterator();
while (itA.hasNext()) {
itA.next(); //注意这里,这句不能少
lenA++;
}
Iterator<String> itB = listB.iterator();
while (itB.hasNext()) {
itB.next(); //注意这里,这句不能少
lenB++;
}
itA = listA.iterator();
itB = listB.iterator();
int wait;
if (lenA >= lenB) {
wait = lenA - lenB;
for (int i = 0; i < wait; i++) {
itA.next();
}
} else {
wait = lenB - lenA;
for (int i = 0; i < wait; i++) {
itB.next();
}
}
while (itA.hasNext() && itB.hasNext()) {
String strA = itA.next();
String strB = itB.next();
if (strA.equals(strB)) {
return strA;
}
wait++;
}
return null;
}
/*
* 实现功能:判断链表相交,并找出相交的第一个节点 算法2: 1. 先遍历一个链表,直到尾部,并将每个节点放入一个哈希表中 2.
* 再遍历另外一个链表,如果遍历到的节点在哈希表中,从该节点开始如果每个节点都在哈希表中,则两个链表相交;第一在哈希表中的节点是开始节点
*/
public String isLinkListCross2(LinkedList<String> listA,LinkedList<String> listB){
String ret=null;
HashSet<String> hsetA=new HashSet<String>();
Iterator<String> itA=listA.iterator();
while(itA.hasNext()){
String str=itA.next();
hsetA.add(str);
}
int startIndexB;
for(int i=0;i<listB.size();i++){
if(hsetA.contains(listB.get(i))){
startIndexB=i;
int startIndexA=listA.indexOf(listB.get(i));
while(startIndexA<listA.size()&& startIndexB<listB.size()){
if(listA.get(startIndexA).equals(listB.get(startIndexB))){
startIndexA++;
startIndexB++;
}else{
i=startIndexB;
break;
}
}
if(startIndexA==(listA.size())){
return listB.get(i);
}
}
}
return ret;
}
public static void main(String[] args) {
LinkedList<String> listA = new LinkedList<String>();
LinkedList<String> listB = new LinkedList<String>();
listA.add("one");
listA.add("two");
listA.add("three");
listA.add("four");
listA.add("five");
listA.add("six");
listB.add("seven");
listB.add("eight");
listB.add("three");
listB.add("four");
listB.add("five");
listB.add("six");
// IsLinkCross test1 = new IsLinkCross();
// String retStr = test1.isLinkListCross1(listA, listB);
// if (retStr == null) {
// System.out.println("no cross point");
// } else {
// System.out.println("lists cross at : " + retStr);
// }
IsLinkCross test2 = new IsLinkCross();
String retStr = test2.isLinkListCross2(listA, listB);
if (retStr == null) {
System.out.println("no cross point");
} else {
System.out.println("lists cross at : " + retStr);
}
}
}
2. 判断链表有环
算法1:哈希法,类似问题1的算法2
算法2:一个最经典的办法是 两个指针,一个每次指向下一个 另一个步长为2即指向下一个的下一个 让他俩从头开始一前一后往后遍历,若无环 最后将是慢者追到快者 若有环则是最后是快者“追上”慢者,因为在环中快者可以反超
3. 写一个函数快速找到中间节点的位置
package org.jyjiao;
import java.util.*;
public class LinkMid {
public String getMidItem(LinkedList<String> list){
String retStr=null;
int fast=0,slow=0;
Iterator<String> it1=list.iterator();
Iterator<String> it2=list.iterator();
int i=0,j=0;
while(it1.hasNext()){
it1.next();
if(it1.hasNext()){
it1.next();
}else{
retStr=it2.next();
break;
}
retStr=it2.next();
}
return retStr;
}
public static void main(String[] args){
LinkedList<String> list=new LinkedList<String>();
list.add("1");
list.add("2");
list.add("3");
list.add("4");
list.add("5");
LinkMid mid=new LinkMid();
String ret=mid.getMidItem(list);
System.out.println("mid item is:"+ret);
}
}
5. 找出链表的倒数第k个节点
算法思想类似求中间节点