链表OJ(LeetCode)

这篇具有很好参考价值的文章主要介绍了链表OJ(LeetCode)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

1.移除链表元素

链表OJ(LeetCode),C家家精品好题,链表,leetcode,linux
法一:遍历删除

struct ListNode
{
	int val;
	struct ListNode* next;
};
struct ListNode* rmele(struct ListNode* head, int val)
{
	struct ListNode* prv = NULL;
	struct ListNode* cp = head;
	while (cp)
	{
		if (cp->val == val)
		{
			if (cp == head) //头删
			{
				//head自动指向cp的下一结点
				head = cp->next;
				//删除目标结点
				free(cp);
				//更新cp
				cp = head;

			}
			else
			{
				//prv连接cp的next结点
				prv->next = cp->next;
				//删除目标值
				free(cp);
				//更新cp
				cp = prv->next;
			}
			
		}
		else //不是继续遍历
		{
			prv = cp;
			cp = cp->next;
		}
	}
	return head;
}

法二:循环尾插

struct ListNode
{
	int val;
	struct ListNode* next;
};
struct ListNode* rmele(struct ListNode* head, int n)
{
	struct ListNode* tail = NULL;
	struct ListNode* cp = head;
	head = NULL; 
	//不置空 若遇到全是目标值的链表 
	//删除后--head应指向NULL--不置空head指向原头结点
	while (cp)
	{
		if (cp->val == n) //是目标值删除
		{
			//obj指向要被删除的目标值
			struct ListNode* obj = cp;
			//cp后移
			cp = cp->next;
			//删除目标值
			free(obj);	
		}
		else              //非目标值尾插
		{
			if (tail == NULL) //尾插首值
			{
				head = cp; //更新head 指向新的头结点
				tail = cp; //更新tail 指向新的尾结点
			}
			else              //尾插非首值
			{
				//tail连接非目标值
				tail->next = cp;
				//更新tail 
				tail = cp; //更新tail 指向新的尾结点
			}
			//cp后移
			cp = cp->next;
		}
	}
	//遍历结束 尾结点的指针域须被置空
	//若遇到空链表 tail初值为空 无法访问next
	if (tail != NULL)
		tail->next = NULL;

	return head;
}

法三:带哨兵位的头结点

struct ListNode
{
	int val;
	struct ListNode* next;
};
struct ListNode* rmele(struct ListNode* head, int n)
{
	struct ListNode* tail = NULL;
	struct ListNode* cp = head;
	head = tail = (struct ListNode*)malloc(sizeof(struct ListNode));
	tail->next = NULL;
	while (cp)
	{
		if (cp->val == n) //是目标值删除
		{
			//obj指向要被删除的目标值
			struct ListNode* obj = cp;
			//cp后移
			cp = cp->next;
			//删除目标值
			free(obj);
		}
		else              //非目标值尾插
		{
			//tail连接非目标值
			tail->next = cp;
			//更新tail 
			tail = cp; //更新tail 指向新的尾结点
			//cp后移
			cp = cp->next;
		}
		//尾插后将指针域置空
		tail->next = NULL;
		//sentinel:哨兵
		struct ListNode* sp = head;
		//更新head 指向非哨兵位的头结点
		head = head->next;
		//销毁哨兵位
		free(sp);

		return head;
	}
}

2.反转链表

链表OJ(LeetCode),C家家精品好题,链表,leetcode,linux
法一:循环头插
链表OJ(LeetCode),C家家精品好题,链表,leetcode,linux

struct ListNode
{
	int val;
	struct ListNode* next;
};
//nh:newhead 
//cp:pointer to current 
//pnext:pointer to next
struct ListNode* reverseList(struct ListNode* head) 
{
	struct ListNode* nh = NULL;
	struct ListNode* cp = head;
	while (cp)
	{
		//pn永远指向cp的下一个结点
		struct ListNode* pnext = cp->next;
		//nh指向上一个结点-->初始为空
		cp->next = nh; //cp的指针域存储上一个结点空间地址 ==》cp连接nh(上一个结点)
		//nh指向更新 指向现结点空间地址
		nh = cp;
		//cp后移
		cp = pnext;
	}
	return nh;
}

