Linked list classic problem

Posted by Chas267 on Sun, 06 Mar 2022 16:21:09 +0100

Reverse linked list

There are two methods to reverse the linked list: iterative method and recursive method.

Iterative method

There are two ideas. One is to move the next node of the head node to the first one at a time until the head node becomes the last one; The second is to move the first node to the back of the tail node in turn until the tail node becomes the first.

Recursive method

Assuming that all nodes except the head node have been reversed and the linked list after the head node is regarded as a whole, the operation that needs to be done is to move the head node to the back of it.

class Solution {
public:
    ListNode* reverseList(ListNode* head) {
        if(head==NULL||head->next==NULL)
            return head;
        ListNode *newhead=reverseList(head->next);
        head->next->next=head;
        head->next=NULL;
        return newhead;

    }
};

Removes the specified element

Iterative method

Use the two pointers with a gap of one to travel at the same time. If the node data of the previous pointer is equal to the specified data, it will be deleted.

Recursive method

First, assume that the specified elements in the linked list except the head node are deleted, and then delete the head node as long as the data of the head node is not equal to the specified value.

class Solution {
public:
    ListNode* removeElements(ListNode* head, int val) {
        if(head==NULL)
            return NULL;
        head->next=removeElements(head->next,val);
        if(head->val==val)
            return head->next;
        else
            return head;
    }
};

Parity linked list

Problem Description: give the head node of the order linked list {head, combine all nodes with odd index and even index respectively, and then return to the reordered list. The index of the first node is considered to be odd, the index of the second node is {even, and so on. Note that the relative order within even and odd groups should be the same as when entering. You have to solve this problem under the additional space complexity of , O(1) and the time complexity of , O(n).

This problem is a bit similar to reversing the linked list. First find the tail node of the linked list, then move the next node of the head node to the back of the tail node, and finally move the head and tail nodes one bit later. The number of cycles is the length of the linked list n/2.

class Solution {
public:
    ListNode* oddEvenList(ListNode* head) {
        if(head==NULL||head->next==NULL||head->next->next==NULL)
        return head;
        ListNode *tail,*a,*b;
        tail=head;a=head;
        int i=1;
        while(tail->next!=NULL)
        {
            tail=tail->next;
            i++;
        }
        for(int j=0;j<i/2;j++)
        {
            b=a->next;
            a->next=b->next;
            tail->next=b;
            b->next=NULL;
            tail=b;
            a=a->next;
        }
        return head;
    }
};

Determine whether it is a palindrome linked list

Iterative method

The idea of iterative method is to first reverse the first half of the linked list, and then traverse the first and second half with two pointers respectively. This practice also needs to pay attention to the parity of the length of the linked list, which is relatively complex.

class Solution {
public:
    bool isPalindrome(ListNode* head) {
        if(head==nullptr||head->next==nullptr)
        return true;
        ListNode *fast,*slow,*head1,*head2;
        fast=head->next;slow=head;
        bool isodd=false;
        while(fast->next!=nullptr)
        {
            fast=fast->next;
            if(fast->next==nullptr)
            {isodd=true; break;}
            fast=fast->next;
            slow=slow->next;
        }
        if(slow==head)
        {
            if(slow->val==fast->val)
            return true;
            else
            return false;
        }
        if(isodd)
            head2=slow->next->next;
        else
            head2=slow->next;//Find half of the list
        ListNode *a,*b;
        a=head;
        while(a!=slow)
        {
            b=a->next;
            a->next=slow->next;
            slow->next=a;
            a=b;
        }//First half reverse
        head1=slow;
        while(head2!=nullptr)
        {
            if(head1->val!=head2->val)
            return false;
            head1=head1->next;
            head2=head2->next;
        }
        return true;
    }
};

Recursive method

  • Set a global variable to hold the reference of the header node.
  • Recursion to the lowest level, and then when it returns, it is compared with the head node at the same time (the head node is from the front to the back, and he is from the back to the front)
class Solution {
    ListNode first;
    public boolean isPalindrome(ListNode head) {
        // Use recursive methods
        first = head;
        return helper(head);
    }

    public boolean helper(ListNode last){
        if(last != null){
            // Keep recursing
            if(!helper(last.next)) return false;
            // Recursion happens from back to front
            if(last.val != first.val) return false;
            first = first.next;
        }
        return true;
    }
}

The condition of bool is passed to the same element recursively, that is, the two elements pass the same condition through the chain method.

Topics: Algorithm data structure linked list