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

剑指 Offer(第2版)面试题 18:删除链表的节点

剑指 Offer(第2版)面试题 18:删除链表的节点

  • 剑指 Offer(第2版)面试题 18:删除链表的节点
    • 题目一:在 O(1) 时间删除链表结点
    • 题目二:删除链表中重复的节点

剑指 Offer(第2版)面试题 18:删除链表的节点

题目一:在 O(1) 时间删除链表结点

题目来源:

  1. 28. 在 O(1) 时间删除链表结点
  2. LeetCode 237. 删除链表中的节点

算法:

  1. 得到要删除节点的下一个节点 pNext;
  2. 将 pNext->val 赋给 node->val;
  3. 让 node 指向 pNext->next;
  4. delete pNext。

代码:

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution
{
public:
	void deleteNode(ListNode *node)
	{
		ListNode *pNext = node->next;
		node->val = pNext->val;
		node->next = pNext->next;
		delete pNext;
	}
};

复杂度分析:

时间复杂度:O(1)。

空间复杂度:O(1)。

题目二:删除链表中重复的节点

题目来源:29. 删除链表中重复的节点

代码 1:书上的版本,很长,但是没有内存泄漏

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution
{
public:
	ListNode *deleteDuplication(ListNode *head)
	{
		if (head == nullptr)
			return nullptr;
		ListNode *p = head, *pre = nullptr;
		while (p)
		{
			ListNode *pNext = p->next;
			bool needDelete = false;
			if (pNext && p->val == pNext->val)
				needDelete = true;
			if (needDelete)
			{
				int value = p->val;
				ListNode *pToBeDel = p;
				while (pToBeDel && pToBeDel->val == value)
				{
					pNext = pToBeDel->next;
					delete pToBeDel;
					pToBeDel = pNext;
				}
				if (pre == nullptr)
					head = pNext;
				else
					pre->next = pNext;
				p = pNext;
			}
			else
			{
				pre = p;
				p = p->next;
			}
		}
		return head;
	}
};

代码 2:简化版,没有 delete 重复节点,存在内存泄漏

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution
{
public:
	ListNode *deleteDuplication(ListNode *head)
	{
		auto dummy = new ListNode(-1); // 建立虚拟头结点
		dummy->next = head;			   // 虚拟头结点指向头结点
		auto p = dummy;

		while (p->next) // p的下一个节点不为空
		{
			auto q = p->next;
			// q的下一个节点不为空,且q的下一个节点的值等于p的下一个节点的值
			while (q->next && q->next->val == p->next->val)
				q = q->next;
			// 如果q==p的下一个节点 p=q
			if (q == p->next)
				p = q;
			// 如果不是说明存在重复元素,则p指向q的下一个节点即非重复节点
			else
				p->next = q->next;
		}
		
		return dummy->next;
	}
};

复杂度分析:

时间复杂度:O(n),其中 n 是链表的长度。

空间复杂度:O(1)。


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

相关文章:

  • LeetCode --- 143周赛
  • STM32寄存器结构体详解
  • vue-router的push和replace的区别
  • 谷歌AI进军教育,这将改变未来?
  • 11.08-10.14谷粒商城
  • 电子工牌独立双通道定向拾音方案(有视频演示)
  • Canal笔记:安装与整合Springboot模式Mysql同步Redis
  • MYSQL数据库中运行SQL文件报错
  • history路由解决刷新出现404的问题
  • go-fastfds部署心得
  • 四.多表查询
  • bootstrap中的图标元素可以免费使用
  • 怎么验证公钥和私钥是一对
  • VMware虚拟机系统CentOS镜像的下载
  • Hadoop学习笔记(HDP)-Part.13 安装Ranger
  • 【深度学习】回归模型相关重要知识点总结
  • HarmonyOS学习--初次下载安装和配置环境
  • SQL Server 2008 使用concat报错
  • Matlab 镜像变换(2D)
  • 有基础转Go语言学习笔记(2. 基本数据结构篇)
  • 【答疑解惑】什么时候需要将数据集划分为训练集和测试集,什么时候需要划分为训练集、验证集和测试集?
  • (未传知网)大数据环境下的隐私安全的图像特征提取及应用
  • IT外包模式兼具优势与挑战:企业如何利用其进行降本增效?
  • ABCDE类网络的划分及保留网段
  • DS图应用--最短路径
  • Es条件查询