算法合集之《数据结构的提炼与压缩》

合集下载

数据压缩算法讲述

数据压缩算法讲述


常见压缩实现工具: RAR:结合了PPM和LZSS算法 GZIP:DEFLATE,gzipped "inflate" data is prefixed with a two-byte header, and suffixed with a four-byte checksum。 ZIP:/76676/



Difference between gzip, zip, deflate 参见:/Archive/Comp/pression/200707/msg00011.html 总结:目前压缩算法在日益更新,很难有最好的。但当前互联网领域广泛被使用,比如浏览器普遍支持的: gzip,deflate,compress等 ,或者一些大公司内部使用的如google的Snappy等。 因为被使用广泛且占有率高,因此可以达到兼容性好,解压方便的效果。





2.常见压缩算法

Wiki罗列了近100种算法,目的都是降低信息冗余度。
压缩算法思想 Entropy Encoding:最少bit数编码,Shannon,Huf较多的单词或词汇组合做成一个对应的字典列表,并用特殊代码来表示 这个单词或词汇。 Sliding Window:滑动窗口 LZ77,如: DEFLATE(先用LZ77,然后用Huffman编码) 非字典算法:(Non-dictionary Algorithms)使用输入中的一部分数据,来预测后续的符号将会是什么,通过 这种算法来减少输出数据的熵,PPM,BZIP
参考:/77247/
3.常见压缩算法比较

QuickLZ: is the world's fastest compression library, reaching 308 Mbyte/s per core. Snappy: is a compression/decompression library. It does not aim for maximum compression, or compatibility with any other compression library; instead, it aims for very high speeds and reasonable compression. For instance, compared to the fastest mode of zlib, Snappy is an order of magnitude faster for most inputs, but the resulting compressed files are anywhere from 20% to 100% bigger. On a single core of a Core i7 processor in 64-bit mode, Snappy compresses at about 250 MB/sec or more and decompresses at about 500 MB/sec or more. LZ4号称速度快,压缩比高。 JAVA实现:https:///jpountz/lz4-java

提高算法效率的常用技巧和数据结构

提高算法效率的常用技巧和数据结构

提高算法效率的常用技巧和数据结构提高算法效率是算法设计的一个重要目标。

在进行算法优化时,可以采用一些常见的技巧和使用适当的数据结构来提高算法的执行速度和效率。

下面将介绍一些常用的技巧和数据结构来优化算法。

一、常用技巧1.分治策略:将问题分解为若干个规模较小且相互独立的子问题,然后逐个解决子问题,最后将子问题的解合并起来得到原问题的解。

常见的分治算法有归并排序和快速排序。

2.动态规划:将一个原问题划分为若干个子问题,并按照一定的顺序进行求解。

使用动态规划可以避免重复计算,提高算法效率。

常见的动态规划算法有背包问题、最短路径问题等。

3.贪心算法:在每一步选择中都采取在当前状态下最好或最优(即最有利)的选择,从而希望导致结果是最好或最优的算法。

贪心算法一般不能保证得到全局最优解,但在某些问题上表现出较好的效果,比如最小生成树问题、背包问题等。

4.二分查找:对于有序数组,可以使用二分查找来快速定位目标元素的位置,减少查找的时间复杂度。

二分查找的时间复杂度为O(logN)。

5.哈希表:使用哈希表可以实现快速查找、插入和删除操作,其平均时间复杂度为O(1)。

哈希表的性能取决于哈希函数的设计和冲突处理策略。

6.双指针法:在某些问题中,可以使用双指针法来提高算法效率。

双指针法一般使用两个指针分别从两端开始,根据问题的特点逐步缩小问题的规模。

7.剪枝:在搜索问题中,可以使用剪枝技巧来减少搜索空间,以提高算法效率。

剪枝可以通过添加一些判断条件来减少不必要的计算或者剪去无效的搜索分支。

8.滑动窗口:滑动窗口是一种处理数组/字符串的问题的有效技巧。

