【链表经典算法OJ题】(2)

4.链表的中间节点

单链表相关经典算法OJ题4: 链表的中间结点
. - 力扣(LeetCode). - 备战技术面试?力扣提供海量技术面试资源,帮助你高效提升编程技能,轻松拿下世界 IT 名企 Dream Offer。https://leetcode.cn/problems/middle-of-the-linked-list/

思路:

问题的关键也在于我们无法直接得到单链表的长度 n,常规方法也是先遍历链表计算 n,再遍历一次得到第 n / 2 个节点,也就是中间节点。

如果想一次遍历就得到中间节点,也需要耍点小聪明,使用「快慢指针」的技巧:

我们让两个指针 slow 和 fast 分别指向链表头结点 head。

每当慢指针 slow 前进一步,快指针 fast 就前进两步,这样,当 fast 走到链表末尾时,slow 就指向了链表中点。

实现代码:

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */
struct ListNode* middleNode(struct ListNode* head) 
{
    struct ListNode*fast=head,*slow=head;
    while(fast&&fast->next)
    {
        slow=slow->next;
        fast=fast->next->next;
    }
   
    return slow;
}

5.环形链表的约瑟夫问题

循环链表经典应⽤-环形链表的约瑟夫问题环形链表的约瑟夫问题_牛客题霸_牛客网编号为 1 到 n 的 n 个人围成一圈。从编号为 1 的人开始报数,报到 m 的人离开。。题目来自【牛客题霸】https://www.nowcoder.com/practice/41c399fdb6004b31a6cbb047c641ed8a

思路:

  • 成环, 返还tail结点
  • 初始化前哨指针,和当前指针
  • 遍历计数,当技术等于m了,则摘掉当前结点,从下个结点开始
  • 返回最一个指针,即当前指针的val

代码实现:

/**
 * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
 *
 * 
 * @param n int整型 
 * @param m int整型 
 * @return int整型
 */
typedef struct ListNode ListNode;
//创建节点
ListNode* buyNode(int x)
{
	ListNode* node = (ListNode*)malloc(sizeof(ListNode));
	if (node == NULL)
	{
		exit(1);

	}
	node->val = x;
	node->next = NULL;
	return node;
}

//创建带环链表
ListNode*createCircle(int n) 
{
	//先创建第一个节点
	ListNode* phead = buyNode(1);
	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)
{
	//1.根据n创建带环链表
	ListNode* prev = createCircle(n);
	ListNode* pcur = prev->next;
	int count = 1;
	//当链表中只有一个节点的情况
	while (pcur->next!=pcur)
	{
		if (count == m)
		{
			//销毁pcur节点
			prev->next = pcur->next;
			free(pcur);
			pcur = prev->next;
			count = 1;
		}
		else
		{
			//此时不需要销毁节点
			prev = pcur;
			pcur = pcur->next;
			count++;
		}
	}
	//此时剩下的一个节点就是要返回的节点里的值
	return pcur->val;
}

6.合并两个有序链表

单链表相关经典算法OJ题6: 分割链表
. - 力扣(LeetCode). - 备战技术面试?力扣提供海量技术面试资源,帮助你高效提升编程技能,轻松拿下世界 IT 名企 Dream Offer。https://leetcode.cn/problems/partition-list-lcci/

思路:

创建大小链表,比x大的插入大链表,比x小的插入小链表。

代码实现:

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */

typedef struct ListNode ListNode;
struct ListNode* partition(struct ListNode* head, int x)
{
	//创建两个带头链表
	ListNode* lessHead, * lessTail;
	ListNode* greaterHead, * greaterTail;
	lessHead = lessTail = (ListNode*)malloc(sizeof(ListNode));
	greaterHead = greaterTail = (ListNode*)malloc(sizeof(ListNode));

	//遍历原链表,将原链表的节点尾插到大小链表中
	ListNode* pcur = head;
	while(pcur)
	{
		if (pcur->val < x)
		{
			//尾插到小链表中
			lessTail->next = pcur;
			lessTail = lessTail->next;
		}
		else
		{
			//尾插到大链表中
			greaterTail->next = pcur;
			greaterTail = greaterTail->next;

		}
		pcur = pcur->next;

	}

    //修改大链表的尾节点的next指针指向
	greaterTail->next = NULL;//若不加这一行,代码会出现死循环

	//小链表的尾节点和大链表的第一个有效节点首尾相接
	lessTail->next = greaterHead->next;


	ListNode* ret = lessHead->next;

	free(lessHead);
	free(greaterHead);
	lessHead = greaterHead = NULL;

	return ret;
}

本篇文章介绍了题目的部分解法。如果本篇有补充的地方,欢迎私信我或在评论区指出,期待与你们共同进步。

相关推荐
白榆maple18 分钟前
(蓝桥杯C/C++)——基础算法(下)
算法
JSU_曾是此间年少22 分钟前
数据结构——线性表与链表
数据结构·c++·算法
sjsjs1129 分钟前
【数据结构-合法括号字符串】【hard】【拼多多面试题】力扣32. 最长有效括号
数据结构·leetcode
此生只爱蛋1 小时前
【手撕排序2】快速排序
c语言·c++·算法·排序算法
blammmp1 小时前
Java:数据结构-枚举
java·开发语言·数据结构
昂子的博客2 小时前
基础数据结构——队列(链表实现)
数据结构
咕咕吖2 小时前
对称二叉树(力扣101)
算法·leetcode·职场和发展
九圣残炎2 小时前
【从零开始的LeetCode-算法】1456. 定长子串中元音的最大数目
java·算法·leetcode
lulu_gh_yu2 小时前
数据结构之排序补充
c语言·开发语言·数据结构·c++·学习·算法·排序算法
丫头,冲鸭!!!3 小时前
B树(B-Tree)和B+树(B+ Tree)
笔记·算法