法二:改变指针指向
链表OJ(LeetCode),C家家精品好题,链表,leetcode,linux

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

struct ListNode* reverseList(struct ListNode* head)
{
	if (head == NULL)
		return NULL;
	struct ListNode* prv, * cp, * pn;
	prv = NULL;
	cp = head;
	pn = cp->next;
	while (cp)
	{
		//cp连接前结点
		cp->next = prv;
		//前结点指针后移
		prv = cp;
		//现结点指针后移
		cp = pn;
		//原pn非空
		if (pn != NULL)
		{
			pn = pn->next;
		}
	}
	return prv;
}

3.链表的中间结点

链表OJ(LeetCode),C家家精品好题,链表,leetcode,linux
链表OJ(LeetCode),C家家精品好题,链表,leetcode,linux

struct ListNode
{
	int val;
	struct ListNode* next;
};
struct ListNode* middleNode(struct ListNode* head)
{
	struct ListNode* s,* f;
	s = f = head;
	while (f && f->next)
	{
		s = s -> next;
		f = f -> next -> next;
	}
	return s;
}

4.倒数第k个结点

链表OJ(LeetCode),C家家精品好题,链表,leetcode,linux
链表OJ(LeetCode),C家家精品好题,链表,leetcode,linux

struct ListNode
{
	int val;
	struct ListNode* next;
};
struct ListNode* FindKthToTail(struct ListNode* pListHead, int k)
{
	struct ListNode* s, * f;
	s = f = pListHead;
	//f先前进k步
	while (k--)
	{	
		if (f != NULL)     //防止输入的值k > 链表长度
			f = f->next;   //即f还未走完k步 链表已结束
		else
			return NULL;
	}
	while (f)
	{
		s = s->next;
		f = f->next;
	}
	return s;
}

5.合并两个有序链表

链表OJ(LeetCode),C家家精品好题,链表,leetcode,linux
法一:归并插入

struct ListNode
{
	int val;
	struct ListNode* next;
};
struct ListNode* mergeTwoLists(struct ListNode* list1, struct ListNode* list2) 
{
	if (list1 == NULL)
		return list2;
	if (list2 == NULL)
		return list1;

	struct ListNode* head, * tail;
	head = tail = NULL;

	while (list1 && list2)
	{
		if (list1->val < list2->val)
		{
			if (tail == NULL)
			{
				//头插--直接指向obj
				head = tail = list1;
			}
			else
			{
				tail->next = list1;
				//后移
				tail = tail->next;
			}
			//后移
			list1 = list1->next;
		}
		else
		{
			if (tail == NULL)
			{
				head = tail = list2;
			}
			else
			{
				tail->next = list2;
				tail = tail->next;
			}
			//后移
			list2 = list2->next;
		}
	}

	if (list1)
		tail->next = list1;
	if (list2)
		tail->next = list2;
	//新链表头结点
	return head;
}

法二:带哨兵位的头结点

struct ListNode
{
	int val;
	struct ListNode* next;
};
struct ListNode* mergeTwoLists(struct ListNode* list1, struct ListNode* list2) 
{
	struct ListNode* head, * tail;

	//哨兵位
	head = tail = (struct ListNode*)malloc(sizeof(struct ListNode));
	tail->next = NULL;

	while (list1 && list2)
	{
		if (list1->val < list2->val)
		{
			tail->next = list1;
			tail = tail->next;
			list1 = list1->next;
		}
		else
		{
			tail->next = list2;
			tail = tail->next;
			list2 = list2->next;
		}
	}

	//有剩余结点--连接
	if (list1)
		tail->next = list1;
	if (list2)
		tail->next = list2;

	struct ListNode* realhead = head->next;
	free(head);
	return realhead;
}

6.链表分割

链表OJ(LeetCode),C家家精品好题,链表,leetcode,linux
链表OJ(LeetCode),C家家精品好题,链表,leetcode,linux