通过维护一个窗口,可以在O(n)的时间复杂度内解决某些问题,例如字符串的最大/最小值子串问题等。

二、常用数据结构1.数组:数组是一种简单而高效的数据结构,可以在O(1)的时间复杂度内访问任意一个元素。

数组适用于随机访问的场景,但插入和删除元素的效率相对较低。

2.链表:链表可以在O(1)的时间复杂度内插入和删除元素,但访问元素时需要遍历链表,时间复杂度为O(n)。

《数据结构与算法 》课件

《数据结构与算法 》课件
人工智能领域中,数据结构对于机器学习、深度学习等算法的效率至关重要。例如,使用决策树、神经网络等数据结构进行分类、预测等任务。
数据结构在人工智能中的优化可以提升算法的效率和准确性,例如通过使用哈希表实现快速特征匹配,提高图像识别速度。
THANK YOU
定义与分类
添加边、删除边、查找路径等。
基本操作
图中的边可以是有方向的,也可以是无方向的。节点之间可以有多种关系,如邻接、相连等。
特性
社交网络、交通网络、路由协议等。
应用场景
05
排序与查找算法
冒泡排序:通过重复地遍历待排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来。遍历数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完成。
详细描述
链表的优势在于可以动态调整大小,插入和删除操作仅需修改指针,时间复杂度为O(1)。但链表访问特定元素需要从头部遍历,效率较低。
VS
栈和队列是特殊的线性数据结构,它们遵循特定的操作规则。栈遵循后进先出(LIFO)原则,队列遵循先进先出(FIFO)原则。
详细描述
栈用于保存按照后进先出顺序访问的数据元素,常见的操作有压栈、弹栈和查看栈顶元素。队列用于保存按照先进先出顺序访问的数据元素,常见的操作有入队、出队和查看队首元素。
03
线性数据结构
数组是线性数据结构中的基本形式,它以连续的内存空间为基础,用于存储固定长度的同类型元素。
数组具有固定的长度,可以通过索引直接访问任意元素。它适合于需要快速访问数据的场景,但插入和删除操作需要移动大量元素,效率较低。
详细描述
总结词
总结词
链表是一种线性数据结构,它通过指针链接各个节点,节点包含数据和指向下一个节点的指针。

数据结构与算法详解

数据结构与算法详解

数据结构与算法详解数据结构和算法是计算机科学中非常重要的两个概念。

数据结构是一种数据组织和存储方式,它能够提高数据的访问和处理效率。

算法是一种解决问题的具体步骤,可以优化问题的解决方式。

在计算机科学中,数据结构和算法被广泛应用于软件开发、数据处理、计算机通信等方面。

本文将深入介绍数据结构和算法的相关内容。

一、常用数据结构常见的数据结构有数组、链表、堆、栈、队列、散列表、二叉树等。

下面依次介绍这些数据结构的特点。

1. 数组数组是一种线性结构,由一组相同类型的元素组成并按照一定的顺序存储。

数组具有下标定位和随机访问等优点,适用于元素较少且随机查询比较频繁的情况。

2. 链表链表也是一种线性结构,由一系列不同类型的数据节点组成。

每个节点包含一个数据项和指向下一个节点的指针。

链表具有灵活的插入和删除操作,适用于元素较多且数据分散的情况。

3. 堆堆是一种特殊的树形结构,它满足父节点的键值总是大于或等于子节点的键值。

堆常用于优先队列、排序等场景中。

4. 栈栈是一种特殊的线性结构,它的数据存储在一个简单的表中,只有在表的一端进行插入和删除操作。

栈的操作是“后进先出”,适用于回溯、表达式求值等场景中。

5. 队列队列也是一种特殊的线性结构,它的数据存储在一个简单的表中,只能从表的一端进行插入,从另一端进行删除。

队列的操作是“先进先出”,适用于排队、广度优先搜索等场景中。

