Linked list OJ problem

insert image description here
Today I will talk about some Oj questions about linked lists. I believe you will raise the linked list to another level after reading it.

topic one

insert image description here
Idea 1
Traversing the linked list is free when Val is worth it, and then we go back until we reach the null pointer at the end. The new linked list is our answer, so let's express it with code.


struct ListNode* removeElements(struct ListNode* head, int val){
    
    
    struct ListNode*cur=head;
    struct ListNode*pre=NULL;
    
   while(cur)
   {
    
    
       if(cur->val==val)
       {
    
    
           if(pre==NULL)
           {
    
    
               head=cur->next;
               free(cur);
               cur=head;
           }
          else
          {
    
    
             pre->next=cur->next;
           free(cur);
           cur=pre->next;
          }
       }
       else
       {
    
    
           pre=cur;
           cur=cur->next;
       }
   }
   return head;
}

Idea 2
If it is not val, we will take it down, if it is val, we will skip it and put it in a new linked list.

struct ListNode* removeElements(struct ListNode* head, int val){
    
    
        struct ListNode*tail=NULL;
        struct ListNode*cur=head;
       
        head=NULL;
        while(cur)
        {
    
    
            if(cur->val==val)
            {
    
    
                cur=cur->next;
            }
            else
            {
    
    
                if(tail==NULL)
                {
    
    
                    head=tail=cur;
                }
                else
                {
    
    
                    tail->next=cur;
                    tail=tail->next;
                }
                 cur=cur->next;
            }
        }
        if(tail)
          tail->next=NULL;   

    return head;
}

Idea 3
The way to get the head node with the sentinel position is to take down the val, not skip it.


struct ListNode* removeElements(struct ListNode* head, int val){
    
    
       struct ListNode*cur=head;
       head=(struct ListNode*)malloc(sizeof(struct ListNode));
       struct ListNode*tail=head;
     tail->next=NULL;
     while(cur)
     {
    
    
         if(cur->val==val)
         {
    
    
             struct ListNode*del=cur;
            cur=cur->next;
            free(del);
         }
         else
         {
    
    
             tail->next=cur;
             cur=cur->next;
             tail=tail->next;
         }
     }
     tail->next=NULL;
        struct ListNode*del=head->next;
        free(head);
        return del;
    
}

Topic two

insert image description here

We can change the direction of this question, give three pointer variables, and change the direction to solve it.

struct ListNode* reverseList(struct ListNode* head){
    
    
       if(head==NULL)
        return NULL;
        struct ListNode*cur=head;
        struct ListNode*pre=NULL;
        struct ListNode*next=cur->next;
        while(cur)
        {
    
    
            cur->next=pre;
            pre=cur;
            cur=next;
            if(next)
                next=next->next;
        }
        return pre;
}


Just insert the second end of the idea into the new linked list.

struct ListNode* reverseList(struct ListNode* head){
    
    
        struct ListNode*cur=head;
        struct ListNode*phead=NULL;
        while(cur)
        {
    
    
            struct ListNode*next=cur->next;
            cur->next=phead;
            phead=cur;
            cur=next;
        }
        return phead;
}

Topic three

insert image description here

Use the speed pointer, take two steps fast and one step slow, and you can solve the problem.

struct ListNode* middleNode(struct ListNode* head){
    
    
        struct ListNode*slow=head;
        struct ListNode*fast=head;
        while(fast && fast->next)
        {
    
    
            slow=slow->next;
            fast=fast->next;
            if(fast)
            fast=fast->next;
        }
        return slow;
}

Topic four

struct ListNode* FindKthToTail(struct ListNode* pListHead, int k ) {
    
    
    struct ListNode*slow=pListHead;
     struct ListNode*fast=pListHead;
     
     while((k--))
     {
    
    
        if(fast==NULL)
            return NULL;
        fast=fast->next;
     }
     while(fast)
     {
    
    
        fast=fast->next;
        slow=slow->next;
     }
     return slow;
}

insert image description here

This question is similar to the fast and slow pointer. Let the fast pointer go k steps first, and then walk at the same time. The end condition is when the fast pointer is empty.

Today I will share four topics first, and I will continue to share a few more later! ! ! thanks for watching

Guess you like

Origin blog.csdn.net/2301_76895050/article/details/132364220