Algunas preguntas de leetcode de la lista enlazada + python (c ++)

Los siguientes puntos de conocimiento son principalmente comunes: 

1-1. Escriba una función para eliminar un nodo dado (no final) en una lista vinculada, y solo se le dará una solicitud para eliminar el nodo.

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;
    }
};

2-1 . Lista enlazada inversa

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
            

3-4. Ordenar lista enlazada

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;



    }
};

 

4-1 . Lista enlazada circular

# 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;
        
    }
};

5-1 Ingrese el nodo principal de una lista vinculada y devuelva el valor de cada nodo desde el final hasta el principio (regrese con una matriz).

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;

    }
};

5-3. Lista vinculada separada

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;
    }
};

 

Supongo que te gusta

Origin blog.csdn.net/fanzonghao/article/details/113889824
Recomendado
Clasificación