struct ListNode
{
	int val;
	struct ListNode* next;
	ListNode(int x)
		:val(x)
		,next(nullptr)
	{

	}
};
class Partition
{
public:
	ListNode* partition(ListNode* pHead, int x)
	{
		//创建哨兵位
		struct ListNode* big_head, * big_tail, * less_head, * less_tail;

		big_head  = big_tail  = (struct ListNode*)malloc(sizeof(struct ListNode));
		less_head = less_tail = (struct ListNode*)malloc(sizeof(struct ListNode));

		big_tail->next  = nullptr;
		less_tail->next = nullptr;

		//遍历
		struct ListNode* cp = pHead;
		while (cp)
		{
			if (cp->val < x)
			{
				less_tail->next = cp;
				less_tail = less_tail->next;
			}
			else
			{
				big_tail->next = cp;
				big_tail = big_tail->next;
			}

			cp = cp->next;
		}
		//连接两段链表
		less_tail->next = big_head->next;
		//注意尾结点指针域置空
		big_tail->next = nullptr;

		struct ListNode* newhead = less_head->next;
		free(big_head);
		free(less_head);
		return newhead;
	}
};

7.链表的回文结构

链表OJ(LeetCode),C家家精品好题,链表,leetcode,linux
链表OJ(LeetCode),C家家精品好题,链表,leetcode,linux

struct ListNode
{
	int val;
	struct ListNode* next;
};
//寻找中间结点
struct ListNode* middleNode(struct ListNode* head)
{
	struct ListNode* s, * f;
	s = f = head;
	while (f && f->next)
	{
		s = s->next;
		f = f->next->next;
	}
	return s;
}
//后半段逆置
struct ListNode* reverseList(struct ListNode* head)
{
	struct ListNode* nh = NULL;
	struct ListNode* cp = head;
	while (cp)
	{
		//pn永远指向cp的下一个结点
		struct ListNode* pnext = cp->next;

		//nh指向上一个结点-->初始为空
		cp->next = nh; //cp的指针域存储上一个结点空间地址 ==》cp连接nh(上一个结点)
		
		//nh指向更新 指向现结点空间地址
		nh = cp;
		
		//cp后移
		cp = pnext;
	}
	return nh;
}
//判断回文
bool isPalindrome(struct ListNode* head) 
{
	struct ListNode* mid = middleNode(head);
	struct ListNode* rhead = reverseList(mid);
	while (head && rhead)
	{
		if (head->val != rhead->val)
		{
			return false;
		}
		else
		{
			head = head->next;
			rhead = rhead->next;
		}
	}
	return true;
}

8.相交链表

链表OJ(LeetCode),C家家精品好题,链表,leetcode,linux
链表OJ(LeetCode),C家家精品好题,链表,leetcode,linux

struct ListNode
{
	int val;
	struct ListNode* next;
};
struct ListNode* getIntersectionNode(struct ListNode* headA, struct ListNode* headB)
{
	if (headA == NULL || headB == NULL)
		return NULL;

	struct ListNode* cpA = headA, * cpB = headB;
	//求链表长度
	int lenA = 1, lenB = 1;
	while (cpA->next)
	{
		cpA = cpA->next;
		lenA++;
	}
	while (cpB->next)
	{
		cpB = cpB->next;
		lenB++;
	}
	//若链表相交 尾结点空间地址定相同
	if (cpA != cpB)
		return NULL;

	//定位长短链表
	struct ListNode* S_list = headA, * L_list = headB;
	if (lenA > lenB)
	{
		S_list = headB;
		L_list = headA;
	}
	//求长度差
	int gap = abs(lenA - lenB);
	//长链表前进gap步
	while (gap--)
	{
		L_list = L_list->next;
	}
	while (S_list != L_list)
	{
		S_list = S_list->next;
		L_list = L_list->next;
	}
	return S_list;
}

9.环形链表

链表OJ(LeetCode),C家家精品好题,链表,leetcode,linux
链表OJ(LeetCode),C家家精品好题,链表,leetcode,linux
链表OJ(LeetCode),C家家精品好题,链表,leetcode,linux

struct ListNode
{
	int val;
	struct ListNode* next;
};
bool has_cycle(struct ListNode* head) 
{
	struct ListNode* f = head, * s = head;
	while (f && f->next)
	{
		s = s->next;
		f = f -> next->next;
		if (s == f)
			return true;
	}
	return false;
}

