1. Lista circular vinculada 1: (1 ~ 3)
Dada una lista vinculada, determine si hay un anillo en la lista vinculada.
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
bool hasCycle(ListNode *head) {
//快慢指针
ListNode* fast=head;
ListNode* slow=head;
while(fast && fast->next){
fast=fast->next->next; //快指针一次走两步
slow=slow->next; //慢指针一次走一步
if(fast==slow) //如果有环一定会相遇
return true;
}
return false;
}
};
2. Lista circular vinculada 2: método de fórmula
Dada una lista vinculada, devuelva el primer nodo donde la lista vinculada comienza a ingresar al bucle. Si la lista vinculada no tiene anillos, se devuelve un valor nulo.
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode *detectCycle(ListNode *head) {
//快慢指针,公式法
ListNode* fast=head;
ListNode* slow=head;
while(fast && fast->next){
fast=fast->next->next;
slow=slow->next;
if(fast==slow){
//相遇后,确定入环结点
ListNode* meet=slow;
ListNode* cur=head;
//找到入环结点:如图所示,因为 L=C-X,所以meet和cur会走相同的距离,一定会在入环点相遇
while(meet!=cur){
cur=cur->next;
meet=meet->next;
}
return cur;
}
}
return nullptr;
}
};
3. Lista enlazada de intersección:
Escribe un programa para encontrar el nodo inicial donde se cruzan dos listas unidas. Si no hay intersección entre las dos listas vinculadas, se devuelve un valor nulo.
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
//双指针:找到两个链表的尾结点,若两个尾结点的地址相等(比较的是地址),则一定相交
ListNode* curA=headA;
ListNode* curB=headB;
int lenA=0,lenB=0;
if(headA==nullptr || headB==nullptr)
return nullptr;
while(curA && curA->next){
++lenA;
curA=curA->next;
}
while(curB && curB->next){
++lenB;
curB=curB->next;
}
if(curA!=curB)
return nullptr;
else{
ListNode* longlist=headA; //找到长的链表
ListNode* shortlist=headB;
if(lenA<lenB){
longlist=headB;
shortlist=headA;
}
int gap=abs(lenA-lenB);
while(gap--) //长的链表先走gap步
longlist=longlist->next;
while(longlist!=shortlist){
//然后一起走,直到相遇
longlist=longlist->next;
shortlist=shortlist->next;
}
return longlist;
}
}
};
4. El nodo del medio de la lista vinculada: (4 ~ 5)
Dada una lista enlazada individual no vacía cuyo nodo principal es head, devuelve el nodo medio de la lista enlazada. Si hay dos nodos intermedios, regrese al segundo nodo intermedio.
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode* middleNode(ListNode* head) {
//双指针
ListNode* fast=head;
ListNode* slow=head;
while(fast && fast->next){
fast=fast->next->next;
slow=slow->next;
}
return slow;
}
};
5. Elimine el nodo N de la parte inferior de la lista vinculada:
Darle una lista vinculada, eliminar el último n-ésimo nodo de la lista vinculada y devolver el nodo principal de la lista vinculada.
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode() : val(0), next(nullptr) {}
* ListNode(int x) : val(x), next(nullptr) {}
* ListNode(int x, ListNode *next) : val(x), next(next) {}
* };
*/
class Solution {
public:
ListNode* removeNthFromEnd(ListNode* head, int n) {
//双指针,让fast先走n步,然后一起走,直到走到末尾
//最后slow指向的是倒数第n个结点的**前一个结点**
//如果fast先走n-1步,然后一起走,则最后slow指向的是倒数第n个结点
ListNode* fast=head;
ListNode* slow=head;
ListNode* tmp=nullptr;
if(head==nullptr) //如果链表为空则返回
return nullptr;
while(n--) //快指针先走n步
fast=fast->next;
while(fast && fast->next){
//然后一起走
slow=slow->next;
fast=fast->next;
}
if(fast==nullptr){
//如果删除的是第一个结点
tmp=head;
head=head->next;
delete tmp;
}
else{
//如果删除的是其余结点
tmp=slow->next;
slow->next=tmp->next;
delete tmp;
}
return head;
}
};
6. Lista enlazada inversa:
Defina una función, ingrese el nodo principal de una lista vinculada, invierta la lista vinculada y genere el nodo principal de la lista vinculada invertida.
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode* reverseList(ListNode* head) {
//头插法逆置单链表
ListNode* cur=head;
ListNode* pre=nullptr;
head=nullptr;
while(cur!=nullptr){
pre=cur;
cur=cur->next;
pre->next=head;
head=pre;
}
return head;
}
};
7. Fusionar dos listas enlazadas ordenadas:
Combine dos listas vinculadas ascendentes en una nueva lista vinculada ascendente y regrese. La nueva lista enlazada se compone de empalmar todos los nodos de las dos listas enlazadas dadas.
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode() : val(0), next(nullptr) {}
* ListNode(int x) : val(x), next(nullptr) {}
* ListNode(int x, ListNode *next) : val(x), next(next) {}
* };
*/
class Solution {
public:
ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {
ListNode* dummy=new ListNode(-1); //创建一个头结点
ListNode* pre=dummy;
while(l1 && l2){
//l1和l2都不为空时
if(l1->val<l2->val){
pre->next=l1;
l1=l1->next;
}
else{
pre->next=l2;
l2=l2->next;
}
pre=pre->next;
}
//合并后 l1 和 l2 最多只有一个还未被合并完,直接将链表末尾指向未合并完的链表即可
pre->next=(l1==nullptr ? l2 : l1);
return dummy->next;
}
};
8. Elimine los elementos de la lista vinculada:
Dado el encabezado del nodo principal de una lista vinculada y un valor entero, elimine todos los nodos de la lista vinculada que satisfagan Node.val == val y devuelva el nuevo nodo principal.
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode() : val(0), next(nullptr) {}
* ListNode(int x) : val(x), next(nullptr) {}
* ListNode(int x, ListNode *next) : val(x), next(next) {}
* };
*/
class Solution {
public:
ListNode* removeElements(ListNode* head, int val) {
//双指针
ListNode* cur=head; //指向当前结点
ListNode* pre=nullptr; //指向当前结点的前驱
if(head==nullptr) //处理第一个结点,若为空
return nullptr;
while(cur!=nullptr){
//遍历
if(head->val==val){
//处理第一个结点,若第一个结点要删除
head=cur->next;
delete cur;
cur=head;
}
else if(cur->val==val){
//删除
pre->next=cur->next;
delete cur;
cur=pre->next;
}
else{
//后移
pre=cur;
cur=cur->next;
}
}
return head;
}
};