Topic: determining whether there is a singly linked list ring, if the cycloalkyl ring found ingress node;
analysis:
- The first problem: Use pointer speed (fast moving twice pointer, slow pointer once go one step further and determine whether to reach NULL, if fast == slow establishment, then the list has ring);
- The second problem: fast when the encounter with slow, slow must also not completed a revolution (contradiction provable);
schematic diagram
A starting point, B is a cyclic entry point, C point is met, then a1 = | AB | indicates the starting point to the change from the inlet, a2 = | CB | represents the meeting point of the entry point to the distance ring, s1 = | AB | + | BC | represents slow down the length of the pointer, s2 represents a pointer to go fast length, C = | BCB | denotes the length of the ring
due to the fast speed is 2 times slow, so the time is met through twice the length
S2 = 2 * S1 = a1 + N * C + (S1-a1) (1)
N represents the number of turns fast walking in the ring, dissolve (1) obtained:
S1 = N * C (2)
to find the relationship between a1 and a2 is :
A2 = the C-(S1-A1) (3)
to (2) into (3) obtained:
A1 = A2 + (N-. 1) * C (. 4)
so that if the pointer m from the starting point A, the pointer n from met eventually meet at point B with the point C after start pointer m, n bypass (N-1) rings
Problem solving:
1 struct Node { 2 int v; 3 Node *next; 4 }; 5 Node* IsCycle(Node *head) { 6 Node *fast=head, *slow=head; 7 8 while(true) { 9 if(fast!=NULL) 10 fast=fast->next; 11 if(fast!=NULL) 12 fast=fast->next; 13 else 14 return NULL; 15 if(slow!=NULL) 16 slow=slow->next; 17 else 18 return NULL; 19 20 if(fast==slow) 21 return fast; 22 } 23 } 24 Node* FindEntry(Node *head, Node *joint) { 25 Node *m=head, *n=joint; 26 while(true) { 27 if(m==n) 28 return m; 29 m=m->next; 30 n=n->next; 31 } 32 } 33 int main() { 34 Node* b1=new Node(); b1->v=1; 35 Node* b2=new Node(); b2->v=2;b1->next=b2; 36 Node* b3=new Node(); b3->v=3;b2->next=b3; 37 Node* b4=new Node(); b4->v=4;b3->next=b4; 38 Node* b5=new Node(); b5->v=5;b4->next=b5; 39 Node* b6=new Node(); b6->v=6;b5->next=b6; 40 Node* b7=new Node(); b7->v=7;b6->next=b7; 41 Node* b8=new Node(); b8->v=8;b7->next=b8; b8->next=b3; 42 43 Node* temp; 44 if((temp=IsCycle(b1))!=NULL) { 45 printf("\nthe joint point is: %d",temp->v); 46 printf("\nthe entry of cycle is: %d",FindEntry(b1,temp)->v); 47 } 48 else 49 printf("\nthere is no cycle."); 50 return 0; 51 }
Topic: determining whether the same two dual tree (left and right subtrees can not cross comparison);
Analysis: recursive implementation, the K level in the tree, there are 2 ^ K nodes, it will be (2 ^ K) * 2 times a call, the time complexity is O (N);
Problem solving:
1 struct Node { 2 int value; 3 Node *left; 4 Node *right; 5 }; 6 7 bool CompareTree(Node *first, Node *second) { 8 if(first==NULL && second==NULL) 9 return true; 10 if((first==NULL && second!=NULL) || 11 (first!=NULL && second==NULL)) 12 return false; 13 if(first->value!=second->value) 14 return false; 15 return CompareTree(first->left,second->left) && 16 CompareTree(first->right, second->right); 17 }
Reproduced in: https: //www.cnblogs.com/leo-chen-2014/p/3747122.html