6. 散列表散列表也叫哈希表,是一种根据键值(key)而直接访问到值(value)的数据结构。

散列表通过哈希函数将键映射到表中位置,从而实现快速查找。

7. 二叉树二叉树是一种特殊的树形结构,每个节点最多有两个子节点。

二叉树包含前序遍历、中序遍历、后序遍历等方法,适用于排序、查找等场景中。

二、常用算法常见的算法包括排序、搜索、图算法等。

下面依次介绍这些算法的特点。

1. 排序算法排序算法是将一组未排序的数据按照一定的规则进行排序的算法。

常见的排序算法有冒泡排序、快速排序、插入排序、选择排序、归并排序、计数排序、桶排序、基数排序等。

数据结构与算法知识点

数据结构与算法知识点

数据结构与算法知识点数据结构与算法是计算机科学的一个核心分支。

它是计算机程序的精华,是解决复杂问题的关键,也是计算机科学中创新最为密集的领域之一。

为了使用计算机来处理越来越复杂的问题,数据结构与算法学科不断发展壮大,成果也越来越丰硕。

理解数据结构和算法的知识是程序设计人员必不可少的基本知识,并且现在已成为计算机专业人士必备知识。

数据结构是指用特定的方法组织数据的一种结构,它使用不同的数据结构使得程序可以运行的更快、更有效。

常见的数据结构有数组、链表、栈、队列、散列表、二叉树、图等,在操作数据时应当选用适合的数据结构,以便提高程序运行时间和内存占用率。

算法是以特定的操作步骤来解决特定问题的方法。

算法是数据处理的核心,它可以使程序在处理数据时有条不紊的运行,从而提高程序的性能。

常见的算法有排序算法、查找算法、图算法、动态规划等,有时也需要利用多种算法来实现复杂的任务,比如深度学习算法就需要结合数据结构和神经网络来实现。

要正确使用数据结构和算法,必须具备一定的知识和技能。

首先,了解数据结构和算法的基本概念,掌握其各自的特点,以及他们之间的联系,比如联合数据结构和复杂算法之间的关系,这样才能正确使用数据结构和算法,从而更好地解决问题。

其次,要掌握常见的数据结构和算法,要能深入理解每一种数据结构和算法的原理,熟悉每一种数据结构和算法的实现细节,比如哪些细节决定了这种数据结构和算法的时空复杂度,这样才能比较准确地选择最佳的数据结构和算法,从而更加高效地处理问题。

最后,应当熟练掌握常用的实现工具,比如语言中所提供的数据结构和算法库以及类库,使用这些工具可以更轻松地实现数据结构和算法,从而改进程序的性能。

数据结构与算法的知识为计算机相关专业人员提供了一个学习的机会,他们要不断更新自己的知识,以适应计算机技术的发展。

学习数据结构与算法不仅是一种技能,更是一种能力,只有具备基本的数据结构和算法知识,才能使计算机程序能够更快更有效地处理复杂问题。

数据结构-哈夫曼编码压缩解压缩设计报告

数据结构-哈夫曼编码压缩解压缩设计报告

