一、合并两个有序链表(leetcode_21)
将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。
【思路】创建一个新的链表(malloc),两个链表的元素依次比较大小,较小就放到新的链表里,直至其中一个链表为空,再将另一个链表剩下的部分接上
注意:链表为空的情况要分开讨论
struct ListNode* mergeTwoLists(struct ListNode* list1, struct ListNode* list2) {
struct ListNode* cur1 = list1;
struct ListNode* cur2 = list2;
struct ListNode* tmp =(struct ListNode*)malloc(sizeof(struct ListNode));
struct ListNode* cur = tmp;
if(cur1 == NULL && cur2 == NULL)
return NULL;
else if(cur1 == NULL)
return cur2;
else if(cur2 == NULL)
return cur1;
while(cur1 && cur2)
{
if(cur1->val >= cur2->val)
{
cur->next = cur2;
cur2 = cur2->next;
}
else
{
cur->next = cur1;
cur1 = cur1->next;
}
cur = cur->next;
}
if(cur1!=NULL)
{
cur->next=cur1;
}
if(cur2!=NULL)
{
cur->next=cur2;
}
return tmp->next;
}
二、反转链表(leetcode_206)
给你单链表的头节点 head
,请你反转链表,并返回反转后的链表。
【思路】创建三个指针,前两个指针用来转变指向,第三个指针为了保存下一个,方便下一次转换
【图解】
step1
step2
step3
step4
依次循环即可
struct ListNode* reverseList(struct ListNode* head) {
if(head == NULL)
{
return NULL;
}
struct ListNode* n1 = NULL;
struct ListNode* n2 = head;
struct ListNode* n3 = head->next;
while(n2)
{
n2->next = n1;
n1 = n2;
n2 = n3;
if(n2) //避免对空指针解引用
n3 = n2->next;
}
return n1;
}
三、链表中间结点(leetcode_876)
给你单链表的头结点 head
,请你找出并返回链表的中间结点。
如果有两个中间结点,则返回第二个中间结点。
【思路】创建两个指针,一个一次走一步,另一个一次走两步,快指针走到末尾时慢指针指向中间结点
如果是奇数个结点,当快指针指向最后一个结点时结束,慢指针指向中间结点;
如果是偶数个结点,当快指针指向空时结束,慢指针指向第二个中间结点;
【图解】
typedef struct ListNode Node;
struct ListNode* middleNode(struct ListNode* head){
Node* slow = head;
Node* fast = head;
while(fast != NULL && fast->next != NULL)
{
slow = slow->next;
fast = fast->next->next;
}
return slow;
}
四、链表的回文结构(牛客OR36)
对于一个链表,请设计一个时间复杂度为O(n),额外空间复杂度为O(1)的算法,判断其是否为回文结构。
给定一个链表的头指针A,请返回一个bool值,代表其是否为回文结构。保证链表长度小于等于900。
样例:1->2->2->1
返回:true
【思路】这道题可以拆解为中间结点和反转链表两个部分,也就是第二题和第三题的结合,思路都是和上面一样的。然后从两边开始遍历,直到遍历到中间结点停止,若全都相等返回true,反之返回false
bool chkPalindrome(ListNode* A) {
ListNode* fast = A, *slow = A;
ListNode* cur = A;
while(fast)
{
slow = slow->next;
if(fast->next)
fast = fast->next->next;
else
break;
}
ListNode* n1 = NULL, *n2 = A, *n3 = A->next;
while (n1 != slow)
{
n1 = n2;
n2 = n2->next;
n3 = n2->next;
}
while(n2)
{
n2->next = n1;
n1 = n2;
n2 = n3;
n3 = n2->next;
}
while(1)
{
if(cur->val == n1->val)
{
cur = cur->next;
n1 = n1->next;
if(cur == slow)
return true;
}
else
return false;
}
}
你学会了吗?