Common techniques for brushing single-linked list questions - constructing sentinel bits

Look deep into your heart and find that all the miracles are in yourself 

Past review:

Common techniques for brushing questions in linked lists - fast and slow pointers

【LeetCode】Single Linked List——Brush Questions

Data Structure - Singly Linked List

Table of contents

Merge two sorted lists

Ideas and Diagrams

Issues that require additional attention 

core code

Linked list partition

Ideas and Diagrams

core code


  Hello everyone, I am Ji Ning. This article introduces to you a common idea in the single-linked list brushing stage-constructing sentinel bits.

  Singly linked lists are divided into two types: leading nodes and non-leading nodes. The first node of the single linked list of the leading node, also called the sentinel bit, belongs to the additional linked list node, has no valid value, only stores the address of the first valid node, and is responsible for finding the first node.

  Then, how to construct the sentinel bit to simplify the OJ problem is a question we need to think about.

  As we all know, in interview questions, written test questions, competition questions and the LeetCode exercises we usually do, the singly linked list given in the title has no sentinel position, and if we want to insert, delete or newly create a single linked list The operation of the node is very complicated, and the pointing of the head pointer is usually changed, and the particularly troublesome boundary is considered.

  Although there are no sentinel slots in many OJ questions, we can consider manually constructing and opening up one or more sentinel slot spaces. After the sentry slots are available, when operating the newly created linked list, the first step only needs to be tail insertion. That's it.

Merge two sorted lists

Merges two ascending lists into a new  ascending  list and returns. The new linked list is formed by splicing all the nodes of the given two linked lists

For example:

Input: l1 = [1,2,4], l2 = [1,3,4]
 Output: [1,1,2,3,4,4]

Example 2:

Input: l1 = [], l2 = []
output: []
Example 3:

Input: l1 = [], l2 = [0]
output: [0]

Ideas and Diagrams

  Compare the nodes of the two linked lists one by one, insert the smaller tail to the back of the new linked list, and each time the tail is inserted, the pointers of the new linked list and the linked list with a smaller value must move forward, and stop the loop if one is empty, and finally Then insert all the linked list nodes that are not empty into the new linked list.

Issues that require additional attention 

To consider the case where a linked list is empty

Because it needs to be tail-inserted into the new linked list, it is necessary to open up an additional space for the sentinel bit, which can facilitate continuous tail-insertion, because it does not need to change the pointing of the head pointer.

To release the space of the sentry position in time

After the loop ends, the linked list that has not been traversed should continue to be inserted into the back of the new linked list

core code

struct ListNode* mergeTwoLists(struct ListNode* list1, struct ListNode* list2){
    struct ListNode *head,*tail;
    head=tail=(struct ListNode*)malloc(sizeof(struct ListNode));
    if(list1==NULL)
        return list2;
    if(list2==NULL)
        return list1;
    while(list1&&list2)
    {
        if(list1->val<list2->val)
        {
            tail->next=list1;
            list1=list1->next;
            tail=tail->next;
        }
        else
        {
            tail->next=list2;
            list2=list2->next;
            tail=tail->next;
        }
    }
    while(list1)
    {
        tail->next=list1;
        list1=list1->next;
        tail=tail->next;
    }
    while(list2)
    {
        tail->next=list2;
        list2=list2->next;
        tail=tail->next;
    }
    struct ListNode *del=head->next;
    free(head);
    return del;
}

Linked list partition

There is a head pointer ListNode* pHead of a linked list  , given a certain value x, write a piece of code to arrange all nodes smaller than x before the rest of the nodes, and the original data order cannot be changed, and return the head pointer of the rearranged linked list.

  As shown in the figure, the given linked list is 4-5-3-1-2-7, given a certain value of 3, the value after division is 1-2-4-5-3-7

Ideas and Diagrams

  Create two linked lists with sentinel bits, store nodes with values ​​less than x and nodes with values ​​greater than x respectively, store all the data behind these two new linked lists, and then point the tail node of the linked list less than x to the one greater than x The first valid node of the linked list, and finally empty the next of the tail node of the linked list greater than x.

core code

class Partition {
public:
    ListNode* partition(ListNode* pHead, int x) {
        ListNode*tail2,*cur2,*tail1,*cur1;//哨兵位
        tail1=cur1=(ListNode*)malloc(sizeof(ListNode));//小于x的
        tail2=cur2=(ListNode*)malloc(sizeof(ListNode));//大于x的
        while(pHead)
        {
            if(pHead->val<x)
            {
                cur1->next=pHead;
                cur1=cur1->next;
            }
            else 
            {
                cur2->next=pHead;
                cur2=cur2->next;
            }
             pHead=pHead->next;
        }
        cur1->next=tail2->next;
        cur2->next=NULL;
        ListNode *del=tail1->next;
        free(tail1);
        free(tail2);
        return del;
    }
};

Note: cur2->next must be empty, otherwise there may be a loop and cannot end.

Supongo que te gusta

Origin blog.csdn.net/zyb___/article/details/132051273
Recomendado
Clasificación