;} 数个的0的充填时个8满不tib的中etyb后最到缩压// ;munkcal tni 数个的tib中etyb// ;munstib tni 量变的tib冲缓来用时件文缩压// ;etyb rahc 1-2*fael过超会不数个 点结大最的树 �树namffuh示表来用 �组数的构结edonTH// ;]1-2*fael[TH edonTH 数个的符字同不录记// ;munfael tni 置位的点结根录记// ;toor tni :etavirp 较比件文的后复恢与件文原将// ;)tuptuo* rahc ,tupni* rahc(2erapmoc diov 较比件文的后缩压与件文原将// ;)tuptuo* rahc ,tupni* rahc (erapmoc diov eslaf败失 eurt 回返功成,数函复恢// ;)tuptuo* rahc ,tupni* rahc (sserpmoced loob eslaf 败失 eurt 回返功成,数函缩压// ;)tuptuo* rahc ,tupni* rahc(sserpmoc loob 空清etyb将// ;)(etybteser diov tib个一入加中etyb的tib个8满未个一对时缩压// ;)tib tni (tibdda diov 码编namffuh的符字个每出列// ;)(edoctnirp diov 码编namffuh的符字个每算计树namffuh用利时缩压// ;)(edoc diov
树namffuh 造构值权的点结各据根时缩压// ;)(etaerc diov 值权的点结应对入写其将�数次的现出符字各计统时缩压// ;)tupni* rahc(tnuoc loob ;)(eerTnamffuh~ lautriv ;)(eerTnamffuh :cilbup { eerTnamffuh ssalc ;edonTH} } ;0 = neledoc ;1- = dlihcr ;1- = dlihcl ;1- = tnerap ;XAM = thgiew { )(edonTH 子孩右左及亲双无�大穷无为值权其令�点结化始初// 度长的码编namffuh点结该录记// ;neledoc tni 码编namffuh的点结该录记// ;edoc* tni 子孩右的点结// ;dlihcr tni 子孩左的点结/ ;dlihcl tni 置位点结亲双的点结录记// ;tnerap tni 值权的点结录记// ;th giew gnol { edonTH tcurts fedepyt 体构结点结的树namffuh//

数据结构与算法知识点总结

数据结构与算法知识点总结
数据结构与算法是计算机科学的基础,它是研究如何有效地存储和处理数据的核心概念。

它们被广泛应用于计算机科学和工程领域,甚至非计算机领域,是深入研究计算机和其他信息处理系统之前必须具备的知识。

本文旨在阐述数据结构与算法的基本概念,并归纳整理出典型的基本算法结构的知识点。

首先,数据结构是一种抽象的概念,指的是组织数据的方法和技巧。

它涉及到如何以有效的方式存储、组织、表达和处理信息。

常见的数据结构包括数组、链表、树、图和哈希表等。

其次,算法是一套用于处理特定问题的指令,是对数据结构操作的具体步骤的描述。

常见的算法类型包括搜索算法、排序算法、图算法、字符串匹配算法以及动态规划算法等。

从算法的角度来看,它们可以通过比较、转换、迭代、重复等方式解决问题,以及解决问题所需的最小步数。

这些算法可以被抽象为诸如分支和界(branchandbound)、动态规划、回溯、随机化、分治法和多项式时间算法等等几大通用结构。

此外,无论是数据结构还是算法,其基本思想就是实现准确、高效、稳定的数据处理,帮助解决复杂的问题。

数据结构的基本原则就是使用最有效的数据存储结构,算法的基本原则就是使用最有效的指令组合,以实现所求解决方案。

最后,为了更好地理解数据结构与算法,基本算法思想要求熟悉并理解几大算法结构,如搜索、排序、图、动态规划、分治等。

总之,数据结构与算法是计算机科学必不可少的知识点,要想掌握它们,就必须了解基本概念,熟悉最常见的算法结构,深入理解其中的思想。

大数据分析中的数据压缩与存储优化方法介绍

大数据分析中的数据压缩与存储优化方法介绍随着互联网和信息技术的迅猛发展,大数据分析成为了各行各业的热门话题。

大数据分析能够帮助企业从海量数据中发现商机、优化运营,提高效率,降低成本。

然而,海量数据的处理、传输和存储也带来了巨大的挑战。

本文将介绍大数据分析中的数据压缩与存储优化方法。

一、数据压缩1. 压缩算法数据压缩是通过一系列算法将原始数据转换成较小的数据集合,以便更高效地存储和传输。

目前常用的压缩算法包括LZ77、LZ78、Huffman编码、LZW、Deflate等。

这些算法在不同场景下有不同的优劣势,需要根据具体的应用场景选择合适的压缩算法。

2. 压缩工具除了压缩算法,压缩工具也是数据压缩的重要组成部分。

常见的压缩工具包括WinRAR、WinZip、7-Zip等。

