
1.先通过快慢指针,找到中间结点
2.对中间结点后面的链表进行反转
3.指针从两端开始移动,如果符合回文结构,在奇数情况下相与,在偶数情况下相邻

public boolean chkPalindrome() {
if (head == null) {
return false;
}
if (head.next == null) {
return true;
}
ListNode fast = head;
ListNode slow = head;
//寻找中间结点
while (fast != null && fast.next != null) {
fast = fast.next.next;
slow = slow.next;
}
//翻转
ListNode cur = slow.next;//cur代表当前需要翻转的结点
while (cur != null) {
ListNode curNext = cur.next;
cur.next = slow;
slow = cur;
cur = curNext;
}
//一个从前往后,一个从后往前,进行比较, 直到slow和head相遇
while (slow != head) {
if (head.val != slow.val) {
return false;
}
if (head.next == slow) {//走到这里两个val值一样,偶数情况
return true;
}
head = head.next;
slow = slow.next;
}
return true;
}

1.比较x重新排序,且不能改变原来是顺序
2.新创建两个链表,链表A存储比x小的,链表B存比x大的
3.比较完后,将两个链表进行拼接
4.将末尾的next置为空

import java.util.*;
/*
public class ListNode {
int val;
ListNode next = null;
ListNode(int val) {
this.val = val;
}
}*/
public class Partition {
public ListNode partition(ListNode Head, int x) {
ListNode cur = Head;
ListNode as = null;
ListNode ae = null;
ListNode bs = null;
ListNode be = null;
while(cur!=null){
if(cur.val<x){
if(as==null){
as = cur;
ae = cur;
} else{
ae.next = cur;
ae = cur;
}
}else{
if(bs==null){
bs = cur;
be = cur;
}else{
be.next = cur;
be = cur;
}
}
cur = cur.next;
}
//A/B两个链表可能不会同时存在元素
if(as==null){//A链表如果为空,返回B链表
return bs;//此时B链表要么为空要么不为空,不为空证明进入到了循环,返回B链表的内容,为空证明没进到循环里面
}
//A链表不为空,拼接两个链表
ae.next = bs;
if(bs != null){//判断;链表B不等于空,避免置空时空指针异常
be.next=null;//将末尾置为空
}
return as;
}
}

1.先分别求出两个链表的长度,根据长度的差值,pl指向长链表 ps指向短链表
2.pl先移动,直到两个链表长度相等
3,pl和ps同时移动,直到相遇

public static MySingleList.ListNode getIntersectionNode(MySingleList.ListNode headA, MySingleList.ListNode headB) {
if (headA==null || headB==null){
return null;
}
//分别求两个链表的长度
int lenA = 0;
int lenB = 0;
MySingleList.ListNode pl = headA;
MySingleList.ListNode ps = headB;
while (pl != null) {
lenA++;
pl = pl.next;
}
while (ps != null) {
lenB++;
ps = ps.next;
}
int len = lenA - lenB;
//求完长度后,ps和pl为空了,要设置回去
pl = headA;
ps = headB;
//根据len的值修改指向
if (len < 0) {
pl = headB;
ps = headA;
len = lenB - lenA;
}//len为差值且一定是整数,pl指向长的链表
while (len != 0) {
pl = pl.next;
len--;
}
while (pl != ps) {
pl = pl.next;
ps = ps.next;
}
/* if (pl == null) {
return null;
}*/
return pl;
}

1.利用快慢指针
2.fast每次走两步,slow每次走一步(
3.走别的倍数可能永远相遇不了,fast走两步相当于追击问题追一步,最坏情况为相差一圈的长度
4.直到相遇则证明链表中有环;(要排除都为空的情况)

/**
* Definition for singly-linked list.
* class ListNode {
* int val;
* ListNode next;
* ListNode(int x) {
* val = x;
* next = null;
* }
* }
*/
public class Solution {
public boolean hasCycle(ListNode head) {
ListNode fast = head;
ListNode slow = head;
while(fast!=null&&fast.next!=null){
fast = fast.next.next;
slow = slow.next;
if(fast==slow){
return true;
}
}
return false;
}
}

1.返回环开始的结点,没有环返回null
2.先找到相遇结点,根据下图推导出,x=y
3.让其中一个指针返回头结点,同时移动直到再次相遇

/**
* Definition for singly-linked list.
* class ListNode {
* int val;
* ListNode next;
* ListNode(int x) {
* val = x;
* next = null;
* }
* }
*/
public class Solution {
public ListNode detectCycle(ListNode head) {
ListNode fast = head;
ListNode slow = head;
while (fast != null && fast.next != null) {//获取相遇结点
slow = slow.next;
fast = fast.next.next;
if (fast == slow) {
break;
}
}
if (fast ==null||fast.next==null){
return null;
}
slow = head;
while (fast!=slow){ //同时移动,相遇位置就是环的开始结点
fast = fast.next;
slow = slow.next;
}
return slow;
}
}
