数据结构
杨陈菊
whether you are lion or gazelle you must sprint for survival
展开
-
迭代与递归的区别
基础不牢,地动山摇。迭代和递归的区别:从“编程之美”的角度看,可以借用一句非常经典的话:“迭代是人,递归是神!”来从宏观上对二者进行把握。递归:重复调用函数自身实现循环称为递归;递归实际上不断地深层调用函数,直到函数有返回才会逐层的返回,递归是用栈机制实现的,每深入一层,都要占去一块栈数据区域,因此,递归涉及到运行时的堆栈开销(参数必须压入堆栈保存,直到该层函数调用返回为止),所以有可能导致堆栈溢出的错误;但是递归编程所体现的思想正是人们追求简洁、将问题交给计算机,以及将大问题分解为相同小问题从而解转载 2020-11-25 16:03:52 · 721 阅读 · 0 评论 -
动态规划求解最大子序列和
1 求解最大子序列和题目给定一个整数数组 nums ,找到一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。示例:输入: nums = [2, 3, -6, 2, 4]输出: 6解释: 连续子数组 [2,4] 的和最大,为 6。2 方法分析本节来源:https://leetcode-cn.com/problems/maximum-subarray/solution/xiang-xi-jie-du-dong-tai-gui-hua-de-shi-xian-yi-li/解题思原创 2020-09-07 20:31:44 · 2239 阅读 · 0 评论 -
关于编程解决问题时的问题定位和数据结构的选择
假设现在面对一个实际的算法问题,则需要从以下两个方面进行思考。1. 问题的分析思路首先,我们要明确目标。 即用尽可能低的时间复杂度和空间复杂度,解决问题并写出代码;接着,我们要定位问题。 目的是更高效地解决问题。这里定位问题包含很多内容。例如:这个问题是什么类型(排序、查找、最优化)的问题;这个问题的复杂度下限是多少,即最低的时间复杂度可能是多少;采用哪些数据结构或算法思维,能把这个问题解决。为了方便理解,下面我们来举一个例子,在一个包含 n 个元素的无序数组 a 中,输出其最大值 ma原创 2020-08-08 21:38:55 · 647 阅读 · 0 评论 -
动态规划
1. 什么是动态规划从数学的视角来看,动态规划是一种运筹学方法,是在多轮决策过程中的最优方法。那么,什么是多轮决策呢?其实多轮决策的每一轮都可以看作是一个子问题。从分治法的视角来看,每个子问题必须相互独立。但在多轮决策中,这个假设显然不成立。这也是动态规划方法产生的原因之一。2. 最短路径问题接下来看一个非常典型的例子,最短路径问题。如下图所示:每个结点是一个位置,每条边是两个位置之间的距离。现在需要求解出一条由 A 到 G 的最短距离是多少。不难发现,我们需要求解的路线是由 A 到 G,这就原创 2020-08-07 21:05:35 · 10458 阅读 · 1 评论 -
常见的4种排序方法(冒泡排序、插入排序、归并排序、快速排序)
前面课时中,我们学习了分治法的思想,以及二分查找的实现方法。我们讲到,二分查找要求原数组必须有序。其实,由无序到有序,这是算法领域最常见的一类问题,即排序问题。本课时,我们就来学习 4 种常见的排序算法,包括冒泡排序、插入排序、归并排序以及快速排序。此外,我们还会对这 4 种排序算法的优劣势进行详细地对比分析。什么是排序问题排序,就是让一组无序数据变成有序的过程。 一般默认这里的有序都是从小到大的排列顺序。下面我们先来讲讲,如何判断不同的排序算法的优劣。衡量一个排序算法的优劣,我们主要会从以下 3 个原创 2020-08-06 23:43:50 · 4828 阅读 · 0 评论 -
数据查找之分治法
前面的文章学习了数据结构、递归思想等,从定性的角度来看,分治法的核心思想就是“分而治之”。利用分而治之的思想,就可以把一个大规模、高难度的问题,分解为若干个小规模、低难度的小问题。随后,开发者将面对多个简单的问题,并很快地找到答案各个击破。在把这些简单问题解决好之后,我们通过把这些小问题的答案合并,就得到了原问题的答案。分治法应用很广泛,很多高效率的算法都是以分治法作为其基础思想,例如排序算法中的快速排序和归并排序。分治法是什么?计算机求解问题所需的计算时间,与其涉及的数据规模强相关。简而言之,问题原创 2020-08-05 22:13:13 · 983 阅读 · 0 评论 -
算法思维基础之“递归”
不管是数据结构还是算法思维,它们的目标都是降低时间复杂度。数据结构是从数据组织形式的角度达成这个目标,而算法思维则是从数据处理的思路上去达成这个目标。本文介绍算法思维基础之一 ----递归1. 什么是递归在数学与计算机科学中,递归 (Recursion))是指在函数的定义中使用函数自身的方法,直观上来看,就是某个函数自己调用自己,有循环的意味在里面。递归有两层含义:递归问题必须可以分解为若干个规模较小、与原问题形式相同的子问题。并且这些子问题可以用完全相同的解题思路来解决;递归问题的演化过程是原创 2020-08-04 18:59:07 · 1470 阅读 · 0 评论 -
高效率的查找神器--哈希表
本文从数据结构角度认识哈希表,更多关于Java编程中HashMap的用法见:对HashMap的简单认识1. 什么是哈希表哈希表名字源于 Hash,也可以叫作散列表。哈希表是一种特殊的数据结构,它与数组、链表以及树等数据结构相比,有很明显的区别。2. 哈希表的核心思想在数组、链表以及树等数据结构中,数据的存储位置和数据的具体数值之间不存在任何关系。因此,在面对查找问题时,这些数据结构必须采取逐一比较的方法去实现。而哈希表的设计采用了函数映射的思想,将记录的存储位置与记录的关键字关联起来。这样的设计方原创 2020-08-03 22:15:35 · 1162 阅读 · 0 评论 -
数据结构基础之树和二叉树:分支关系与层次结构下的增删查操作
本文主要内容是树和二叉树概念,以及如何用树和二叉树实现对数据的增删查的操作。1.树树是由结点和边组成的,不存在环的一种数据结构。树满足递归定义的特性。也就是说,如果一个数据结构是树结构,那么剔除掉根结点后,得到的若干个子结构也是树,通常称作子树。在一棵树中,根据结点之间层次关系的不同,对结点的称呼也有所不同。我们来看下面这棵树,如下图所示:A 结点是 B 结点和 C 结点的上级,则 A 就是 B 和 C 的父结点,B 和 C 是 A 的子结点。B 和 C 同时是 A 的“孩子”,则可以称原创 2020-08-02 22:27:45 · 866 阅读 · 0 评论 -
关于面试高频问题之--字符串匹配问题
字符串匹配问题是面试的高频问题之一,本文讲字符串和它的相关操作。1. 字符串是什么字符串(string) 是由 n 个字符组成的一个有序整体( n >= 0 )。例如,s = “BEIJING” ,s 代表这个串的串名,BEIJING 是串的值。这里的双引号不是串的值,作用只是为了将串和其他结构区分开。字符串的逻辑结构和线性表很相似,不同之处在于字符串针对的是字符集,也就是字符串中的元素都是字符,线性表则没有这些限制。在实际操作中,我们经常会用到一些特殊的字符串:s = ""; // 表示空原创 2020-08-01 17:30:57 · 1094 阅读 · 0 评论 -
数组--数据结构中的最基本结构
通过前面几篇文章,我们了解了线性表、栈、队列的基本概念及各自的增删查操作。同时了解了数据结构中时间复杂度和空间复杂度的概念和衡量方式。由于栈和队列是特殊的线性表,本质上它们都可以被看作是一类基本结构。而数组则可以看成是线性表的一种推广,它属于另外一种基本的数据结构。本文我们从数据结构的角度重新认识数组的概念以及如何用数组实现增删查的操作。1. 数组是什么数组是数据结构中的最基本结构,几乎所有的程序设计语言都把数组类型设定为固定的基础变量类型。我们可以把数组理解为一种容器,它可以用来存放若干个相同类型原创 2020-07-31 21:17:27 · 2698 阅读 · 0 评论 -
队列--先进先出的线性表
前面的文章介绍了线性表,后进先出的线性表–栈。本文介绍另一种特殊的链表–队列以及队列的增删查。1.队列的定义与栈相似,队列也是一种特殊的线性表,与线性表的不同之处也是体现在对数据的增和删的操作上。队列的特点是先进先出:先进,表示队列的数据新增操作只能在末端进行,不允许在队列的中间某个结点后新增数据;先出,队列的数据删除操作只能在始端进行,不允许在队列的中间某个结点后删除数据。也就是说队列的增和删的操作只能分别在这个队列的队尾和队头进行。与线性表、栈一样,队列也存在这两种存储方式,即顺序队列和原创 2020-07-29 20:37:47 · 7099 阅读 · 0 评论 -
线性表基本操作
数据在代码中被处理和操作的最小单位动作是增、删、查。他们是深入学习数据结构的根基,通过“增删查”操作,我们可以选择更合适的数据结构来解决实际工作中遇到的问题。例如几个客户端分别分别向服务端发送请求,服务端要采取先到先得的处理方式,应该如何设计数据结构呢?本文介绍数据结构之一,线性表。1.什么是线性表数据结构是数据的组织方式。那么线性表就是数据的组织方式之一。线性表是n个数据元素的有限列表,最常用的是链式表达,通常也叫作线性链表或链表。在链表中存储的数据元素叫做结点,一个结点存储的就是一条数据记录。每个原创 2020-07-28 12:55:25 · 2539 阅读 · 0 评论 -
栈--后进先出的线性表
1、栈是什么首先线性表是使用非常广泛的一类数据结构,它对数据的顺序非常敏感,而且它对数据的增删操作非常灵活。栈是一种特殊的线性表。栈与线性表的不同,体现在增和删的操作。具体而言,栈的数据结点必须后进先出。宏观上来看,与数组或链表相比,栈的操作更为受限,那为什么我们要用这种受限的栈呢?其实,单纯从功能上讲,数组或者链表可以替代栈。然而问题是,数组或者链表的操作过于灵活,这意味着,它们过多暴露了可操作的接口。这些没有意义的接口过多,当数据量很大的时候就会出现一些隐藏的风险。一旦发生代码 bug 或者受到攻原创 2020-06-11 20:49:23 · 3254 阅读 · 1 评论 -
时间复杂度和空间复杂度
1.复杂度是什么?首先需要知道怎么衡量复杂度。而在实际衡量时,我们通常会围绕以下2 个维度进行:时间复杂度和空间复杂度。2.如何去计算复杂度?复杂度是一个关于输入数据量 n 的函数。假设你的代码复杂度是 f(n),那么就用个大写字母 O 和括号,把 f(n) 括起来就可以了,即 O(f(n))。例如,O(n) 表示的是,复杂度与计算实例的个数 n 线性相关;O(logn) 表示的是,复杂度与计算实例的个数 n 对数相关。3.复杂度计算的三个原则O(n) = O(2n) O(n²)+O(n) =原创 2020-05-26 14:55:08 · 291 阅读 · 0 评论