链表OJ(LeetCode),C家家精品好题,链表,leetcode,linux
链表OJ(LeetCode),C家家精品好题,链表,leetcode,linux
链表OJ(LeetCode),C家家精品好题,链表,leetcode,linux
链表OJ(LeetCode),C家家精品好题,链表,leetcode,linux
n是偶数能追上
n是奇数 C-1是偶数能追上
n是奇数 C-1是奇数追不上

10.环形链表Ⅱ

链表OJ(LeetCode),C家家精品好题,链表,leetcode,linux

1.常规思路

slow进环后在一圈内一定会被fast追上:slow进环后 fast一定在slow前面 二者之间最大距离为一圈 slow走1圈 fast会走2圈 超出的这一圈绝对会碰到slow ==》 fast最多走2圈就会追上slow【fast比slow每次多走一步的前提下】

链表OJ(LeetCode),C家家精品好题,链表,leetcode,linux

struct ListNode
{
	int val;
	struct ListNode* next;
};
struct ListNode* detectCycle(struct ListNode* head) 
{
	struct ListNode* s, * f;
	s = f = head;
	//若f 、 f->next二者有一为空 == 定不存在环
	while (f && f->next)
	{
		//s走1步 f走2步
		s = s->next;
		f = f -> next->next;
		//s == f :定有环
		if (s == f)
		{
			struct ListNode* meet = s;
			while (meet != head)
			{
				meet = meet->next;
				head = head -> next;
			}
			//相等即二者相遇 相遇点即为交点
			return meet;
		}
	}
	return NULL;
}

2.新型思路【无码】

链表OJ(LeetCode),C家家精品好题,链表,leetcode,linux

问题变成了:newhead的链表和head的链表的寻找交点的问题

11.复制带随机指针的链表

链表OJ(LeetCode),C家家精品好题,链表,leetcode,linux
链表OJ(LeetCode),C家家精品好题,链表,leetcode,linux
链表OJ(LeetCode),C家家精品好题,链表,leetcode,linux
链表OJ(LeetCode),C家家精品好题,链表,leetcode,linux文章来源地址https://www.toymoban.com/news/detail-571193.html

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>
struct Node
{
	int val;
	struct Node* next;
	struct Node* random;
};
struct Node* copyRandomList(struct Node* head)
{
	// 1、拷贝连接
	struct Node* cp = head;
	while (cp)
	{
		struct Node* tmp = (struct Node*)malloc(sizeof(struct Node));
		//拷贝val
		tmp->val = cp->val;
		//拷贝next 即:原结点next指向谁 拷贝结点的next就指向谁
		tmp->next = cp->next;
		//cp和tmp连接
		cp->next = tmp;
		//cp后移
		cp = tmp->next;
	}
	//2、匹配random
	cp = head;
	while (cp)
	{
		struct Node* tmp = cp->next;
		if (cp->random == NULL)
			tmp->random = NULL;
		else
			tmp->random = cp->random->next;
		cp = tmp->next;
	}
	//3、旧连旧--新连新
	cp = head;
	struct Node* Head = NULL, * Tail = NULL;
	while (cp)
	{
		struct Node* tmp = cp->next;
		struct Node* next = tmp->next;
		if (Tail == NULL)
		{
			Head = Tail = tmp;
		}
		else
		{
			Tail->next = tmp;
			Tail = Tail->next;
		}
		cp->next = next;
		cp = next;
	}
	return Head;
}