这些工具不仅支持常见的文件格式压缩,还能够对数据库、日志等大数据进行压缩,将数据的存储空间降低到最小。

二、存储优化1. 数据存储格式选择合适的数据存储格式可以有效地优化大数据的存储空间。

常见的数据存储格式包括文本格式、二进制格式、压缩格式等。

不同的格式对于不同类型的数据有不同的适用性,需要根据数据的特点选择合适的存储格式。

2. 数据分区与索引在大数据存储中,合理的数据分区和索引设计可以提高数据的存取效率。

通过对数据进行分区,可以将数据按照一定的规则进行划分,提高数据的检索效率。

同时,合理的索引设计可以加快数据的查询速度,降低存储空间的消耗。

三、存储优化实践1. 压缩与解压缩在实际的大数据存储过程中,压缩和解压缩是常用的存储优化方法。

通过压缩数据,可以减少数据文件的大小,降低存储空间的占用。

而解压缩则可以在需要时快速恢复数据,保证数据的完整性和可用性。

2. 数据分区与归档对于历史数据和不常用的数据,可以进行分区存储和归档。

将历史数据和不常用的数据归档到低成本的存储介质上,如磁带、光盘等,可以释放高成本的存储空间,降低存储成本。

3. 数据压缩与加速在数据传输过程中,可以通过数据压缩和加速技术优化数据传输效率。

数据结构的提炼与压缩共36页


21、要知道对好事的称颂过于夸大,也会招来人们的反感轻蔑和嫉妒。——培根 22、业精于勤,荒于嬉;行成于思,毁于随。——韩愈
23、一切节省,归根到底都归结为时间的节省。——马克思 24、意志命运往往背道而驰,决心到最后会全部推倒。——莎士比亚
数据结构的提炼与压缩
26、机遇对于有准备的头脑有特别的 亲和力 。 27、自信是人格的核心。
28、目标的坚定是性格中最必要的力 量泉源 之一, 也是成 功的利 器之一 。没有 它,天 才也会 在矛盾 无定的 迷径中 ,徒劳 无功。- -查士 德斐尔 爵士。 29、困难就是机遇。--温斯顿.丘吉 尔。 30、我奋斗,所以我快乐。--格林斯 潘。
25、学习是劳动

字节集压缩算法 -回复

字节集压缩算法-回复什么是字节集压缩算法?字节集压缩算法是一种用于压缩数据的算法。

它通过对数据进行编码和解码的过程,将数据压缩至更小的字节数,并在需要时将其恢复为原始数据。

字节集压缩算法有多种不同的类型和实现方式,每种类型和实现方式都有其特定的优势和适用场景。

字节集压缩算法的原理是基于数据中存在的冗余性。

在大多数数据集中,存在大量相似或重复的字节序列。

例如,文本文件中的连续重复字符、图像文件中的连续颜色像素或音频文件中的连续声音样本等。

字节集压缩算法利用这种冗余性,通过使用编码技术将重复的字节序列替换为更短的编码表示,从而减少数据的存储空间。

字节集压缩算法的实现方式有很多种,其中一种常见的实现方式是基于字典的压缩算法,如LZW(Lempel-Ziv-Welch)算法。

LZW算法是一种无损数据压缩算法,广泛用于多媒体和文本数据的压缩。

该算法在压缩过程中逐步构建一个字典,记录已经出现的字节序列和对应的编码。

LZW压缩算法的压缩过程如下:1. 初始化字典,包含单个字符的条目。

2. 从输入数据中读取第一个字符作为当前字符。

3. 读取下一个字符拼接到当前字符后面,形成当前字符串。

4. 如果当前字符串在字典中存在,则将当前字符串更新为当前字符串加上下一个字符的组合,并重复步骤3,直到找到字典中不存在的字符串。

5. 将当前字符串在字典中对应的编码输出,并将当前字符串加入字典,并重复步骤3。

6. 重复步骤3到5,直到读取完所有的输入数据。

