单链表OJ题
- 前言
- 一、返回链表开始入环的第一个节点
- 思路一
- 思路二
- 二、返回链表的深度拷贝
- 总结
前言
此次练习题有两道!
有点小难度,但相信难不住大家的!
我也会给出两道OJ题的链接,大家也赶快去试一试吧
一、返回链表开始入环的第一个节点
题目链接:OJ链接
提示:
链表中节点的数目范围在范围 [0, 104] 内
-105 <= Node.val <= 105
pos 的值为 -1 或者链表中的一个有效索引
本题有两个解析思路~
思路一
代码演示:
//解题方法一
struct ListNode *detectCycle(struct ListNode *head) {struct ListNode *move1=head;struct ListNode *move2=head;while(move1&&move2&&move2->next){//快慢指针移动move1=move1->next;move2=move2->next->next;if(move1==move2){{//找到相遇点struct ListNode *meet=move1;//meet从相遇点开始移动struct ListNode *move3=head;//move3从head开始移动while(meet!=move3){//两个指针同时移动找到起始点meet=meet->next;move3=move3->next;}return meet;}}return NULL;
}
思路二
提示:如果不了解如何找出公共点的的话,前面的博客会对大家有所帮助!
博客链接:单链表OJ题
代码演示:
//解题方法二
struct ListNode *detectCycle(struct ListNode *head) {struct ListNode *move1=head;struct ListNode *move2=head;while(move1&&move2&&move2->next){//快慢指针移动move1=move1->next;move2=move2->next->next;if(move1==move2){//找到相遇点struct ListNode *temp=move1;//保存相遇点位置move1=move1->next;//将move1变为第二链表起始点temp->next=NULL;//将相遇点的next置空struct ListNode *head1=head;struct ListNode *head2=move1;int len1=0,len2=0;while(head1!=NULL){//计算链表长度len1++;head1=head1->next;}while(head2!=NULL){head2=head2->next;len2++;}int k=abs(len1-len2);//得到两链表长度相减的绝对值//将longs指向较长的链表,shorts指向较短的链表struct ListNode *shorts=head;struct ListNode *longs=move1;if(len1>len2){shorts=move1;longs=head;}while(k--&&longs!=NULL){//较长的链表移动k位longs=longs->next;}if(k>0&&longs==NULL){return NULL;}while(shorts!=longs){//两链表同时遍历,找到第一个公共点shorts=shorts->next;longs=longs->next;}return longs;}}return NULL;
}
二、返回链表的深度拷贝
题目链接:OJ链接
提示:
0 <= n <= 1000
-104 <= Node.val <= 104
Node.random 为 null 或指向链表中的节点。
解题思路:
代码演示
struct Node* BuyNewnode(int x){//创建结点函数struct Node*newnode=(struct Node*)malloc(sizeof(struct Node));newnode->val=x;newnode->next=NULL;newnode->random=NULL;return newnode;
}
//查找random所在位置的函数
struct Node* findrandom(struct Node* head,struct Node* newhead,struct Node* random){struct Node*move1=head;struct Node*move2=newhead;while(move1!=random){move1=move1->next;move2=move2->next;}return move2;
}struct Node* copyRandomList(struct Node* head) {struct Node*move=head;struct Node*newhead=NULL;struct Node*tail=NULL;while(move!=NULL){//将新建结点依次尾插到新链表中if(tail==NULL){struct Node*newnode= BuyNewnode(move->val);newhead=tail=newnode;move=move->next;}else{struct Node*newnode= BuyNewnode(move->val);tail->next=newnode;tail=tail->next;move=move->next;}}struct Node*setran=newhead;struct Node*findran=head;while(setran&&findran){struct Node*temp=findrandom(head,newhead,findran->random);setran->random=temp;setran=setran->next;findran=findran->next;}return newhead;
}
总结
这次的题目稍稍有些难度!
但是绝对难不倒大家的!
加油! 加油!