Los siguientes puntos de conocimiento son principalmente comunes:
pitón:
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
def deleteNode(self, node):
"""
:type node: ListNode
:rtype: void Do not return anything, modify node in-place instead.
"""
node.val = node.next.val
node.next = node.next.next
Implementación de C ++:
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
void deleteNode(ListNode* node) {
node->val = node->next->val;
node->next = node->next->next;
}
};
1-2 . Eliminar elementos duplicados en la lista vinculada ordenada
Determine si es un nodo duplicado comparando el valor de un nodo con los nodos posteriores. Si es un duplicado, cambiamos el siguiente puntero del nodo actual para que omita el siguiente nodo y apunte directamente al siguiente nodo. Si no es un duplicado, el nodo se mueve hacia abajo.
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
def deleteDuplicates(self, head: ListNode) -> ListNode:
node = head
while node and node.next:
if node.val == node.next.val:
node.next = node.next.next
else:
node = node.next
return head
Implementación de C ++:
/**
* 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* deleteDuplicates(ListNode* head) {
ListNode* node = head;
while(node !=nullptr && node->next !=nullptr){
if(node->val == node->next->val){
node->next = node->next->next;
}
else
{
node = node->next;
}
}
return head;
}
};
1-3 . Elimina el nodo N de la parte inferior de la lista vinculada
Idea: encuentre la longitud de la lista vinculada, busque el nodo anterior del nodo que se eliminará agregando un nodo al nodo principal y luego elimínelo
Método 1: bucle
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, val=0, next=None):
# self.val = val
# self.next = next
class Solution:
def removeNthFromEnd(self, head: ListNode, n: int) -> ListNode:
length = 0
node = head
#获取链表长度
while node:
length+=1
node= node.next
# print(length)
curr_length = 0
new_head = ListNode(0)
new_head.next = head
node2=new_head
stop_length = length - n
#循环走到要删除节点的前一个节点
while stop_length:
stop_length-=1
node2 = node2.next
#跳过要删除的节点即可
node2.next = node2.next.next
return new_head.next
Método 2: recursividad
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, val=0, next=None):
# self.val = val
# self.next = next
class Solution:
def __init__(self):
self.count = 0
def removeNthFromEnd(self, head: ListNode, n: int) -> ListNode:
if not head:
return head
head.next = self.removeNthFromEnd(head.next, n) # 递归调用
self.count += 1 # 回溯时进行节点计数
return head.next if self.count == n else head
Método 3: puntero doble
El primer puntero y el segundo puntero están separados por n, de modo que el primero se ejecuta hasta el final y el siguiente nodo del segundo es el último n.
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, val=0, next=None):
# self.val = val
# self.next = next
class Solution:
# def __init__(self):
# self.count = 0
def removeNthFromEnd(self, head: ListNode, n: int) -> ListNode:
new_head = ListNode(0)
new_head.next = head
first = head
second = new_head
for i in range(n):
first = first.next
while first:
first = first.next
second = second.next
second.next = second.next.next
return new_head.next
Implementación de C ++:
/**
* 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) {
ListNode* new_head = new ListNode(0);
new_head ->next = head;
ListNode* first = head;
ListNode* second = new_head;
for(int i=0;i<n;i++){
first = first->next;
}
while(first){
first = first->next;
second = second->next;
}
second->next = second->next->next;
return new_head->next;
}
};
1-4 . Eliminar el nodo de la lista vinculada
Idea: puntero doble
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
def deleteNode(self, head: ListNode, val: int) -> ListNode:
if head is None:
return head
new_head = ListNode(0)
new_head.next = head
pre = new_head
cur = head
while cur.val != val:
pre = cur
cur = cur.next
pre.next = cur.next
return new_head.next
Implementación de C ++:
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode* deleteNode(ListNode* head, int val) {
if(head == NULL){
return NULL;
}
ListNode* new_head = new ListNode(0);
new_head->next = head;
ListNode* pre = new_head;
ListNode* cur = head;
while(cur->val != val){
pre = cur;
cur = cur->next;
}
pre->next = cur->next;
return new_head->next;
}
};
1-5. Intercambiar nodos en la lista vinculada en pares
Idea: método iterativo
código python:
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, val=0, next=None):
# self.val = val
# self.next = next
class Solution:
def swapPairs(self, head: ListNode) -> ListNode:
new_head = ListNode(0)
new_head.next = head
temp = new_head
while temp.next and temp.next.next:
node1 = temp.next
node2 = temp.next.next
temp.next = node2
node1.next = node2.next
node2.next = node1
temp = node1
return new_head.next
Implementación de C ++:
/**
* 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* swapPairs(ListNode* head) {
ListNode* new_head = new ListNode(0);
new_head->next = head;
ListNode* temp = new_head;
while(temp->next && temp->next->next){
ListNode* head1 = temp->next;
ListNode* head2 = temp->next->next;
temp->next = head2;
head1->next = head2->next;
head2->next = head1;
temp = head1;
}
return new_head->next;
}
};
Idea 1: puntero doble
class Solution(object):
def reverseList(self, head):
"""
:type head: ListNode
:rtype: ListNode
"""
# 申请两个节点,pre和 cur,pre指向None
pre = None
cur = head
# 遍历链表,while循环里面的内容其实可以写成一行
while cur:
# 记录当前节点的下一个节点
tmp = cur.next
# 然后将当前节点指向pre
cur.next = pre
# pre和cur节点都前进一位
pre = cur
cur = tmp
return pre
Implementación de C ++:
/**
* 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* reverseList(ListNode* head) {
ListNode* pre = nullptr;
ListNode* temp = head;
while(head){
temp = head->next;
head->next = pre;
pre = head;
head = temp;
}
return pre;
}
};
Idea 2. Método recursivo
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
def reverseList(self, head: ListNode) -> ListNode:
# pre = None
# cur = head
# while cur:
# node = cur.next
# cur.next = pre
# pre = cur
# cur = node
# return pre
if head is None or head.next is None:
return head
new_node = self.reverseList(head.next)
print('head.val',head.val)
head.next.next = head
head.next = None
return new_node
2-2: Lista vinculada giratoria
Ideas:
Después de formar una lista circular, el nodo móvil se divide
pitón:
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, val=0, next=None):
# self.val = val
# self.next = next
class Solution:
def rotateRight(self, head: ListNode, k: int) -> ListNode:
if k == 0 or head is None or head.next is None:
return head
#计算链表长度
cur = head
n = 1
while cur.next:
cur = cur.next
n += 1
# print('==n:', n)
add = n - k % n
if add == n:#k是n的整数倍直接返回原节点
return head
cur.next = head #构成环
while add:
cur = cur.next
add -= 1
new_head = cur.next#找到移动后的开始节点
cur.next = None#拆开
return new_head
Implementación de C ++:
/**
* 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* rotateRight(ListNode* head, int k) {
if(k == 0 || head == nullptr || head->next == nullptr){
return head;
}
int n = 1;//得到环长度
ListNode* cur = head;
while(cur->next){
cur = cur->next;
n++;
}
//找到移动的add长度
int add = n - k % n;
if(add == n){
return head;
}
cur->next = head;//构成环
while(add){
cur = cur->next;
add--;
}
ListNode* new_node = cur->next;
cur->next = nullptr;//拆环
return new_node;
}
};
3-1. Fusionar dos listas enlazadas ordenadas
Idea: introducir una implementación de Python de cabeza de puntero
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
def mergeTwoLists(self, l1: ListNode, l2: ListNode) -> ListNode:
head = ListNode(0)
node = head
while l1 and l2:
if l1.val < l2.val:
node.next = l1
l1 = l1.next
else:
node.next = l2
l2 = l2.next
node = node.next
if l1 is not None:
node.next= l1
if l2 is not None:
node.next= l2
return head.next
Implementación de C ++:
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {
ListNode* new_head = new ListNode(0);
ListNode* node = new_head;
while(l1!=NULL && l2 !=NULL){
if(l1->val<l2->val){
node->next = l1;
l1 = l1->next;
}
else{
node->next = l2;
l2 = l2->next;
}
node = node->next;
}
if (l1!=NULL){
node->next = l1;
}
if(l2!=NULL){
node->next = l2;
}
return new_head->next;
}
};
3-2. Fusionar K listas enlazadas ascendentes
Idea 1: La pregunta anterior fusiona los dos en un bucle for para fusionarlos en orden
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, val=0, next=None):
# self.val = val
# self.next = next
class Solution:
def mergeTwo(self, l1, l2):
if l1 is None:
return l2
if l2 is None:
return l1
head = ListNode(0)
node = head
while l1 and l2:
if l1.val <l2.val:
node.next = l1
l1 = l1.next
else:
node.next = l2
l2 = l2.next
node = node.next
if l1:
node.next = l1
if l2:
node.next = l2
return head.next
def mergeKLists(self, lists: List[ListNode]) -> ListNode:
ans = None
for i in range(len(lists)):
ans = self.mergeTwo(ans,lists[i])
return ans
c ++:
/**
* 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* mergtwo(ListNode* l1, ListNode* l2){
if(l1==nullptr){
return l2;
}
if(l2==nullptr){
return l1;
}
ListNode* new_head= new ListNode(0);
ListNode* node = new_head;
while(l1 && l2){
if(l1->val<l2->val){
node->next = l1;
l1= l1->next;
}
else{
node->next = l2;
l2= l2->next;
}
node = node->next;
}
if(l1){
node->next = l1;
}
if(l2){
node->next = l2;
}
return new_head->next;
}
ListNode* mergeKLists(vector<ListNode*>& lists) {
ListNode* res = nullptr;
for (int i=0;i<lists.size();i++){
res = mergtwo(res,lists[i]);
}
return res;
}
};
Idea 2: Divide y vencerás fusiona 1
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, val=0, next=None):
# self.val = val
# self.next = next
class Solution:
def mergeTwo(self, l1, l2):
if l1 is None:
return l2
if l2 is None:
return l1
head = ListNode(0)
node = head
while l1 and l2:
if l1.val <l2.val:
node.next = l1
l1 = l1.next
else:
node.next = l2
l2 = l2.next
node = node.next
if l1:
node.next = l1
if l2:
node.next = l2
return head.next
def mergeSort(self, lists, left, right):
if left==right:
return lists[left]
middle = left + (right-left)//2
# print('== middle:', middle)
l1 = self.mergeSort(lists,left,middle)
# print('== l1:', l1)
l2 = self.mergeSort(lists,middle+1,right)
return self.mergeTwo(l1, l2)
def mergeKLists(self, lists: List[ListNode]) -> ListNode:
# print('==hahah')
if len(lists)==0:
return None
return self.mergeSort(lists,0,len(lists) - 1)
Implementación de C ++:
/**
* 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* mergetwo(ListNode* l1, ListNode* l2){
if(l1==nullptr){
return l2;
}
if(l2==nullptr){
return l1;
}
ListNode* new_head= new ListNode(0);
ListNode* node = new_head;
while(l1 && l2){
if(l1->val<l2->val){
node->next = l1;
l1= l1->next;
}
else{
node->next = l2;
l2= l2->next;
}
node = node->next;
}
if(l1){
node->next = l1;
}
if(l2){
node->next = l2;
}
return new_head->next;
}
ListNode* mergesort(vector<ListNode*>& lists,int left, int right){
if(left==right){
return lists[left];
}
int middle = left+(right -left)/2;
ListNode* l1 = mergesort(lists,left,middle);
ListNode* l2 = mergesort(lists,middle+1,right);
return mergetwo(l1,l2);
}
ListNode* mergeKLists(vector<ListNode*>& lists) {
// ListNode* res = nullptr;
// for (int i=0;i<lists.size();i++){
// res = mergtwo(res,lists[i]);
// }
// return res;
if (lists.size()==0){
return nullptr;
}
return mergesort(lists,0,lists.size()-1);
}
};
Idea 3: fusión de ramas 2 Fusión de clasificación con referencia al algoritmo de clasificación https://blog.csdn.net/fanzonghao/article/details/81270601
class Solution:
def mergeTwo(self, l1, l2):
if l1 is None:
return l2
if l2 is None:
return l1
head = ListNode(0)
node = head
while l1 and l2:
if l1.val < l2.val:
node.next = l1
l1 = l1.next
else:
node.next = l2
l2 = l2.next
node = node.next
if l1:
node.next = l1
if l2:
node.next = l2
return head.next
def mergeSort(self, L):
if len(L) <= 1:
return L[0]
mid = len(L) // 2
l1 = self.mergeSort(L[:mid])
l2 = self.mergeSort(L[mid:])
return self.mergeTwo(l1, l2)
def mergeKLists(self, lists: List[ListNode]) -> ListNode:
if len(lists)==0:
return None
return self.mergeSort(lists)
3 -3. Combinar dos listas enlazadas ordenados
Idea: La condición de terminación recursiva es que el nodo es Ninguno.
1. Recursividad
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, val=0, next=None):
# self.val = val
# self.next = next
class Solution:
def mergeTwoLists(self, l1: ListNode, l2: ListNode) -> ListNode:
#递归的终止条件
if l1 is None:
return l2
elif l2 is None:
return l1
elif l1.val < l2.val:
l1.next = self.mergeTwoLists(l1.next,l2)
return l1
else:
l2.next = self.mergeTwoLists(l1,l2.next)
return l2
2. Método iterativo:
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
def mergeTwoLists(self, l1: ListNode, l2: ListNode) -> ListNode:
fake_head_node = ListNode(0)
cur = fake_head_node
while l1 and l2:
if l1.val<l2.val:
cur.next = l1
l1 = l1.next
else:
cur.next = l2
l2 = l2.next
cur = cur.next
if l1:
cur.next = l1
else:
cur.next = l2
return fake_head_node.next
Idea 1: La ordenación por fusión primero encuentra el punto central a través de los punteros rápido y lento para el truncamiento y luego desensambla y fusiona de forma recursiva.
código python:
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, val=0, next=None):
# self.val = val
# self.next = next
class Solution:
def merge(self, left, right):
res = ListNode(0)
temp = res
while left and right:
if left.val < right.val:
temp.next, left = left, left.next
else:
temp.next, right = right, right.next
temp = temp.next
temp.next = left if left else right
return res.next
def sortList(self, head: ListNode) -> ListNode:
if head is None or head.next is None:
return head
#快慢指针找到链表中心点
slow, fast = head, head.next
while fast and fast.next:
fast, slow = fast.next.next, slow.next
mid, slow.next = slow.next, None#将找到的中心点进行截断故 slow.next = None
left, right = self.sortList(head), self.sortList(mid)#递归一直进行拆分
return self.merge(left, right)#合并操作
código c ++:
/**
* 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* mergetwo(ListNode* l1,ListNode* l2){
ListNode* new_head = new ListNode(0);
ListNode* node = new_head;
while(l1 && l2){
if(l1->val<l2->val){
node->next = l1;
l1 = l1->next;
}
else{
node->next = l2;
l2 = l2->next;
}
node = node->next;
}
if(l1){
node->next = l1;
}
if(l2){
node->next = l2;
}
return new_head->next;
}
ListNode* sortList(ListNode* head) {
if(head==nullptr || head->next==nullptr){
return head;
}
ListNode* slow = head;
ListNode* fast = head->next;
while(fast && fast->next){
slow = slow->next;
fast = fast->next->next;
}
ListNode* middle = slow->next;
slow->next = nullptr;
ListNode* l1 = sortList(head);
ListNode* l2 = sortList(middle);
return mergetwo(l1,l2);
}
};
Idea 2: la fusión también es recursiva
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, val=0, next=None):
# self.val = val
# self.next = next
class Solution:
# def merge(self, left, right):
# res = ListNode(0)
# temp = res
# while left and right:
# if left.val < right.val:
# temp.next, left = left, left.next
# else:
# temp.next, right = right, right.next
# temp = temp.next
# temp.next = left if left else right
# return res.next
def merge(self,left,right):
if left is None:
return right
if right is None:
return left
if left.val < right.val:
left.next = self.merge(left.next, right)
return left
else:
right.next = self.merge(left, right.next)
return right
def sortList(self, head: ListNode) -> ListNode:
if head is None or head.next is None:
return head
#快慢指针找到链表中心点
slow, fast = head, head.next
while fast and fast.next:
fast, slow = fast.next.next, slow.next
mid, slow.next = slow.next, None#将找到的中心点进行截断故 slow.next = None
left, right = self.sortList(head), self.sortList(mid)#递归一直进行拆分
return self.merge(left, right)#合并操作
3-5. Suma dos números
Idea: abre una cabeza y usa un puntero para atravesar. A lo que debes prestar atención es a llevar
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, val=0, next=None):
# self.val = val
# self.next = next
class Solution:
def addTwoNumbers(self, l1: ListNode, l2: ListNode) -> ListNode:
head = ListNode(0)
new_node = head
carry = 0
while l1 and l2:
new_node.next =ListNode(l1.val+l2.val+carry)
carry = new_node.next.val//10
new_node.next.val = new_node.next.val%10
l1 = l1.next
l2= l2.next
new_node = new_node.next
# print(carry)
while l1:
new_node.next = ListNode(l1.val+carry)
carry = new_node.next.val//10
new_node.next.val = new_node.next.val%10
l1 = l1.next
new_node = new_node.next
while l2:
new_node.next = ListNode(l2.val+carry)
carry = new_node.next.val//10
new_node.next.val = new_node.next.val%10
l2 = l2.next
new_node = new_node.next
if carry:
new_node.next = ListNode(carry)
return head.next
Implementación de C ++:
/**
* 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* addTwoNumbers(ListNode* l1, ListNode* l2) {
ListNode* head = new ListNode(0);
ListNode* new_head = head;
int carry = 0;
while(l1 && l2){
new_head->next = new ListNode(l1->val + l2->val + carry);
carry = new_head->next->val/10;
new_head->next->val = new_head->next->val%10;
new_head = new_head->next;
l1 = l1->next;
l2 = l2->next;
}
while(l1){
new_head->next = new ListNode(l1->val + carry);
carry = new_head->next->val/10;
new_head->next->val = new_head->next->val%10;
new_head = new_head->next;
l1 = l1->next;
}
while(l2){
new_head->next = new ListNode(l2->val + carry);
carry = new_head->next->val/10;
new_head->next->val = new_head->next->val%10;
new_head = new_head->next;
l2 = l2->next;
}
if(carry){
new_head->next = new ListNode(carry);
}
return head->next;
}
};
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
def hasCycle(self, head: ListNode) -> bool:
#快慢指针 人追人
slow,fast = head,head
while fast:
if fast and fast.next:
slow = slow.next
fast=fast.next.next
else:
return False
if slow==fast:
return True
return False
Implementación de C ++:
/**
* 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* slow = head;
ListNode* fast = head;
while(fast){
if(fast && fast->next){
slow = slow->next;
fast = fast->next->next;
}
else{
return false;
}
if(slow==fast){
return true;
}
}
return false;
}
};
4-2 Dada una lista enlazada con bucles, implemente un algoritmo para volver al nodo inicial del bucle.
Suponga que hay dos punteros, a saber, punteros rápidos y lentos. El puntero rápido da dos pasos a la vez y el puntero lento avanza paso a paso. Si hay un anillo, los dos punteros deben coincidir;
Prueba: Suponiendo que el puntero rápido realmente cruza el puntero lento, y el puntero rápido está en la posición i + 1, y el puntero lento está en la posición i, luego, en el paso anterior, el puntero rápido está en la posición i-1 y el El puntero lento también está en la posición i-1, se encontraron.
A: punto de inicio de la lista vinculada
B: punto de inicio del anillo
C: punto de encuentro
X: la distancia desde el
punto de inicio del anillo hasta el punto de encuentro Y: la distancia desde el punto de inicio de la lista vinculada al punto de inicio del anillo
R: la longitud del anillo
S: la distancia recorrida durante el primer encuentro
1. La distancia recorrida por el puntero lento ralentiza el primer encuentro S1 = Y + X; (11)
La distancia recorrida por el puntero rápido primer encuentro rápido S2 = 2S1 = Y + X + NR; (2)
Descripción: Puntero rápido El la velocidad de es el doble de la velocidad del puntero lento, y la distancia en el mismo tiempo debe ser el doble que la del puntero lento. Y + X + NR se debe a que el puntero rápido puede pasar N vueltas antes de que los dos se encuentren;
sustituir (1) en (2) Obtenga: Y = NR -X;
2. Al devolver el puntero lento al punto A, el puntero completo y el puntero rápido se mueven al mismo tiempo y se encuentran en el punto B. Este es el nodo del anillo.
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
def detectCycle(self, head: ListNode) -> ListNode:
slow = head
fast = head;
while fast:
if fast and fast.next:
slow = slow.next
fast = fast.next.next
else:
return None
if slow==fast:
break
if fast ==None or fast.next==None:
return None
slow= head
while slow!=fast:
slow = slow.next
fast = fast.next
return slow
Implementación de C ++:
/**
* 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* slow = head;
ListNode* fast = head;
while(fast){
if(fast && fast->next){
slow = slow->next;
fast = fast->next->next;
}
else{
return NULL;
}
if(slow==fast){
break;
}
}
if(!fast || !fast->next){
return NULL;
}
slow = head;
while(slow!=fast){
slow = slow->next;
fast = fast->next;
}
return slow;
}
};
4-3 . Las listas vinculadas se cruzan
Por ejemplo, esta pregunta debería ser una pregunta de doble puntero más obvia. Si se puede implementar un algoritmo para hacer que los dos punteros vayan del punto A y el punto B al punto C respectivamente, después de que los dos punteros vayan a C respectivamente, cada uno de ellos comienza desde el punto de inicio del otro puntero., Es decir, la segunda vez que el puntero A camina desde el punto B, lo mismo es cierto para el puntero B. De esta manera, la longitud de la ruta del puntero A AO + OC + BO debe ser igual a la longitud de la trayectoria del puntero B BO + OC + AO, lo que significa que los dos punteros se encontrarán definitivamente en el punto O en la segunda ronda de la marcha. Después de que se encuentren, la condición para salir del bucle es alcanzado. El código es el siguiente:
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
def getIntersectionNode(self, headA: ListNode, headB: ListNode) -> ListNode:
index_a = headA
index_b = headB
while index_a !=index_b:
if index_a !=None:
index_a = index_a.next
else:
index_a = headB
if index_b != None:
index_b = index_b.next
else:
index_b = headA
return index_a
Implementación de C ++:
/**
* 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* node_A = headA;
ListNode* node_B = headB;
while(node_A!=node_B){
if(node_A!=NULL){
node_A=node_A->next;
}
else{
node_A = headB;
}
if(node_B!=NULL){
node_B=node_B->next;
}
else{
node_B = headA;
}
}
return node_A;
}
};
4-4. El primer nodo común de dos listas enlazadas
Idea: Los dobles punteros y los dos punteros se turnan para recorrer sus respectivas distancias, de manera que el encuentro sea un nodo público, para el caso donde no hay nodo público, hay que juzgar que el propio nodo no es ninguno, no. el siguiente es ninguno e intercambia punteros; de lo contrario, caerás en un bucle infinito y la salida es ninguna en este momento.
pitón
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
def getIntersectionNode(self, headA: ListNode, headB: ListNode) -> ListNode:
first_head = headA
second_head = headB
while first_head !=second_head:
if first_head is not None:
first_head = first_head.next
else:
first_head = headB
if second_head is not None:
second_head = second_head.next
else:
second_head = headA
# print(first_head)
return first_head
c ++:
/**
* 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 *first_node;
first_node = headA;
ListNode *second_node;
second_node= headB;
while(first_node != second_node)
{
if(first_node !=NULL)
{
first_node = first_node->next;
}
else
{
first_node = headB;
}
if(second_node !=NULL)
{
second_node = second_node->next;
}
else
{
second_node = headA;
}
}
return first_node;
}
};
1. Pedir prestado la pila
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
def reversePrint(self, head: ListNode) -> List[int]:
stack = []
while head:
stack.append(head.val)
head = head.next
return stack[::-1]
c ++:
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
vector<int> reversePrint(ListNode* head) {
vector<int> res;
while(head){
res.push_back(head->val);
head = head->next;
}
reverse(res.begin(),res.end());
return res;
}
};
2. Retroceso recursivo
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
def reversePrint(self, head: ListNode) -> List[int]:
if head:
return self.reversePrint(head.next)+[head.val]
else:
return []
5-2 . Juzgue si una lista vinculada es una lista vinculada palíndromo
Use la lista para copiar el valor de la lista y juzgue si es una cadena palíndromo
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
def isPalindrome(self, head: ListNode) -> bool:
stack= []
while head:
stack.append(head.val)
head = head.next
return stack==stack[::-1]
Implementación de C ++:
/**
* 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:
bool isPalindrome(ListNode* head) {
vector<int> res;
while(head){
res.push_back(head->val);
head = head->next;
}
int left=0;
int right=res.size()-1;
while(left<right){
if(res[left]==res[right]){
left+=1;
right-=1;
}
else{
return false;
}
}
return true;
}
};
Idea: abra dos nodos grandes y pequeños para apuntar a los mayores que x y menores que x. Una vez completado el recorrido, se pueden fusionar
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
def partition(self, head: ListNode, x: int) -> ListNode:
small_head = ListNode(0)
large_head = ListNode(0)
small_node = small_head
large_node = large_head
while head:
if head.val < x:
small_node.next = head
small_node = small_node.next
else:
large_node.next = head
large_node = large_node.next
head= head.next
large_node.next = None
small_node.next = large_head.next
return small_head.next
escritura en c ++:
/**
* 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* partition(ListNode* head, int x) {
ListNode* small_head = new ListNode(0);
ListNode* big_head = new ListNode(0);
ListNode* small_node =small_head;
ListNode* big_node = big_head;
while(head){
if (head->val<x){
small_node->next = head;
small_node = small_node->next;
}
else{
big_node->next = head;
big_node = big_node->next;
}
head = head->next;
}
big_node->next = nullptr;
small_node->next = big_head->next;
return small_head->next;
}
};
6-1. El árbol binario se expande en una lista vinculada
Idea: se puede ver que los nodos atravesados de acuerdo con el pedido anticipado se colocan en el subárbol derecho
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def help(self, node):
if node is not None:
self.res.append(node)
self.help(node.left)
self.help(node.right)
def flatten(self, root: TreeNode) -> None:
"""
Do not return anything, modify root in-place instead.
"""
self.res = []
self.help(root)
# print(self.res)
length = len(self.res)
for i in range(1,length):
pre,cur = self.res[i-1],self.res[i]
pre.left = None
pre.right = cur
return root
Implementación de C ++:
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
vector<TreeNode* >res;
void help(TreeNode* node){
if(node){
res.push_back(node);
help(node->left);
help(node->right);
}
}
void flatten(TreeNode* root) {
help(root);
for(int i=1;i<res.size();i++){
TreeNode* pre = res[i-1];
TreeNode* cur = res[i];
pre->left = nullptr;
pre->right = cur;
}
// return root;
}
};