7. 输出压缩后的数据。

LZW压缩算法的解压过程是压缩过程的逆过程,通过使用相同的字典进行解码。

解压过程如下:1. 初始化字典,包含单个字符的条目。

2. 读取压缩后的数据中的第一个编码,将其解码为对应的字符串,并输出。

3. 读取下一个编码拼接到当前解码字符串后面,形成当前解码字符串。

4. 如果当前解码字符串在字典中存在,则将其更新为当前解码字符串加上下一个编码对应的字符串的组合,并重复步骤3,直到找到字典中不存在的字符串。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

摘要时间复杂度和空间复杂度是衡量一个数据结构的重要指标,往往,简单存储结构和小存储规模的数据结构会带来较低的时空复杂度。

因此,在程序设计中就需要仔细分析问题,化简存储结构,减少存储规模。

关键字化简存储结构、减少存储规模、“提炼”、“压”、“缩”、DFS序、BFS序引言作为程序设计的一部分,数据结构在现在的信息学竞赛中起着越来越大的作用。

一方面,一个好的数据结构是高效实现算法的基础,例如当算法设计动态序关系时,通过平衡排序二叉树维护序关系就要比普通线性结构高效的多;另一方面,的信息学竞赛中已经涌现出一大批“赤裸裸”的数据结构题,即题目所需要的,就是设计一个能维护特定数据关系,能高效完成特定操作的数据结构,例如NOI2007 necklace、CEOI2007 necklace都是这样的问题。

衡量一个程序的优劣,有四个主要的参考度量:时间复杂度,空间复杂度,求解精确度,编程复杂度。

时间复杂度衡量程序运行的时间,往往用一个相对输入规模的阶表示,例如冒泡排序的时间复杂度是O(n2);空间复杂度用来衡量程序所需的除读入外的额外内存空间,往往也用一个相对输入规模的阶表示,例如KMP算法的空间复杂度是O(n);求解精确度衡量程序输出解的质量,往往用与最优解之间的相对或绝对误差来描述,现在的信息学竞赛中大多数问题不允许有误差,而另一些问题将求解精确度作为评分尺度之一;编程复杂度衡量正确编程和程序调试的困难程度。

而作为对数据结构优劣的评判,(在编程复杂度不过分高的前提下)一个数据结构的时空复杂度就显得最为重要。

本文将主要讨论的通过“化繁为简”的手段优化数据结构的时空复杂度。

“化繁为简”作为一个可以广泛应用的方法,它能给程序设计带来以下两方面的优势。

一方面,直观地看,在规模小、结构简单的数据上进行操作,时空耗费比起规模大、结构复杂的数据在操作规模上“天生”就有着无与伦比的优势。

例如,图结构的存储无论是采取邻接矩阵还是邻接表,空间都是O(m+n),只要不是稀疏图,就会占用平方阶的空间,同时,所有基本操作的时间复杂度也在平方阶之上;但对于树结构而言,常用的左儿子右兄弟表示法只需要O(n)的空间复杂度,像遍历这样的基本操作,时间复杂度也是O(n)。

另一方面,一个简单的数据结构可以有更多的处理手段,也适应于更多的算法。

例如,在图结构上,一般只能进行连通性判断,流算法(事实上,流算法实现中利用到了树结构)等;而在树结构上,就可以实施树型动态规划;更进一步,对于线性结构而言,DP(Dynamic Programming,动态规划)的形式更加灵活,而且还可以使用线段树,树状数组等工具;另外,如果线性结构辅助序关系,那么各种平衡BST (Binary Search Tree,二叉搜索树)也能有用武之地。

本文将提出三种常见的化繁为简的手段(i)提炼:忽略无效信息,减少存储规模(ii)压:调整存储方式,化简存储结构(iii)缩:合并重复信息,减少存储规模1.二维结构的化简二维结构主要分两种情况,其一:两维对称,即矩阵的情况;其二:两维不对称,即一个线性表,它的每个元素都是一维结构,串数组是常见的情况。

