【链表经典算法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;
}

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

相关推荐
灭霸112314 分钟前
力扣 用队列实现栈(Java)
算法·leetcode·职场和发展
-代号95271 小时前
【LeetCode】十、二分查找法:寻找峰值 + 二维矩阵的搜索
算法·leetcode·矩阵
这题怎么做?!?1 小时前
自我反思与暑假及大三上学期规划
linux·数据结构·c++
皇华ameya1 小时前
AMEYA360:类比半导体推出36V超低输入偏置电流高性能通用运算放大器
数据结构·贪心算法·动态规划
@干吧jyb1 小时前
贪心算法练习题(7/2)
数据结构·算法·leetcode·贪心算法
A22742 小时前
LeetCode 1327, 383, 236
java·算法·leetcode
jiayoushijie-泽宣2 小时前
深入浅出3D感知中的优化与基于学习的技术 (第三章) 原创教程
人工智能·算法·机器学习·3d·机器人
小oo呆4 小时前
【机器学习300问】135、决策树算法ID3的局限性在哪儿?C4.5算法做出了怎样的改进?
算法·决策树·机器学习
情系明明5 小时前
使用c++设计一个计算器
数据结构·c++·算法
神州问学6 小时前
存算一体架构或成为AI处理器技术发展关键
人工智能·算法·语言模型·架构·gpu算力