# C Language Chain List Foundation Must Brush 21 Questions - Triple Hammer (Middle)

Posted by Eng65 on Thu, 02 Dec 2021 18:43:28 +0100

# π Write before

Catalog

π Write before

π Topic 7. Palindrome Structure of Chain Lists

β Idea 1: Pointer moves from end to middle

β Idea two: Open an array

β Idea 3: Find intermediate node + backward inversion

π Question 8. Intersect Chain List

β Idea One

β Idea Two

π Question 9. Ring Chain List

β Idea 1: Use fast and slow pointers

π Questions on this topic - > Interview Extensions

π Topic 10. Ring Chain Table II

β Thought one: Push formula

β Idea Two: Variant Representation of Intersecting Chain Lists

π Question 11. Copying a chain table with random pointers

β Idea 1: Copy node links behind

π Question 12. Inserting and sorting chains

β Idea One

π Question 13. Removing duplicate nodes from a list of chains

β Idea 1: Multi-pointer problem

# π Topic 7. Palindrome Structure of Chain Lists

## β Idea 1: Pointer moves from end to middle

Pointers on both sides point to the same element -->Walk in the middle

However, because it is a single-chain list, the tail pointer cannot be moved backwards! Arrays can do this! Failed!

## β Idea two: Open an array

Open an int a[900], put the data of the chain table into an array, and use the array to judge ----------------------> Spatial Complexity O(N)

## β Idea 3: Find intermediate node + backward inversion

1. Find the middle node first---->Fast and slow pointers

2. Inverse second half--->

3. Comparison with the second half

```     //Find middle node, fast slow pointer
while(fast&&fast->next)
{
slow=slow->next;//slow take a step
fast=fast->next->next;//fast takes two steps
}
return slow;
}```
``` //Invert Chain List Using Head Interpolation
while(cur)
{
struct ListNode* next=cur->next;
cur=next;
}
}```
```/*
struct ListNode {
int val;
struct ListNode *next;
ListNode(int x) : val(x), next(NULL) {}
};*/

bool chkPalindrome(ListNode* A) {
struct ListNode* mid=middleNode(A);//Finding intermediate nodes
struct ListNode* rhead=reverseList(mid);//Invert the subsequent elements of the intermediate node
while(A&&rhead)//Comparison of two groups of elements, one ending
{
return false;
else
{
A=A->next;
}
}
return  true;
}
};```

Successfully run, but I don't know if you found one thing carefully. According to the code of the Compare program, we can find that the comparison of even numbers is easy to understand. rehead will be empty and jump out of the program at the end, but for odd numbers, why can we skip?

# π Question 8. Intersect Chain List

For this topic, intersection can only be the case in the following picture, so can be seen in the title given!

## β Idea One

Q: Determine if two linked lists intersect

Find out if the addresses of nodes in two linked lists are identical

This method is a bit time-complex and is not recommended

## β Idea Two

Q: Determine if two linked lists intersect

step1. Compare tail pointers

step2. If they intersect, find the intersection point

1. Calculate the lengths of the two chains so that the long chains can take the gap step first

2. Walk at the same time, the first identical node is the intersection

```/**
* struct ListNode {
*     int val;
*     struct ListNode *next;
* };
*/

{
return NULL;
}
int lenA=0,lenB=0;
while(curA->next)//Traverse all the way to the last node
{
curA=curA->next;//curA may be a null pointer, add judgment above
lenA++;
}
while(curB->next)
{
curB=curB->next;
lenB++;
}
//Disjoint-
if(curA!=curB)
return NULL;

//Long walk first, then at the same time
if(lenB>lenA)//If B is long A is short
{
}
int gap = abs(lenB-lenA);//abs takes absolute value
while(gap--)//Gap--take the gap step
{
longlist=longlist->next;
}
printf("1");
while(longlist!=shortlist)
{
shortlist=shortlist->next;
longlist=longlist->next;
}
return shortlist;
}```

# π Question 9. Ring Chain List

## β Idea 1: Use fast and slow pointers

1.Fast pointer-->Take two steps at a time

2.Slow pointer slow-->One step at a time

3. If you have a ring, slow and fast will meet in the ring

```/**
* struct ListNode {
*     int val;
*     struct ListNode *next;
* };
*/
while(fast&&fast->next)
{
slow=slow->next;
fast=fast->next->next;//fast takes two steps
if(slow==fast)
{
return true;
}
}
return false;
}```

# π Questions on this topic - > Interview Extensions

1. Why do slow and fast take one step and two steps? They will meet in the ring. Will they never catch up?

Proof: fast must already be in the ring when slow enters the ring. Assume that when slow enters the ring, the distance between fast and slow is N (fast follows slow, followed by N steps). For each step of slow, fast takes two steps forward and reduces the distance by one step. That is, slow takes N steps, the distance between fast and slow decreases N, and finally meets.

2.slow one step, fast three? Why?