下面我们分别就这两种情况举个例子。

问题一:ural 1568 Train car sorting问题描述:对于一个序列,定义一种操作,将a变成b,使得:,…,,…。

其中s+t=n,,,{,…,,…}={1,2,3…n}。

例如:1 2 3 4 5可转化为1 3 5 2 4。

给出一个序列(满足是1到n的一个排列),求一种方案,通过最少的操作次数是它变成升序序列。

这一题从题面看,操作的定义比较复杂,没有一个明显的切入点,很难设计出一个能有效解决它的算法。

其实只要找到题目中涉及的操作对应的不变量,问题就能迎刃而解。

为算法刻画和证明的方便,引入以下定义:称一个的矩阵A为序列的母矩阵,当且仅当,矩阵A中的所有非零元素,自上到下自左到右逐列读出得到,自左到右自下到上逐行读出得到升序序列。

称序列的所有母矩阵中,行数列数都最小的那个矩阵为序列的最简母矩阵。

例如:当n=5时,{5,3,2,4,1}的最简母矩阵为。

本题的算法只需要完成以下步骤即可。

(i)判断当前是否是升序序列,若是则打印输出结束程序,若否转(ii)(ii)计算的最简母矩阵A(设A是一个的矩阵)(iii)对进行如下题意中的操作:A的偶数行全部非零元素自左到右自上到下逐行读出得到,A的奇数行全部非零元素自左到右自上到下逐行读出得到。

重复(i)。

算法证明如下:只需证明:算法中给出的解是最优的,即操作步骤最少的。

首先:的最简母矩阵A,经上面的(iii)后,将成为一个行的矩阵。

(这是因为,…,其中表示A的第k行中非零元素构成的集合,对应A经操作后得到的矩阵B)。

其次:是一个升序序列,当且仅当,他的最简母矩阵是一个的矩阵。

例如:a=,b=,可得到最简母矩阵A=,则得到B=;由上面这两个事实可以得到,算法中给出的方案含有且只含有个步骤。

下面证明,这是最优的。

这只需证明:若的最简母矩阵有p行,则一次操作后得到的最简母矩阵至少有行。

我们用反证法。

假设存在一种操作方案,使得的最简母矩阵B只有行,。

则由抽屉原则,必定存在B的一行(不妨设为第行),使得其中含有来自A的不同的三行的非零元素(因为2<),设其中分别来自第行。

不妨<<,则由性质二(在A中)知:>>。

这样又由性质二(在B中),在B中第行中从左到右依次是。

所以,由性质一(在B中),在中出现的先后顺序为先,再,最后。

再由抽屉原则,中必有两个,同属于以下两个集合之一:{,…},{,…}。

不妨设同属于{,…}。

这样,、在中出现的先后顺序与中相同。

即在中也是先出现后出现。

我们考虑以下这些数:,+1,+2…-1,。

一方面,由于、在B中同行,由性质二(在B中),所有这些数在B中也同行,且位置介于、之间。

所以,他们在中按照顺序依次(不一定连续)出现。

同时,由性质一,他们一定同属于{,…},所以,他们在中也按照顺序依次(不一定连续)出现。

另一方面,由性质二(在A中),他们在A中的行号介于[,],且严格不增。

由于在A中不同行,所以其中必有相邻两个数在A中不同行,设为、+1。

由性质二,、+1一定处在相邻两行。

(否则,他们中间的行只能全零,那这些行就可以省略,这与A的最简性是矛盾的。

)另外,由前面的结论,在中先出现,+1后出现。

所以,在A中的列号小于+1的列号。

即、+1的位置关系是这样的:。

显然这两行是可以合并的,这与A的最简性矛盾!证毕。

当然,给出这样一个算法,不是本文的关键。

注意到这个算法的操作对象是矩阵,如果使用一般的实现方法,不可避免在最坏情况下单次操作的复杂度达到O(n2),显然,复杂度过高,还有优化余地。

