一、环形链表
141.环形链表(题目链接)
思路:使用快慢指针,慢指针走一步,快指针走俩步,如果是环形链表,那么快慢指针一定相遇,如果不是环形结构那么快指针或者快指针的next一定先为NULL.
代码如下:
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
typedef struct ListNode ListNode ;
bool hasCycle(struct ListNode *head) {
if(head==NULL||head->next==NULL)
{
return false;
}
ListNode* fast=head;
ListNode* slow=head;
while(fast&&fast->next)
{
fast=fast->next->next;
slow=slow->next;
if(fast==slow)
{
return true;
}
}
return false;
}
二、环形链表||
142.环形链表||(题目链接)
思路:用快慢指针方式。慢指针走一步,快指针走俩步,如果是环形,那么快慢指针第一次相遇,快指针走的次数是慢指针的俩倍,S(快)=2k,S(慢)=k,而且快指针比慢指针多走一个环形(这里可以验证:快指针第一次超越慢指针不可能越过慢指针,必定重合,可自行画图解析) ,即k=一圈的节点数,也就是慢指针此时从第一节点出发走了一个环形节点数步数,若此时让快指针从头节点出发,慢指针从原位置出发,俩指针每次都走一步,快指针走a步到达入环的第一个节点,那么慢指针是不是走a+k次呢?是不是可以认为慢指针先走a次,到达入环第一个节点,然后再走(k次=一圈)回到原位置呢。
代码如下:
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
typedef struct ListNode ListNode;
struct ListNode *detectCycle(struct ListNode *head) {
if(head==NULL||head->next==NULL)
{
return NULL;
}
ListNode* fast=head;
ListNode*slow=head;
do
{
slow=slow->next;
fast=fast->next->next;
}while((fast!=NULL&&fast->next!=NULL&&slow!=fast));
if(fast==NULL||fast->next==NULL)
{
return NULL;
}
if(slow==fast)
{
fast=head;
}
while(fast!=slow)
{
slow=slow->next;
fast=fast->next;
}
return fast;
}
三、俩俩交换链表中的节点
24.俩俩交换链表中的节点
解法一:递归思想
1)将大化小:将整个链表俩俩交换节点化为前俩个节点交换后指向后面整体俩俩交换的部分链表,以此层层递进,将整体化为部分
2)出口:最后剩一个节点或NULL,则返回此节点
创造新的头节点为链表的头节点的第二个节点,让原来的头节点指向后面交换返回的节点,让新头节点指向原头节点,返回新头节点
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
typedef struct ListNode ListNode;
struct ListNode* swapPairs(struct ListNode* head) {
if(head==NULL||head->next==NULL)
{
return head;
}
ListNode* newhead=head->next;
head->next=swapPairs(newhead->next);
newhead->next=head;
return newhead;
}
解法二:迭代思想
创造一个哑节点,为node,紧跟后面的节点为node1和node2,每次交换node1和node2的位置,然后node走到交换后node1的位置,继续交换后面俩个节点的位置,直到后面没有节点或只有一个节点
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
typedef struct ListNode ListNode;
struct ListNode* swapPairs(struct ListNode* head) {
if(head==NULL||head->next==NULL)
{
return head;
}
ListNode*node=(ListNode*)malloc(sizeof(ListNode));
ListNode*tmp=node;
tmp->next=head;
while(tmp->next!=NULL&&tmp->next->next!=NULL)
{
ListNode*node1=tmp->next;
ListNode*node2=tmp->next->next;
node1->next=node2->next;
node2->next=node1;
tmp->next=node2;
tmp=node1;
}
return node->next;
}
四、排序链表
148.排序链表(题目链接)
思路: 用一个数组存储链表的所有数据, 然后对数组进行快排, 然后将数据填入链表 ,返回即可
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
int compare(const void *e1,const void *e2)
{
return *((int*)e1)-*((int*)e2);
}
typedef struct ListNode ListNode;
struct ListNode* sortList(struct ListNode* head) {
if(head==NULL||head->next==NULL)
{
return head;
}
//至少俩个节点
int arr[50000];
ListNode*pcur=head;
int i=0;
while(pcur)
{
arr[i]=pcur->val;
i++;
pcur=pcur->next;
}
qsort(arr,i,sizeof(int),compare);
pcur=head;
for(int j=0;j<i;j++)
{
pcur->val=arr[j];
pcur=pcur->next;
}
return head;
}