Proof: every step of slow, every 3 steps of fast, every 2 steps of distance reduction, for distance N, only N is even, then they will meet, but if N is odd, they will miss. Assuming the ring length is C, the gap between fast and slow becomes (C-1) when it is missed. If C-1 is odd, then slow and fast never meet, because the distance reduction between slow and fast is always an even number (2)

# π Topic 10. Ring Chain Table II

## β Thought one: Push formula

Q1: Why did Slow walk L+X? Can't slow walk a little longer to meet?

A1: Because fast will catch up with slow in one circle after it enters the ring, slow is L+X. If slow has already taken one circle, then fast has already taken two circles and already caught up!

```Because of the fast pointer fast Is a slow pointer slow Move twice as far, so you can get
The formula is as follows:
2(L+X)=L+X+n*C
L+X=n*C
L=n*C-x
-------------------->```

From the above formula, it can be concluded that when a pointer moves from the point of intersection and a pointer moves from the point of beginning, they meet at the entry point.

```/**
* struct ListNode {
*     int val;
*     struct ListNode *next;
* };
*/
struct ListNode *detectCycle(struct ListNode *head) {
while(fast&&fast->next)
{
slow=slow->next;
fast=fast->next->next;
if(slow==fast)
{
//meet
struct ListNode* meet=fast;
//The deduction proves that one pointer goes from head to meet
//They will meet at the entry point
{
meet=meet->next;
}
return meet;
}
}
return NULL;
}```

# π Question 11. Copying a chain table with random pointers

138. Copy a chain table with a random pointerhttps://leetcode-cn.com/problems/copy-list-with-random-pointer/

We can easily copy the next corresponding to each node, but the element that the random pointer points to is the difficulty of this problem.

Difficulty: random of copy nodes - too inefficient and complex to process

1. For example, in Example 1 above, the second node randomly points to 7, the new chain table does not know the address of 7, and needs to be traversed. The time complexity is O(N), so the time complexity to process each node randomly is O(N*N)

2. If there are many 7 in this list, the random 7 will not know which 7 it is, and the number of nodes with a value of 7 will need to be determined.

## β Idea 1: Copy node links behind

Β

```struct Node* copyRandomList(struct Node* head) {
//The step1 copy node is behind the origin node to establish the corresponding relationship
while(cur)
{
struct Noed* next=cur->next;
struct Node* copy=(struct Node*)malloc(sizeof(struct Node));
copy-val=cur-val;
cur->next=copy
copy->next=next;

cur=next;
}```

```  //step2. Processing random of copy nodes
while(cur)
{
struct Node*copy=cur->next;
if(cur->random==NULL)
{
copy->random=NULL;
}
else
{
copy->random=cur->random->next; //This sentence is the essence
}
cur=copy->next;
}```

π The cleverness of the algorithm:

1. Make the copy random node behind the origin node by linking the copy node behind the origin node----->

2. So as long as you find the origin node that random ly points to, you will find the location of the copy node, avoiding searching in the new list of chains

```    //step3. Remove the copy nodes and link them together to restore the original list
//Sentry position for easy tail insertion
while(cur)
{
struct Node*copy=cur->next;
struct Node*next=copy->next;
//Tail insertion
copyTail->next=copy;
copyTail=copyTail->next;
cur->next=next;
cur=next;
}
free(guard);
guard=NULL;

# π Question 12. Inserting and sorting chains

147. Insertion sort of chain tablehttps://leetcode-cn.com/problems/insertion-sort-list/

Β

## β Idea One

```/**
* struct ListNode {
*     int val;
*     struct ListNode *next;
* };
*/

while(cur)//2. Termination Conditions
{
//3. Iteration Conditions
struct ListNode*next=cur->next;

//Interpolate cur nodes into the preceding ordered interval
while(c)
{
if(cur->val<c->val)
{
break;
}
else
{
p=c;
c=c->next;
}
}
if(p==NULL)
{
cur->next=c;
}
else
{
p->next=cur;
cur->next=c;
}
cur = next;
}
}```

# π Question 13. Removing duplicate nodes from a list of chains

## β Idea 1: Multi-pointer problem

Delete Problem-->Delete Duplicates-->Double Pointer Problem

```/**
* struct ListNode {
*	int val;
*	struct ListNode *next;
* };
*
* C Language declaration defines global variables. Add static to prevent duplicate definitions
*/
/**
* The class name, method name and parameter name in the code have been specified. Do not modify them, just return to the value specified by the method.
*
*
* @return ListNode class
*/
struct ListNode* deleteDuplication(struct ListNode* pHead ) {

while(next)
{
if(cur->val==next->val)
{
//Remove duplicates
while(next && cur->val==next->val)//To prevent null pointers, use the operator's short-circuit effect
{
next=next->next;
}
//Delete the node cur to next
while(cur!=next)
{
struct ListNode* del=cur;
cur=cur->next;
free(del);
}
if(prev==NULL)
{
}
else
{
prev->next=cur;
}
if(next)
{
next=next->next;
}
}
else
{
//Move back at the same time
prev=cur;
cur=next;
next=next->next;
}
}