链表OJ题

文章目录

1. 链表的回文结构

因为单链表不能从后往前找节点,所以我们先找到中间节点,然后逆置,最后进行比较。

c 复制代码
#include <stdio.h>
#include <stdbool.h>

typedef struct ListNode
{
	int val;
	struct ListNode* next;
}ListNode;

struct ListNode* middleNode(struct ListNode* head)
{
	ListNode* slow, * fast;
	slow = fast = head;

	while (fast && fast->next)
	{
		slow = slow->next;
		fast = fast->next->next;
	}

	return slow;
}

struct ListNode* reverseList(struct ListNode* head)
{
	if (NULL == head)
	{
		return head;
	}

	ListNode* n1, * n2, * n3;
	n1 = NULL, n2 = head, n3 = head->next;

	while (n2)
	{
		n2->next = n1;
		n1 = n2;
		n2 = n3;

		if (n3)
		{
			n3 = n3->next;
		}
	}

	return n1;
}

bool chkPalindrome(ListNode* A)
{
	ListNode* mid = middleNode(A);
	ListNode* rmid = reverseList(mid);

	while (A && rmid)
	{
		if (A->val != rmid->val)
		{
			return false;
		}

		A = A->next;
		rmid = rmid->next;
	}

	return true;
}

2. 相交链表

c 复制代码
#include <stdio.h>
#include <stdlib.h>

struct ListNode
{
	int val;
	struct ListNode* next;
};

struct ListNode* getIntersectionNode(struct ListNode* headA, struct ListNode* headB)
{
	struct ListNode* curA = headA;
	struct ListNode* curB = headB;

	int lenA = 0;

	while (curA->next)
	{
		++lenA;
		curA = curA->next;
	}
	
	int lenB = 0;

	while (curB->next)
	{
		++lenB;
		curB = curB->next;
	}

	//不相交
	if (curA != curB)
	{
		return NULL;
	}

	int gap = abs(lenA - lenB);
	//因为我们不知道A长还是B长,所以我们要用假设法,先假设A长,如果不对,再调换一下就行
	struct ListNode* longList = headA;
	struct ListNode* shortList = headB;

	if (lenB > lenA)
	{
		longList = headB;
		shortList = headA;
	}

	//让长的先走gap步
	while (gap--)
	{
		longList = longList->next;
	}

	//再同时走,找交点
	while (longList != shortList)
	{
		longList = longList->next;
		shortList = shortList->next;
	}

	return longList;
}

3. 链表中倒数第k个结点

思路2:

c 复制代码
#include <stdio.h>

struct ListNode
{
	int val;
	struct ListNoe* next;
};

struct ListNode* FindKthToTail(struct ListNode* pListHead, int k)
{
	struct ListNode* slow = pListHead, * fast = pListHead;

	//fast先走k步
	while (k--)
	{
		//k还没有减到0,链表已经空了,说明k大于链表的长度
		if (NULL == fast)
		{
			return NULL;
		}

		fast = fast->next;
	}

	//slow和fast同时走,fast走到空,slow就是倒数第k个
	while (fast)
	{
		slow = slow->next;
		fast = fast->next;
	}

	return slow;
}

4. 环形链表


c 复制代码
#include <stdbool.h>

struct ListNode
{
	int val;
	struct ListNode* next;
};
 

bool hasCycle(struct ListNode* head)
{
	struct ListNode* slow = head, * fast = head;

	while (fast && fast->next)
	{
		slow = slow->next;
		fast = fast->next->next;

		if (slow == fast)
		{
			return true;
		}
	}

	return false;
}

5. 环形链表 II

找入环点:

法一:

c 复制代码
#include <stdio.h>

struct ListNode
{
	int val;
	struct ListNode* next;
};

struct ListNode* detectCycle(struct ListNode* head)
{
	struct ListNode* slow = head, * fast = head;

	while (fast && fast->next)
	{
		slow = slow->next;
		fast = fast->next->next;

		if (slow == fast)
		{
			struct ListNode* meet = slow;

			while (meet != head)
			{
				meet = meet->next;
				head = head->next;
			}

			return meet;
		}
	}