要进一步优化程序,可以着眼数据结构。

不难发现,矩阵中的非零元素只有n个,因此可以只记录这些元素的位置,这样就等于把矩阵的规模缩小到了O(n),这一优化方法使得时空复杂度都得到了巨大的改进。

因此,算法的总时间复杂度是O(n·ans),同时是输出的复杂度,空间复杂度O(n),相比朴素实现矩阵的效果时空复杂度都得到了大大改进。

另外,仔细分析证明,可以发现列数的最优性是可以忽略的。

这样,在具体实现时让矩阵的每列只有一个元素,使得每个元素的位置信息可以更加简单,程序编码更加简便。

回顾这一问题的解决,关键在于“提炼”方法的使用忽略了矩阵中的非零元素这一无用信息,从而可以用线性表存储矩阵结构,使时间复杂度从O(n2·ans)降到O(n·ans),空间复杂度从O(n2) 降到O(n)。

问题二:CEOI 2007 Day 2 Necklaces问题描述:要求编译一个库,能够对若干已知的整数串进行两个操作:(i)在某个已知串的左端或右端增加或减少一个元素,得到一个新的已知的串。

(ii)输出某个已知串的最左端或最右端的数。

在问题的一开始,只有一个已知的串:空串。

这道题是一道典型的“赤裸裸”的数据结构题,若要进行n 个操作,则最坏情况下,需要维护O(n)个长为O(n)的字符串。

显然,朴素的实现无论在时间上还是空间上总的复杂度都要达到平方阶,这是不能令人满意的。

分析这道题的特点,发现由于每个串都要由之前的某个串经过微小加工得到,所以,这些串之间一定有很多公共部分。

不妨利用这一点来优化数据结构。

首先利用两种特殊情况来帮助思维(见表1):(i) 在某一串左侧,分别加上不同的元素,得到不同的串。

这一特例容易让我们想到星形存储。

(ii) 在某一串左侧,加上一列元素,在从右段依次删除。

这一特例容易让我们想到链形存储加上首尾指针。

特殊情况存储方式这样,我们就需要设计一种数据结构,上面的星形和链形统一起来。

很明显,树形结构可以胜任。

有了树形的构想,整个数据结构的设计就不难了。

根据上面的分析,可以维护一个数据结构,称它left-right tree 。

left tree 和right tree 都是Trie(字母树)。

表1 两种特殊情况和它们的存储方式 A B C A B C D C BC ABC AB BA A CA DA对于每个已知的串s ,我们把它任意(实际上不是任意的)分成左右两部分,左串存储在left tree 中,右串存储在right tree 中。

这样,我们只需要四个量:left_root, left_leave, right_root, right_leave ,就可以描述s :s 就由left tree 中left_leave 到left_root 的路径代表的串,与right tree 中right_root 到right_leave 的路径代表的串组成。

下面给出一个left-right tree 的例子(见图1)同时,我们允许,左串和右串中任意一串为空,甚至都为空,这时实际s 就为空。

并规定:若在左树中的串为空,则left_root=0;同样若在右树中的串为空,则right_root=0。

有了这样的数据结构,各个操作的实现已经不难了,只要实现好下面几个情况即可:(i) 已知树中某链的两端点,求底部端点的父亲(ii) 已知树中某链的两端点,求顶部端点在链中的儿子这些看起来都是Trie 的基本操作,但由于本题中Trie 的元素的规模不受限制,故(ii)的实现并不平凡,因此仍需要探讨,关于树形结构的化简将在第二部 1 234 56 7 8 9left tree right treeleft_leave left_root right_root right_leave图1 整数串(5,2,1,7,8)在一棵left-right tree 中的表示分着重讨论。

总结本题,关键在于,用“缩”的方法,利用Trie,将串数组中的重复数据压缩,用树形结构简化储存,空间复杂度从O(n2)到O(n),有了质的飞跃。

相关文档
最新文档