当前位置: 首页 > article >正文

【数据结构】链表OJ题

目录

  • 面试题 02.04 分割链表
  • 剑指 Offer II 027 回文链表
  • 160 相交链表
  • 141 环形链表
  • 142 环形链表 II
  • 138 复制带随机指针的链表

面试题 02.04 分割链表

  • 定义lesshead和greaterhead链接小于和大于等于k的值
  • 分别设置哨兵位和尾节点指针
  • 最后将两表去除哨兵位再链接

在这里插入图片描述

struct ListNode* partition(struct ListNode* head, int x)
{
	struct ListNode* lesshead, * lesstail, * greaterhead, * 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 = head;
	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* newhead = lesshead->next;

	free(lesshead);
	free(greaterhead);
	return newhead;
}

 

剑指 Offer II 027 回文链表

  • 先找到链表中间节点
  • 将中间节点以后的节点从原链表截断逆置生成新链表
  • 与原链表逐节点的值相比较
    在这里插入图片描述
//回文结构
bool isPalindrome(struct ListNode* head) {
	if (head == NULL)
	{
		return false;
	}

	//找中间节点
	struct ListNode* cur = head, * slow = head, * fast = head;
	while (fast && fast->next)
	{
		slow = slow->next;
		fast = fast->next->next;
	}
	struct ListNode* mid = slow;

	//将中间节点之后的顺序反转
	struct ListNode* newhead = slow;
	cur = newhead;
	struct ListNode* prev = NULL;
	while (cur)
	{
		struct ListNode* next = cur->next;
		cur->next = prev;
		prev = cur;
		cur = next;
	}
	newhead = prev;

	//遍历两组链表,检查是否每位相等
	struct ListNode* cur2 = newhead;
	struct ListNode* cur1 = head;
	while (cur1 && cur2)
	{
		if (cur1->val != cur2->val)
		{
			return false;
		}
		cur1 = cur1->next;
		cur2 = cur2->next;
	}
	return true;
}

 

160 相交链表

  • 根据两链表长度求出长度差k
  • 较长的链表先走k步
  • 两表再一起走,节点地址相同时返回此节点
 int ListSize(struct ListNode * head)
 {
     struct ListNode * cur=head;
     int len=0;
     while(cur)
    {
        len++;
        cur=cur->next;
    }
    return len;
 }
struct ListNode *getIntersectionNode(struct ListNode *headA, struct ListNode *headB) {
    int len1=ListSize(headA);
    int len2=ListSize(headB);
    int k=abs(len1-len2);
    struct ListNode * longlist=headA;
    struct ListNode * shortlist=headB;
    if(len1<len2)
    {
        longlist=headB;
        shortlist=headA;
    }
    struct ListNode * cur1=longlist, *cur2=shortlist;
    while(k--)
    {
        cur1=cur1->next;
    }
    while(cur1 && cur2)
    {
        if(cur1==cur2)
        {
            return cur1;
        }
        cur1=cur1->next;
        cur2=cur2->next;
    }
    return NULL;
}

 

141 环形链表

快慢指针法,相遇则为环形链表

//环形链表,快慢指针法
bool hasCycle(struct ListNode* head) {
	struct ListNode* slow = head;
	struct ListNode* fast = head;
	while (fast && fast->next)
	{

		fast = fast->next->next;
		slow = slow->next;
		if (slow == fast)
		{
			return true;
		}
	}
	return false;
}

142 环形链表 II

  • 先找到入环点
  • 相遇点到入环点的距离等于链头到入环点的距离
  • 从链头和相遇点出发,相遇点即为入环点

在这里插入图片描述

//环形链表 II
//找到入环点,再判断环形链表代码块内续写
struct ListNode* detectCycle(struct ListNode* head) {
	struct ListNode* slow = head, * fast = head, * meet = NULL;
	while (fast && fast->next)
	{
		//找到快慢指针相遇点
		fast = fast->next->next;
		slow = slow->next;
		//相遇点到入环点的距离等于链头到入环点的距离
		if (slow == fast)
		{
			meet = slow;
			while (meet != head)
			{
				meet = meet->next;
				head = head->next;
			}
			return meet;
		}
	}
	return NULL;
}

138 复制带随机指针的链表

  • 在原链表每个节点后复制一个节点
  • 根据原节点设置复制节点的random
    • 注意不可复制节点的同时处理random,因为random指向位置还未完成复制
  • 将处理好的复制节点链接到newhead
    在这里插入图片描述
//复制带随机指针的链表
struct Node* copyRandomList(struct Node* head) {
	struct Node* cur = head;
	//在原链表每个节点后复制一个节点
	while (cur)
	{
		struct Node* copy = (struct Node*)malloc(sizeof(struct Node));
		copy->val = cur->val;
		copy->next = cur->next;
		cur->next = copy;
		cur = copy->next;
	}
	cur = head;
	struct Node* next = NULL;
	//根据原节点设置复制节点的random
	while (cur)
	{
		struct Node* copy = cur->next;
		next = copy->next;
		if (cur->random == NULL)
		{
			copy->random = NULL;
		}
		else
		{
			copy->random = cur->random->next;
		}
		cur = next;
	}
	//将处理好的复制节点链接到newhead
	cur = head;
	struct Node* newtail = NULL, * newhead = NULL;
	while (cur)
	{
		struct Node* copy = cur->next;
		next = copy->next;
		if (newtail == NULL)
		{
			newhead = newtail = copy;
		}
		else
		{
			newtail->next = copy;
			newtail = copy;
		}
		cur->next = next;
		cur = next;
	}
	return newhead;
}

http://www.kler.cn/a/3466.html

相关文章:

  • 迅为RK3568开发板篇OpenHarmony实操HDF驱动控制LED-添加内核编译
  • 2024年智慧消防一体化安全管控年度回顾与2025年预测
  • 【数据结构】二分查找
  • unity插件Excel转换Proto插件-ExcelToProtobufferTool
  • Spark SQL中的from_json函数详解
  • WPF1-从最简单的xaml开始
  • 中国石油大学(北京)第三届“骏码杯”程序设计竞赛(同步赛)
  • Day927.如何进行组件化分析和设计? -系统重构实战
  • Kafka介绍
  • 提升网站性能:Nginx五种高效负载均衡策略
  • Maven依赖管理
  • css绘制一个Pinia小菠萝
  • Matter名词解释
  • 初识HTTP协议
  • 大数据的常用算法(分类、回归分析、聚类、关联规则、神经网络方法、web数据挖掘)
  • 数组(完全二叉树)向下建堆法与堆排序O(N*logN)
  • redis 集群
  • [数据结构] 用两个栈实现队列详解
  • Prometheus cadvisor容器监控和node-exporter节点监控
  • STM-32:按键控制LED灯 程序详解
  • Linux的基础知识
  • 【SSM】Spring + SpringMVC +MyBatis 框架整合
  • 【C#进阶】C# 集合类
  • C语言数据结构初阶(8)----栈与队列OJ题
  • 主线程与子线程之间相互通信(HandlerThread)
  • Gateway服务网关