目录
LeetCode 24.两两交换链表中的节点
文章讲解:代码随想录
初看思路:不交换值,而进行交换节点,那必然涉及到指针的操作,那么就需要一个或多个新节点来存储临时值。需要多少个新节点,那就需要画图来思考总结规律了。
图片如下:
之前我们学过操作链表的时候,在链表中添加节点或者删除节点,往往有一个虚拟节点会很好统一操作,这里我们也先设置一个虚拟节点,并且把这个虚拟节点指向头节点。
接下来,我们则需要交换元素为1和元素为2的节点。在这个过程中,dummyhead需要指向2节点,在指向节点2的同时,我们就无法获取节点1的位置,所以在操作dummyhead指针的之前此时需要一个节点temp来存储节点1。
那么这个时候我们就可以使节点2指向节点1也即是temp,但是此时问题又来了,当节点2指向节点1的时候,我们就无法获取节点3的位置,所以在操作dummyhead指针之前这里也需要一个节点tempTwo来存储节点3。
最后我们可以在把节点1(也即是temp)指向节点3(也即是tempTwo),我们就可以反转节点1和节点2的位置,之后就要移动cur指针到需要反转节点的前面的位置。
之后就需要判断循环的终止条件,通过上面我们可以知道,移动的是cur指针,当链表中的节点数量为偶数是,cur.next就会为null;当链表中的节点数量为奇数时,最后一个节点就不需要反转,那么此时cur.next.next也会为null。所以综上所述,判断条件就可以为
while(cur.next != null && cur.next.next != null){}
代码如下(Java):
/**
* 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 swapPairs(ListNode head) {
//创建虚拟头节点
ListNode dummyHead = new ListNode();
//将虚拟头节点指向原头节点
dummyHead.next = head;
//创建临时temp节点
ListNode temp = new ListNode();
//创建临时tempTwo节点
ListNode tempTwo = new ListNode();
//创建cur节点指向虚拟头节点
ListNode cur = dummyHead;
while(cur.next != null && cur.next.next != null){
temp = cur.next;
tempTwo = cur.next.next.next;
cur.next = cur.next.next;
cur.next.next = temp;
temp.next = tempTwo;
cur = cur.next.next;
}
return dummyHead.next;
}
}
LeetCode 19.删除链表的倒数第N个结点
文章讲解:代码随想录
代码如下(Java):
/**
* 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();
ListNode cur = dummyHead;
dummyHead.next = head;
int length = 0;
//统计链表的长度
while(cur.next != null){
length++;
cur = cur.next;
}
cur = dummyHead;
//定位要删除节点的前一个位置
length -= n;
//length为零说明,要删除的节点为头节点
if(length == 0){
cur.next = cur.next.next;
}else{
//定位要删除节点的前一个位置
for(int i = 0; i < length; i++){
cur = cur.next;
}
//找到之后进行删除节点操作
cur.next = cur.next.next;
}
return dummyHead.next;
}
}
使用快慢指针的解法(Java):
/**
* 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 fastIndex = dummyHead;
ListNode slowIndex = dummyHead;
//想要slowIndex节点位于删除元素的起一个位置,那么此时fastIndex就会和slowIndex节点的位置相差n
//所以先让fastIndex节点走n步
while(n-- != 0 && fastIndex.next != null){
fastIndex = fastIndex.next;
}
//该循环是把slowIndex节点放在要删除节点的前一个节点当中
//此时fastIndex节点也位于尾节点
while(fastIndex.next != null){
slowIndex = slowIndex.next;
fastIndex = fastIndex.next;
}
//进行删除节点的操作
slowIndex.next = slowIndex.next.next;
return dummyHead.next;
}
}
LeetCode 面试题 02.07.链表相交
文章讲解:代码随想录
代码如下(Java):代码随想录
/**
* 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;
int lenA = 0;
int lenB = 0;
while(curA != null){
lenA++;
curA = curA.next;
}
while(curB != null){
lenB++;
curB = curB.next;
}
curA = headA;
curB = headB;
if(lenB > lenA){
int temp = lenA;
lenA = lenB;
lenB = temp;
ListNode tempNode = curA;
curA = curB;
curB = tempNode;
}
int gapLen = lenA - lenB;
while(gapLen-- > 0){
curA = curA.next;
}
while(curA != null && curB != null){
if(curA == curB){
return curA;
}
curA = curA.next;
curB = curB.next;
}
return null;
}
}
LeetCode 142.环形链表 II
文章讲解:代码随想录
视频讲解:把环形链表讲清楚! 如何判断环形链表?如何找到环形链表的入口? LeetCode:142.环形链表II_哔哩哔哩_bilibili
力扣题目: LeetCode 142.环形链表 II
代码如下(Java):
/**
* 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 slow = head;
ListNode fast = head;
while(fast != null && fast.next != null){
slow = slow.next;
fast = fast.next.next;
if(slow == fast){
ListNode index1 = fast;
ListNode index2 = head;
while(index1 != index2){
index1 = index1.next;
index2 = index2.next;
}
return index1;
}
}
return null;
}
}