目录
[1.3 单链表相关经典算法OJ题3:链表的中间节点](#1.3 单链表相关经典算法OJ题3:链表的中间节点)
1.单链表经典算法OJ题⽬
1.1单链表相关经典算法OJ题1:移除链表元素
cpp
struct ListNode* removeElements(struct ListNode* head, int val) {
struct ListNode* newhead,* newtail;
newtail=newhead=NULL;
struct ListNode* pcur=head;
while(pcur)
{
if(pcur->val!=val)
{
if(newhead==NULL)
{
newhead=newtail=pcur;
}
else{
newtail->next=pcur;
newtail=newtail->next;
}
}
pcur=pcur->next;
}
if(newtail)
newtail->next=NULL;
return newhead;
}
1.2单链表相关经典算法OJ题2:反转链表
思路一:
cpp
struct ListNode* reverseList(struct ListNode* head) {
struct ListNode* prev = NULL;
struct ListNode* curr = head;
while (curr) {
struct ListNode* next = curr->next;
curr->next = prev;
prev = curr;
curr = next;
}
return prev;
}
思路二:(指针)
1.3 单链表相关经典算法OJ题3:链表的中间节点
思路一:计数法
cpp
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
struct ListNode* middleNode(struct ListNode* head) {
struct ListNode* p=head;
struct ListNode* q=head;
int k=0,j=0;
while(p)
{
k++;
p=p->next;
}
struct ListNode* phead=NULL;
struct ListNode* ptail=NULL;
while(q)
{
j++;
if(j>=k/2+1)
{
if(phead==NULL)
phead=ptail=q;
else
{
phead->next=q;
phead=phead->next;
}
}
q=q->next;
}
if(phead) phead->next=NULL;
return ptail;
}
思路二:快慢指针
cpp
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
struct ListNode* middleNode(struct ListNode* head) {
struct ListNode* slow=head;
struct ListNode* fast=head;
while(fast&&fast->next)
{
slow=slow->next;
fast=fast->next->next;
}
return slow;
}
1.4单链表相关经典算法OJ题4:合并两个有序链表
1.5 循环链表经典应⽤------环形链表的约瑟夫问题
著名的Josephus问题
据说著名犹太历史学家Josephus有过以下的故事:在罗⻢⼈占领乔塔帕特后,39个犹太⼈与 Josephus及他的朋友躲到⼀个洞中,39个犹太⼈决定宁愿死也不要被⼈抓到,于是决定了⼀个⾃杀 ⽅式,41个⼈排成⼀个圆圈,由第1个⼈开始报数,每报数到第3⼈该⼈就必须⾃杀,然后再由下⼀ 个重新报数,直到所有⼈都⾃杀⾝亡为⽌。
然⽽Josephus和他的朋友并不想遵从,Josephus要他的朋友先假装遵从,他将朋友与⾃⼰安排在 第16个与第31个位置,于是逃过了这场死亡游戏。
cpp
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param n int整型
* @param m int整型
* @return int整型
*/
struct ListNode* buynode(int x)
{
struct ListNode*newnode=(struct ListNode*)malloc(sizeof(struct ListNode));
newnode->val=x;
newnode->next=NULL;
return newnode;
}
struct ListNode* create(int n)
{
struct ListNode* phead=buynode(1);
struct ListNode* ptail=phead;
for(int i=2;i<=n;i++)
{
ptail->next=buynode(i);
ptail=ptail->next;
}
ptail->next=phead;
return ptail;
}
int ysf(int n, int m ) {
struct ListNode*prev=create(n);
struct ListNode*pcur=prev->next;
int count=1;
while(pcur->next!=pcur)
{
if(count==m)
{
prev->next=pcur->next;
free(pcur);
pcur=prev->next;
count=1;
}
else {
{
prev=pcur;
pcur=pcur->next;
count++;
}
}
}
return pcur->val;
}
1.4单链表相关经典算法OJ题5:分割链表
cpp
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
struct ListNode* partition(struct ListNode* head, int x){
if(head==NULL)
{
return head;
}
struct ListNode* lesshead,*lesstail;
struct ListNode* greatehead,*greatetail;
lesshead=lesstail=(struct ListNode*)malloc(sizeof(struct ListNode));
greatehead=greatetail=(struct ListNode*)malloc(sizeof(struct ListNode));
struct ListNode*pcur=head;
while(pcur)
{
if(pcur->val<x)
{
lesstail->next=pcur;
lesstail=lesstail->next;
}
else{
greatetail->next=pcur;
greatetail=greatetail->next;
}
pcur=pcur->next;
}
greatetail->next=NULL;
lesstail->next=greatehead->next;
return lesshead->next;
}