出题:判断一个单向链表是否有环,如果有环则找到环入口节点;
分析:
- 第一个问题:使用快慢指针(fast指针一次走两步,slow指针一次走一步,并判断是否到达NULL,如果fast==slow成立,则说明链表有环);
- 第二个问题:fast与slow相遇时,slow一定还没有走完一圈(反证法可证明);
示意图
A为起始点,B为环入口点,C为相遇点,则a1=|AB|表示起始点到换入口的距离,a2=|CB|表示相遇点到环入口点的距离,s1=|AB|+|BC|表示slow指针走的长度,s2表示fast指针走的长度,C=|BCB|表示环的长度
由于fast的速度是slow的2倍,所以相遇的时候走过的长度也是2倍
s2=2*s1=a1+N*C+(s1-a1)
(1)
N表示fast在环中走的圈数,化解(1)得到:
s1=N*C
(2)
找到a1和a2的关系:
a2=C-(s1-a1)
(3)
将(2)代入(3)得到:
a1=a2+(N-1)*C
(4)
所以如果指针m从起始点A出发,指针n从相遇点C出发,n绕行(N-1)圈环之后最终跟m指针在B点相遇
解题:
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 }
出题:判断两棵二元树是否相等(左右子树不能交叉比较);
分析:使用递归实现,在树的K层,有2^K 个节点,所以会进行(2^K)*2次调用,所以时间复杂度为O(N);
解题:
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 }
时间: 2024-08-03 06:40:46