24. 两两交换链表中的节点
![](https://i-blog.csdnimg.cn/blog_migrate/84e47075aea2556d1c3cd8fe197fac28.png)
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode() {}
* ListNode(int val) { this.val = val; }
* ListNode(int val, ListNode next) { this.val = val; this.next = next; }
* }
*/
class Solution {
// 获取链表的结点个数
public int size(ListNode head){
// 如果传入空链表,直接返回链表大小为0
if(head == null){
return 0;
}
// 链表可以保证至少头结点不为空,长度至少为1
ListNode cur = head;
int size = 1;
while(cur.next != null){
cur = cur.next;
size++;
}
return size;
}
public ListNode swapPairs(ListNode head) {
ListNode dummyhead = new ListNode();
dummyhead.next = head;
ListNode current = dummyhead;
if(size(head) % 2 == 0){
// 如果链表长度为偶数
while(current.next != null){
ListNode temp = current.next;
ListNode temp1 = current.next.next.next;
current.next = current.next.next;
current.next.next = temp;
temp.next = temp1;
current = current.next.next;
}
}else{
// 如果链表长度为奇数
while(current.next.next != null){
ListNode temp = current.next;
ListNode temp1 = current.next.next.next;
current.next = current.next.next;
current.next.next = temp;
temp.next = temp1;
current = current.next.next;
}
}
return dummyhead.next;
}
}
19.删除链表的倒数第N个节点
![](https://i-blog.csdnimg.cn/blog_migrate/b81c0fce7ef5895a71c9913fdcca6161.png)
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode() {}
* ListNode(int val) { this.val = val; }
* ListNode(int val, ListNode next) { this.val = val; this.next = next; }
* }
*/
class Solution {
public ListNode removeNthFromEnd(ListNode head, int n) {
// 快慢指针解法
ListNode dummyhead = new ListNode();
dummyhead.next = head;
ListNode fast = dummyhead;
ListNode low = dummyhead;
// 为了保证low移动到待删除目标结点的前驱结点
n++ ;
// 将fast移动n+1步,(从fast往回数第n个,要把low停在倒数第n个结点的前驱结点)
// 若n>链表长度,则fast停在尾结点后驱null
while(n != 0 && fast != null){
fast = fast.next;
n--;
}
// fast和low同时后移,直到fast移到最后的null
while(fast != null){
fast = fast.next;
low = low.next;
}
// 此时,low.next为倒数第n个结点
low.next = low.next.next;
return dummyhead.next;
}
}
面试题 02.07. 链表相交
![](https://i-blog.csdnimg.cn/blog_migrate/a21543f1d1ad2e1a38688bd413fcb5a5.png)
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) {
* val = x;
* next = null;
* }
* }
*/
public class Solution {
// 我走过你走的路 —— 我们终将彼此相遇
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
ListNode curA = headA;
ListNode curB = headB;
while(curA != curB){
curA = curA==null ? headB : curA.next;
curB = curB==null ? headA : curB.next;
}
return curA;
}
}
-
题解(自己写的,但是系统显示超时,Emm感觉思路没问题但是就是超时,望大佬指正) :
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) {
* val = x;
* next = null;
* }
* }
*/
public class Solution {
// 得到传入链表的长度
public int size(ListNode head){
// 如果传入链表为空,直接返回0
if(head == null){
return 0;
}
// 此时至少链表不为空
int size = 1;
ListNode cur = head;
while(cur.next != null){
cur = cur.next;
size++;
}
return size;
}
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
ListNode curA = headA;
ListNode curB = headB;
int result = size(headA) - size(headB);
// 当链表A长度>=链表B长度时
if(result >= 0){
// 将两个链表末端对齐
while(result != 0 && curA.next != null){
curA = curA.next;
result--;
}
while(curA != null || curB != null){
// 当A、B指针均未走到末尾向后搜索时
// 遇到两个指针相等(即两个结点相同)
if(curA == curB){
return curA;
}
}
// 若无交点,返回null
return null;
}else{
// 当B链表长度>A链表长度时
// 将两个链表末端对齐
while(result != 0 && curB.next != null){
curB = curB.next;
result++;
}
while(curA != null || curB != null){
// 当A、B指针均未走到末尾向后搜索时
// 遇到两个指针相等(即两个结点相同)
if(curA == curB){
return curB;
}
}
// 若无交点,返回null
return null;
}
}
}
142.环形链表II
tips:需要注意的点是:经过推导,将环拉直,不难得出low在进入环之后,走完一圈之前必然被fast追上过,所以设low为x+y。
![](https://i-blog.csdnimg.cn/blog_migrate/7a37a3e56c722c5885ac45b30c0e088b.jpeg)
/**
* 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 low = head;
while(fast != null && fast.next != null){
fast = fast.next.next;
low = low.next;
// 遇到环,快慢指针相遇
if(fast == low){
ListNode cur1 = fast;
ListNode cur2 = head;
while(cur1 != cur2){
cur1 = cur1.next;
cur2 = cur2.next;
}
// cur1/cur2相遇点即为环入口
return cur1;
}
}
// fast走完未遇到环,说明链表无环,返回null
return null;
}
}