一、两链表的交点:
PS:节点类:
class ListNode {
int val;
ListNode next;
ListNode(int x) { val = x; }
}
思路一: 通过set集合来判断,将链表一放入set集合中,遍历链表二,如果存在相同的值,则为交点,return结束遍历返回该交点;
public class Solution {
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
Set<ListNode> set = new HashSet<ListNode>();
while(headA!=null){
set.add(headA);
headA = headA.next;
}
while(headB!=null){
if(set.contains(headB)){
return headB;
}
headB = headB.next;
}
return null;
}
}
思路二: 算出两个链表的长度,将长链表的指针移动相应的差值,使得循环时,两链表是等长的,每一次循环判断链表A的指针的B的指针的值是否是同一个,如果是,则为交点。
public class Solution {
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
int sizeA = getSize(headA);
int sizeB = getSize(headB);
//链表A比链表B长
if(sizeA>sizeB){
int count = sizeA-sizeB;
while(count>0){
headA = headA.next;
count--;
}
}else{
int count = sizeB-sizeA;
while(count>0){
headB = headB.next;
count--;
}
}
while(headA!=null&headB!=null){
if(headA == headB){
return headA;
}
headA = headA.next;
headB = headB.next;
}
return null;
}
public int getSize(ListNode listnode){
int len = 0;
while(listnode != null){
len++;
listnode = listnode.next;
}
return len;
}
}
二、判断链表是否有环,返回true/fasle;
思路一:使用set集合遍历链表,如果集合中不存在则add,存在则返回true;
public class Solution {
public boolean hasCycle(ListNode head) {
Set<ListNode> set = new HashSet<ListNode>();
while(head!=null){
if(set.contains(head)){
return true;
}
set.add(head);
head = head.next;
}
return false;
}
}
思路二:使用快慢指针,设置快指针步长为2,慢指针步长为1;遍历链表,如果两指针相遇,则true,否则是为false;Ps:while循环的条件需要判断慢指针是否为null,快指针是否为null;以及快指针的next是否为null,缺一则会出现空指针异常:
public class Solution {
public boolean hasCycle(ListNode head) {
ListNode fast_node = head;
while(head != null&&fast_node != null&&fast_node.next !=null){
head = head.next;
fast_node = fast_node.next.next;
if(head == fast_node){
return true;
}
}
return false;
}
}
二、判断链表是否有环,返回入环处的节点;
思路一:同上,使用set返回的不是true/false,而是重复节点。
思路二:
1、同上,在取得相遇节点时,使用meet临时变量保存。
2、判断此时meet是否和head相同,如果相同则为入环处
3、如果不同,则使meet和head以步长为1向下遍历,知道相遇,相遇的节点则为入环处。
public class Solution {
public ListNode detectCycle(ListNode head) {
ListNode fast_node = head;
ListNode slow_node = head;
ListNode meet = null;
while(slow_node != null && fast_node != null &&fast_node.next!=null){
slow_node =slow_node.next;
fast_node = fast_node.next.next;
if(slow_node == fast_node){
meet = slow_node;
break;
}
}
if(meet != null){
while(head != null){
if(head == meet){
return head;
}
head = head.next;
meet = meet.next;
}
}
return meet;
}
}