到了这里,关于链表OJ(LeetCode)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 数据结构:带环单链表基础OJ练习笔记(leetcode142. 环形链表 II)(leetcode三题大串烧)

    目录 一.前言  二.leetcode160. 相交链表  1.问题描述 2.问题分析与求解 三.leetcode141. 环形链表 1.问题描述 2.代码思路  3.证明分析  下一题会用到的重要小结论: 四.leetcode142. 环形链表 II 1.问题描述 2.问题分析与求解 Judgecycle接口: 方法一: 方法二:  单链表和带环单链表

    2023年04月08日
    浏览(40)
  • 单链表OJ题:LeetCode--142.环形链表Ⅱ(判断第一次入环的节点)

    朋友们、伙计们,我们又见面了,本期来给大家解读一下LeetCode中第142道单链表OJ题,如果看完之后对你有一定的启发,那么请留下你的三连,祝大家心想事成!   数据结构与算法专栏 : 数据结构与算法 个  人  主  页  : stackY、 C 语 言 专 栏 : C语言:从入门到精通 Le

    2024年02月08日
    浏览(39)
  • Leetcode 1367. Linked List in Binary Tree (二叉树好题)

    Linked List in Binary Tree Medium Given a binary tree root and a linked list with head as the first node. Return True if all the elements in the linked list starting from the head correspond to some downward path connected in the binary tree otherwise return False. In this context downward path means a path that starts at some node and goes downwards. Exampl

    2024年01月25日
    浏览(49)
  • Leetcode 508. Most Frequent Subtree Sum (二叉树后序遍历好题)

    Most Frequent Subtree Sum Solved Medium Topics Companies Given the root of a binary tree, return the most frequent subtree sum. If there is a tie, return all the values with the highest frequency in any order. The subtree sum of a node is defined as the sum of all the node values formed by the subtree rooted at that node (including the node itself). Example

    2024年02月22日
    浏览(39)
  • 经典LeetCode在线OJ习题

    目录 习题一:移除元素 (一)、题目  (二)、示例 (三)、解题思路 思路一: 思路一源代码: 源代码解释: 思路二:(最标准最适用) 思路二源代码: 源代码解释:  习题二:归并两个有序数组 (一)、题目  (二)、示例 (三)、解题思路  思路一:暴力求解但

    2024年02月10日
    浏览(40)
  • Leetcode-二叉树oj题

    144. 二叉树的前序遍历 https://leetcode.cn/problems/binary-tree-preorder-traversal/ 这个题目在遍历的基础上还要求返回数组,数组里面按前序存放二叉树节点的值。 既然要返回数组,就必然要malloc一块空间,那么我们需要算出这个二叉树的节点个数,所以就创建一个函数TreeSize求出节点

    2024年02月05日
    浏览(38)
  • 队列实现及leetcode相关OJ题

    上一篇写的是栈这一篇分享队列实现及其与队列相关OJ题 1、队列概念 队列同栈一样也是一种特殊的数据结构,遵循 先进先出 的原则,例如:想象在独木桥上走着的人,先上去的人定是先从独木桥上下来,为啥说是特殊呢? 因为它只允许在对尾插入数据 (简称 入队 , 然后在

    2024年02月03日
    浏览(39)
  • 顺序表链表OJ题(1)——【LeetCode】

    W...Y的主页 😊 代码仓库分享 💕  前言: 今天我们来回顾一下顺序表与链表,针对这一块我们也有许多OJ题目供大家参考。当我们学习完顺序表链表后避免不了一些习题的练习,这样才能巩固我们学习的内容。 话不多说,我们开始进入OJ习题训练!!! 【leetcode 27.移除元素

    2024年02月10日
    浏览(41)
  • 【LeetCode】【C++】string OJ必刷题

    👀 樊梓慕: 个人主页  🎥 个人专栏: 《C语言》《数据结构》《蓝桥杯试题》《LeetCode刷题笔记》《实训项目》《C++》《Linux》 🌝 每一个不曾起舞的日子,都是对生命的辜负 目录 前言 【LeetCode】415.字符串相加 【LeetCode】43.字符串相乘   【LeetCode】125.验证回文字符串 【

    2024年02月05日
    浏览(41)
  • 二叉树OJ题:LeetCode--100.相同的树

    朋友们、伙计们,我们又见面了,本期来给大家解读一下LeetCode中第100道二叉树OJ题,如果看完之后对你有一定的启发,那么请留下你的三连,祝大家心想事成! 数据结构与算法专栏: 数据结构与算法 个  人  主  页  : stackY、 C 语 言 专 栏 : C语言:从入门到精通 LeetCo

    2024年02月11日
    浏览(37)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包