20210308 et 20210309: une collection de questions de liste chaînée

Examen des sujets de liste liée

Ecrire devant

  1. La dernière fois que cette catégorie de sujets a été écrite, c'était il y a exactement 6 mois, c'est-à-dire que mes deux blogs, 20200908 et 20200909, concernaient tous les sujets de cet article, qui sont liés aux listes chaînées. Le petit objectif de ce mois-ci est de fusionner et de réécrire les catégories des sujets de Likou avant la fin. Visant à améliorer le niveau général de l'architecture, l'auto-évaluation est que je suis devenu plus compétent et maîtrisé systématiquement le cpp cette année. Bien que ma direction personnelle soit SDR, les exercices de réflexion comme des algorithmes ne sont toujours pas disponibles. Le développement futur sera matériel ou ou la simulation est indissociable de ces capacités de base. C'est tout le non-sens, tout le monde encourage!

sujet

    1. Liste liée inversée
      Insérez la description de l'image ici
    1. Liste liée inversée II
      Insérez la description de l'image ici
    1. Liste circulaire liée II
      Insérez la description de l'image ici
    1. Liste fractionnée
      Insérez la description de l'image ici
    1. Copier une liste liée avec des pointeurs aléatoires
      Insérez la description de l'image ici
    1. Combiner K listes chaînées ascendantes
      Insérez la description de l'image ici

Idées et algorithmes

    1. Liste liée inversée
    1. Liste liée inversée II
    1. Liste circulaire liée II
    1. Liste fractionnée
    1. Copier une liste liée avec des pointeurs aléatoires
    1. Combiner K listes chaînées ascendantes

Les sujets ci-dessus doivent être considérés comme couvrant la plupart des principaux points de la liste chaînée.L'écriture et la maîtrise des idées peuvent fondamentalement faire ce genre de sujets avec facilité.

Code

  1. Liste liée inversée
/**
 * 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* new_head = NULL;
        while (head) {
    
    
            // 备份head->next
            ListNode* tmp = head->next;
            // 更新head->next
            head->next = new_head;
            // 移动head_next
            new_head = head;
            // 遍历链表
            head = tmp;
        }
        return new_head;
    }
};
  1. Liste liée inversée II
/**
 * 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* reverseBetween(ListNode* head, int m, int n) {
    
    
        int change_len = n - m + 1;
        ListNode* pre_head = NULL;
        ListNode* result = head;
        // 将head向前移动m-1次找到中间段 翻转之前的head,
        while (head && --m) {
    
    
            pre_head = head;
            head = head->next;
        }
        // 这个head就是翻转之后的中间段的tail,这里直接给好
        ListNode* tail = head;

        ListNode* new_head = NULL;
        // m-n段的翻转操作
        while (head && change_len) {
    
    
            // 备份即将被翻转的head的下一跳
            ListNode* next = head->next;
            // 重新指定下一跳为新的new_head
            head->next = new_head;
            // head和new_head更新
            new_head = head;
            head = next;
            // 最后要翻转n-m+1次。
            --change_len;
        }
        // 最后连接子段和原来的pre_head以及尾巴,注意此时的尾巴就是head
        tail->next = head;
        if (pre_head) {
    
    
            pre_head->next = new_head;
        } else {
    
    
            // 注意如果pre_head为NULL,那么结果直接返回new_head,即若是从第一个位置开始翻转,那么头节点不能为空。
            result = new_head;
        }
        return result;
    }
};
    1. Liste circulaire liée II
/**
 * 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) {
    
    
        std::set<ListNode*> node_set;
        while(head) {
    
    
            if(node_set.find(head) != node_set.end()) {
    
    
                return head;
            }
            node_set.insert(head);
            head = head->next;
        }
        return NULL;
    }
};
    1. Liste fractionnée
/**
 * 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 less_head;
        ListNode more_head;
        ListNode* less_ptr = &less_head;
        ListNode* more_ptr = &more_head;
        // 遍历,将链表的数据分类跟在more_head和less_head之后
        while (head) {
    
    
            if (head->val >= x) {
    
    
                more_ptr->next = head;
                more_ptr = head;
            } else {
    
    
                less_ptr->next = head;
                less_ptr = head;
            }
            head = head->next;
        }
        // 连接即可
        less_ptr->next = more_head.next;
        more_ptr->next = NULL;
        // 注意返回不要搞错了,返回的是less_head.next
        return less_head.next;
    }
};
    1. Copier une liste liée avec des pointeurs aléatoires
/*
// Definition for a Node.
class Node {
public:
    int val;
    Node* next;
    Node* random;
    
    Node(int _val) {
        val = _val;
        next = NULL;
        random = NULL;
    }
};
*/

class Solution {
    
    
public:
    Node* copyRandomList(Node* head) {
    
    
        map<Node*,int> node_map;
        vector<Node*> node_vec;
        Node* ptr = head;
        // 遍历,用map将对应的id存起来,用vec将对应的节点存下来
        int i = 0;
        while (ptr) {
    
    
            node_vec.push_back(new Node(ptr->val));
            node_map[ptr] = i;
            ptr = ptr->next;
            ++i;
        }
        node_vec.push_back(0);
        // 再次遍历链表并进行连接next和random指针域
        ptr = head;
        i = 0;
        while (ptr) {
    
    
            // 连接next域
            node_vec[i]->next = node_vec[i + 1];
            // 连接random域
            if (ptr->random) {
    
    
                int id = node_map[ptr->random];
                node_vec[i]->random = node_vec[id];
            }
            ptr = ptr->next;
            ++i;
        }
        return node_vec[0];
     }
};
    1. Combiner K listes chaînées ascendantes
/**
 * 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* mergeKLists(vector<ListNode*>& lists) {
    
    
        if (lists.size() == 0) {
    
    
            return NULL;
        }
        if (lists.size() == 1) {
    
    
            return lists[0];
        }
        if (lists.size() == 2) {
    
    
            return mergeTwoLists(lists[0],lists[1]);
        }
        int mid = lists.size() / 2;
        vector<ListNode*> subList1;
        vector<ListNode*> subList2;
        for (int i = 0; i < mid; ++i) {
    
    
            subList1.push_back(lists[i]);
        }
        for (int i = mid; i < lists.size(); ++i) {
    
    
            subList2.push_back(lists[i]);
        }

        ListNode* l1 = mergeKLists(subList1);
        ListNode* l2 = mergeKLists(subList2);
        return mergeTwoLists(l1,l2);

    }

    ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {
    
    
        ListNode tmp_head(0);
        ListNode* pre = &tmp_head;
        while (l1 && l2) {
    
    
            if (l1->val < l2->val) {
    
    
                pre->next = l1;
                l1 = l1->next;
            } else {
    
    
                pre->next = l2;
                l2 = l2->next;
            }
            pre = pre->next;
        }
        if (l1) {
    
    
            pre->next = l1;
        }
        if (l2) {
    
    
            pre->next = l2;
        }
        return tmp_head.next;
    }
};

Je suppose que tu aimes

Origine blog.csdn.net/qq_36828395/article/details/114608255
conseillé
Classement