一、合并两个有序链表
21. 合并两个有序链表
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
struct ListNode* mergeTwoLists(struct ListNode* l1, struct ListNode* l2) {
// 首先判断链表是否为空
if(l1 == NULL){
return l2;
}
if(l2 == NULL){
return l1;
}
struct ListNode* head = NULL,*tail = NULL;
while(l1 != NULL && l2 != NULL){
// 如果l1的val小于l2的val就将l1的val尾差
if(l1->val < l2->val){
// 第一个tail是为NULL
if(tail == NULL){
head = tail = l1;
}
else{
// tail 已经有节点,连接下一个节点
tail->next = l1;
// 并且tail往后面走
tail = tail->next;
}
// 同时l1插入后到下一个节点
l1 = l1->next;
}else{ // 这里就是l2小了
if(tail == NULL){
head = tail = l2;
}
else{
tail->next = l2;
tail = tail->next;
}
l2 = l2->next;
}
}
// 不一定同时结束,判断谁还有剩余,将剩余的连接到后面
if(l1)
tail->next = l1;
if(l2)
tail->next = l2;
return head;
}
- 优化后:
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
struct ListNode* mergeTwoLists(struct ListNode* l1, struct ListNode* l2) {
struct ListNode* head = NULL,*tail = NULL;
// 1.首先判断链表是否为空
if(l1 == NULL){
return l2;
}
if(l2 == NULL){
return l1;
}
// 1.1可以首先取一个做头
if(l1->val < l2->val){
head = tail = l1;
l1 = l1->next;
}else{
head = tail = l2;
l2 = l2->next;
}
//1.2或者开辟一个哨兵位
// head = tail = (struct ListNode*)malloc(sizeof(struct ListNode));
// 但是注意返回值 head,需要返回第一个头,而不是哨兵位
// struct ListNode* first = head->next;
// free(head);
// return first;
while(l1 != NULL && l2 != NULL){
// 如果l1的val小于l2的val就将l1的val尾差
if(l1->val < l2->val){
tail->next = l1;
l1 = l1->next;
}else{ // 这里就是l2小了
tail->next = l2;
l2 = l2->next;
}
tail = tail->next;
}
// 不一定同时结束,判断谁还有剩余,将剩余的连接到后面
if(l1)
tail->next = l1;
if(l2)
tail->next = l2;
return head;
}
二、环形链表
141. 环形链表
思路一:快慢指针
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
bool hasCycle(struc t ListNode *head) {
struct ListNode* slow = head,*fast = head;
while(fast && fast->next){
slow = slow->next;
fast = fast->next->next;
// 如果相遇就返回true
if(slow == fast){
return true;
}
}
// 如果循环完毕,还没有等于就没有带环
return false;
}
三、环形链表2
142. 环形链表 II
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
struct ListNode *detectCycle(struct ListNode *head) {
struct ListNode* slow = head,*fast = head;
while(fast && fast->next){
slow = slow->next;
fast = fast->next->next;
// 推导的结论:一个指针从相遇点meet开始走,一个指针从head走,他们会在入口点相遇
if(slow == fast){
struct ListNode* meet = slow;
while(head != meet){
// 他们没有相等则继续往下走
head = head->next;
meet = meet->next;
}
// 退出循环则相遇
return meet;
}
}
// 表示无环等于空
return NULL;
}