LeetCode Hot Topic 100 - Linked List Topic (2)

1. Circular linked list

141. Circular linked list (question link)

Idea: Use fast and slow pointers. The slow pointer takes one step and the fast pointer takes two steps. If it is a circular linked list, then the fast and slow pointers must meet. If it is not a circular structure, the fast pointer or the next of the fast pointer must be NULL first.

code show as below:

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */
 typedef   struct ListNode ListNode ;
bool hasCycle(struct ListNode *head) {
    if(head==NULL||head->next==NULL)
    {
        return false;
    }
    ListNode* fast=head;
    ListNode* slow=head;
    while(fast&&fast->next)
    {
        
        fast=fast->next->next;
        slow=slow->next;
        if(fast==slow)
        {
            return true;
        }
    }
    return false;
    
}

 2. Circular linked list||

142. Circular linked list || (question link)

Idea: Use fast and slow pointers. The slow pointer takes one step, and the fast pointer takes two steps. If it is a ring, then the first time the fast and slow pointers meet , the number of steps the fast pointer takes is the number of steps taken by the slow pointer. Two times, S (fast) = 2k, S (slow) = k, and the fast pointer moves one more circle than the slow pointer (it can be verified here: the fast pointer does not surpass the slow pointer for the first time It may cross the slow pointer, it must coincide, you can draw and analyze it yourself) , that is, k=the number of nodes in a circle, that is, the slow pointer starts from the first The node starts from a ring node and counts the number of steps.If the fast pointer starts from the head node and the slow pointer starts from the original position, the two pointers will take one step each time, and the fast pointer will take a step After reaching the first node entering the loop, does the slow pointer move a+k times? Can we think that the slow pointer first moves a times to reach the first node in the loop, and then moves (k times = one circle) back to the original position?

code show as below: 

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */
 typedef struct ListNode ListNode;
struct ListNode *detectCycle(struct ListNode *head) {
    if(head==NULL||head->next==NULL)
    {
        return NULL;
    }
    ListNode* fast=head;
    ListNode*slow=head;
   
    do
    {
        slow=slow->next;
        fast=fast->next->next;
       
    }while((fast!=NULL&&fast->next!=NULL&&slow!=fast));
    if(fast==NULL||fast->next==NULL)
    {
        return NULL;
    }
    if(slow==fast)
    {
        fast=head;
    }
    while(fast!=slow)
    {
         slow=slow->next;
        fast=fast->next;
       
    }
    return fast;
}

3. Two pairs exchange nodes in the linked list

 24. The two exchange nodes in the linked list

Solution 1: Recursive thinking

1)Convert large to small: Change the two exchange nodes of the entire linked list into the first two nodes and then point to the back of the entire linked list. The exchanged partial linked list proceeds layer by layer and turns the whole into parts

2)Exit: If there is only one node left or NULL, this node will be returned

Create a new head node as the second node of the head node of the linked list, let the original head node point to the node returned by the subsequent exchange, let the new head node point to the original head node, and return the new head node 

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */
 typedef struct ListNode ListNode;
struct ListNode* swapPairs(struct ListNode* head) {
       if(head==NULL||head->next==NULL)
       {
           return head;
       }
      ListNode*  newhead=head->next;
      head->next=swapPairs(newhead->next);
      newhead->next=head;
      return newhead;
}

 Solution 2: Iterative thinking

Create a dumb node, called node, and the following nodes are node1 and node2. Each time the positions of node1 and node2 are exchanged, then node goes to the position of node1 after the exchange, and continues to exchange the positions of the next two nodes until there are no nodes behind it. or only one node

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */
 typedef struct ListNode ListNode;
struct ListNode* swapPairs(struct ListNode* head) {
       if(head==NULL||head->next==NULL)
       {
           return head;
       }
       ListNode*node=(ListNode*)malloc(sizeof(ListNode));
       ListNode*tmp=node;
       tmp->next=head;
      while(tmp->next!=NULL&&tmp->next->next!=NULL)
      {
         ListNode*node1=tmp->next;
         ListNode*node2=tmp->next->next;
         node1->next=node2->next;
         node2->next=node1;
         tmp->next=node2;
         tmp=node1;
      }
      return node->next;
}

4. Sorting linked list

148. Sorting linked list (question link)

 Idea: Use an array to store all the data in the linked list, then perform quick sorting on the array, then fill in the data into the linked list and return it.

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */
 int compare(const void *e1,const void *e2)
 {
     return *((int*)e1)-*((int*)e2);
 }
 typedef struct ListNode ListNode;
struct ListNode* sortList(struct ListNode* head) {
    if(head==NULL||head->next==NULL)
    {
        return head;
    }
    //至少俩个节点
    int arr[50000];
    ListNode*pcur=head;
    int i=0;
    while(pcur)
    {
        arr[i]=pcur->val;
        i++;
        pcur=pcur->next;
    }
    qsort(arr,i,sizeof(int),compare);
    pcur=head;

   for(int j=0;j<i;j++)
    {
        pcur->val=arr[j];
        pcur=pcur->next;
    }
    return head;
}

Guess you like

Origin blog.csdn.net/zhoubancheng/article/details/134274726