	return NULL;
}

法二:

c 复制代码
#include <stdio.h>
#include <stdlib.h>

struct ListNode
{
	int val;
	struct ListNode* next;
};

struct ListNode* getIntersectionNode(struct ListNode* headA, struct ListNode* headB)
{
	struct ListNode* curA = headA;
	struct ListNode* curB = headB;

	int lenA = 0;

	while (curA->next)
	{
		++lenA;
		curA = curA->next;
	}

	int lenB = 0;

	while (curB->next)
	{
		++lenB;
		curB = curB->next;
	}

	//不相交
	if (curA != curB)
	{
		return NULL;
	}

	int gap = abs(lenA - lenB);
	struct ListNode* longList = headA;
	struct ListNode* shortList = headB;

	if (lenB > lenA)
	{
		longList = headB;
		shortList = headA;
	}

	//让长的先走gap步
	while (gap--)
	{
		longList = longList->next;
	}

	//再同时走,找交点
	while (longList != shortList)
	{
		longList = longList->next;
		shortList = shortList->next;
	}

	return longList;
}

struct ListNode* detectCycle(struct ListNode* head)
{
	struct ListNode* slow = head, * fast = head;

	while (fast && fast->next)
	{
		slow = slow->next;
		fast = fast->next->next;

		if (slow == fast)
		{
			struct ListNode* meet = slow;
			struct ListNode* headx = meet->next;
			meet->next = NULL;

			return getIntersectionNode(head, headx);
		}
	}

	return NULL;
}

6. 随机链表的复制

写代码的时候建议一边画细图,一边写:

c 复制代码
#include <stdio.h>
#include <stdlib.h>

struct Node
{
    int val;
    struct Node *next;
    struct Node *random;
};

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 = cur->next->next;
    }

    //控制拷贝节点的random
    cur = head;

    while (cur)
    {
        struct Node* copy = cur->next;
        
        if (NULL == cur->random)
        {
            copy->random = NULL;
        }
        else
        {
            copy->random = cur->random->next;
        }

        //迭代
        cur = cur->next->next;
    }

    //把copy节点解下来,链接成新链表
    struct Node* copyhead = NULL, * tail = NULL;
    cur = head;

    while (cur)
    {
        struct Node* copy = cur->next;
        struct Node* next = copy->next;

        //尾插
        if (NULL == tail)
        {
            copyhead = tail = copy;
        }
        else
        {
            tail->next = copy;
            tail = tail->next;
        }

        cur->next = next;
        cur = next;
    }

    return copyhead;
}
相关推荐
luckys.one23 分钟前
第9篇:Freqtrade量化交易之config.json 基础入门与初始化
javascript·数据库·python·mysql·算法·json·区块链
TomCode先生1 小时前
c#动态树形表达式详解
开发语言·c#
高-老师1 小时前
基于R语言的物种气候生态位动态量化与分布特征模拟
开发语言·r语言·物种气候
大翻哥哥2 小时前
Python 2025:量化金融与智能交易的新纪元
开发语言·python·金融
~|Bernard|2 小时前
在 PyCharm 里怎么“点鼠标”完成指令同样的运行操作
算法·conda
战术摸鱼大师2 小时前
电机控制(四)-级联PID控制器与参数整定(MATLAB&Simulink)
算法·matlab·运动控制·电机控制
Christo32 小时前
TFS-2018《On the convergence of the sparse possibilistic c-means algorithm》
人工智能·算法·机器学习·数据挖掘
weixin_437830942 小时前
使用冰狐智能辅助实现图形列表自动点击:OCR与HID技术详解
开发语言·javascript·ocr
鹿鹿学长3 小时前
2025年全国大学生数学建模竞赛(C题) 建模解析|婴儿染色体数学建模|小鹿学长带队指引全代码文章与思路
c语言·开发语言·数学建模
好家伙VCC3 小时前
数学建模模型 全网最全 数学建模常见算法汇总 含代码分析讲解
大数据·嵌入式硬件·算法·数学建模