👋大家好呀!这个是付青云同学的博客
目前一直在学习C语言。🐸
写博客是为了来记录我的学习过程,同时也希望通过博客能够帮助到需要帮助的人。
如果我的博客可以帮助到你,不妨给我一个关注哦😁!
最近在学数据结构,学了的知识后当然要巩固一下,所以就找了一些经典的链表题写一写,同时也分享一下我做题的一些思路。
另外:这个系列文章将会有上中下三部分,难度递增,下篇努力正制作中。。。
【数据结构】(图解)力扣刷题之单链表(上)
合并两个有序链表
题目描述如下(具体可以点击上方链接):
思路:
- 首先比较两个链表的头节点,将小的头节点放入直接创建的变量中
- 之后继续比较两个链表val大小,尾插
如图:
注意:当有一个链表为空时,就直接返回另外一个链表
代码如下:
struct ListNode* mergeTwoLists(struct ListNode* list1, struct ListNode* list2)
{
if(list1==NULL)
return list2;
if(list2==NULL)
return list1;
struct ListNode* head=NULL,*tail=NULL;
//将小的头节点放在head中
if(list1->val<list2->val)
{
head=tail=list1;
list1=list1->next;
}
else
{
head=tail=list2;
list2=list2->next;
}
//比较节点大小,尾插
while(list1&&list2)
{
if(list1->val<list2->val)
{
tail->next=list1;
tail=tail->next;
list1=list1->next;
}
else
{
tail->next=list2;
tail=tail->next;
list2=list2->next;
}
}
//将两个链表的尾节点放入
if(list1)
{
tail->next=list1;
}
if(list2)
{
tail->next=list2;
}
return head;
}
链表分割
题目描述如下(具体可以点击上方链接):
思路:
开辟两个新链表(lessHead和graterHead),将小于x的节点放入lessHead中,将大于等于x的节点放入graterHead中;最后将两个链表连接起来即可。
注意:在开辟空间的时候,最后一定要记得释放!
如图:
代码如下:
struct ListNode* partition(struct ListNode* pHead, int x)
{
struct ListNode* lessHead,*greaterHead,*lessTail,*greaterTail;
//创建哨兵位
lessHead=lessTail=(struct ListNode*)malloc(sizeof(struct ListNode));
lessTail->next=NULL;
greaterHead=greaterTail=(struct ListNode*)malloc(sizeof(struct ListNode));
greaterTail->next=NULL;
struct ListNode* cur=pHead;
while(cur)
{
if(cur->val < x)
{
lessTail->next=cur;
lessTail=cur;
}
else
{
greaterTail->next=cur;
greaterTail=cur;
}
cur=cur->next;
}
lessTail->next=greaterHead->next;
greaterTail->next=NULL;
struct ListNode* newnode=lessHead->next;
//注意要释放
free(lessHead);
free(greaterHead);
return newnode;
}
链表的回文结构
题目描述如下(具体可以点击上方链接):
思路:
首先找到链表的中间结点,将中间结点之后的链表翻转,之后再跟节点之前的链表比较,如果全部相同,输出true,反之输出false
链表的中间结点和反转链表
代码如下:
bool isPalindrome(struct ListNode* head)
{
//找出中间节点
struct ListNode* slow,*fast;
slow=fast=head;
while(fast && fast->next)
{
slow=slow->next;
fast=fast->next->next;
}
//中间节点逆置
struct ListNode* n1,*n2,*n3;
n1=NULL;
n2=slow;
n3=slow->next;
while(n2)
{
n2->next=n1;
n1=n2;
n2=n3;
if(n3)
{
n3=n3->next;
}
}
//比较
while(n1 && head)
{
if(head->val != n1->val)
{
return false;
}
else
{
n1=n1->next;
head=head->next;
}
}
return true;
}
相交链表
题目描述如下(具体可以点击上方链接):
方法一:暴力求解法
思路:
就是将每个节点比较,如果有相同的节点则说明相交
代码如下:
struct ListNode *getIntersectionNode(struct ListNode *headA, struct ListNode *headB)
{
struct ListNode* n1=headA;
while(n1)
{
struct ListNode* n2=headB;
while(n2)
{
if(n1==n2)
{
return n1;
}
else if(n1->next==n2->next)
{
return n1->next;
}
else
{
n2=n2->next;
}
}
n1=n1->next;
}
return NULL;
}
方法二:比尾相差法
思路:
- 将两个链表的长度求出,得到它们它们的长度之差k,
- 让长链表先走k步,随后两个链表一起走并且比较next
如果有相同的next,就说明是相交的链表
代码如下:
struct ListNode *getIntersectionNode(struct ListNode *headA, struct ListNode *headB)
{
struct ListNode* n1=headA;
struct ListNode* n2=headB;
int t1=1;
int t2=1;
int n;
while(n1->next)
{
n1=n1->next;
t1++;
}
while(n2->next)
{
n2=n2->next;
t2++;
}
//判断相交
struct ListNode* nA=headA;
struct ListNode* nB=headB;
if(n1==n2)
{
//找出相交点
//1.求出两链表长度
//2.齐头并进
n=abs(t1-t2);
while(n--)
{
if(t1>t2)
{
nA=nA->next;
}
else
{
nB=nB->next;
}
}
while(nA!=nB)
{
nA=nA->next;
nB=nB->next;
}
}
else
{
return NULL;
}
return nA;
}