今天又是刷题的一天,今天给又给大家分享两道题目,两题相较昨天的两题还是挺有思考意义的,虽然对大佬来说还是简单的,但对于我们这种新手小白还是挺有练习价值的,小白可以跟我一起来看看哟。
将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。
仔细审题不难理解这里就是要我们把两个链表给链接起来,但是这里需要注意的是题目明确要求要通过给定的节点来组成,不能创建新的节点来完成。
那么下面我写一下参考答案:
这里运用尾插法,就是不断寻找两个链表当前节点val 的值哪个更小,哪个小就尾插哪个即可。
/** * Definition for singly-linked list. * struct ListNode { * int val; * struct ListNode *next; * }; */ struct ListNode* mergeTwoLists(struct ListNode* list1, struct ListNode* list2) { if(list1==NULL) { return list2; } if(list2==NULL) { return list1; } struct ListNode* phead=(struct ListNode*)malloc(sizeof(struct ListNode)); struct ListNode* tail=phead; while(list1 && list2) { if(list1->val > list2->val) { tail->next=list2; tail=list2; list2=list2->next; } else { tail->next=list1; tail=list1; list1=list1->next; } } if(list1) { tail->next=list1; } if(list2) { tail->next=list2; } struct ListNode* new=phead->next; free(phead); return new; }
代码解析:
当list1和 list2 中任意一个为空时返回另一个即可。
这里我们创建一个哨兵头,这个后面是要销毁的,为了不用特地再找开始第一个tail,到底是两个链表中的首个val,可以直接将哨兵头作为长链表开始的尾即tail=phead。然后后面的就是简单的尾插,即找到两个链表节点哪个值小然后尾插到长链表中,最后就可以将链表连接成功了。
给你一个链表的头节点 head
,判断链表中是否有环。
如果链表中有某个节点,可以通过连续跟踪 next
指针再次到达,则链表中存在环。 为了表示给定链表中的环,评测系统内部使用整数 pos
来表示链表尾连接到链表中的位置(索引从 0 开始)。注意:pos
不作为参数进行传递 。仅仅是为了标识链表的实际情况。
如果链表中存在环 ,则返回 true
。 否则,返回 false
。
审题过后我们就知道题目要求我们判断一个链表中是否有循环部分,如果有返回true,否则返回false。那么现在我们的难点就是如何判断出一个链表是否有环,这里我的方法就是快慢指针法。
下面是我的方法:
/** * Definition for singly-linked list. * struct ListNode { * int val; * struct ListNode *next; * }; */ bool hasCycle(struct ListNode *head) { struct ListNode* fast=head; struct ListNode* slow=head; while(fast && fast->next) { fast=fast->next->next; slow=slow->next; if(fast==slow) { return true; } } return false; }
代码解析:这里我的快慢还是使用一个是一次走一个节点,另一个走两个节点,那么只要在这个链表中如果存在循环那么,快的指针迟早追上慢的指针,那么有人会问追上就一定是有slow==fast吗?答案是如果快慢指针一个走一步,一个走两步那是一定会出现slow==fast的情况。 至于为什么下面在给大家解析:
大家先假设一下环的长度为C,那么如果我们快慢指针为快指针走2步,慢指针走1步,那么他们的每一步距离差距都是1,在没进入环之前是距离加一,进入环后他们走一步就是距离减一,我们可以看下图:
如图这样最后可以相遇的,但是如果快指针一次走3步,而慢的一次走1步就不一定会有相遇的情况。
好了今天文章到这。望多多支持。