数据结构与算法01:常用的数据结构

数据结构与算法

在算法中,要考虑数据结构的优缺点是否会影响到算法的时间和空间复杂度

常用数据结构:

数组:

优点:
构建一个数组非常简单。能让我们在O(1)的时间里根据数组的下标(index)查询某个元素
缺点:
构建时必须分配一段连续的空间;
查询某个元素是否存在时需要遍历整个数组,耗费O(n)的时间(其中,n是元素的个数);
删除和添加某个元素时,同样需要消耗O(n)的时间

​字符串:
常见的算法就是将字符串转化为数组之后进行操作

类似:字符串反转:
将字符串变换为数组,两个指针分别指向头和尾,值进行交换,然后头指针向后移位,尾指针 向前移位,再进行交换,循环执行到指针相遇为止

Leetcode:242.有效的字母异位词
​ 给定两个字符串s和t,编写一个函数来判断t是否是t的字母异位词。可以假设字符串只包含小写字母
示例1:输入:s = “anagram”,t = “nagaram” 输出:true
解题思路:
​ 因为小写英文字母一共有26个,所以可以有一个26长度的字符串,将s中出现的每个字母对应位置的值+1,再根据t将值-1,判断最后是否都为0即可。

链表

单链表:
链表中的每一个元素实际上是一个单独的对象,而所有对象都通过每个元素中的引用字段链接在一 起。

双链表:
与单链表不同的是,双链表的每个结点中都含有两个引用字段。

优点:
灵活地分配内存空间
​能在O(1)的时间内删除或者添加元素
缺点: 查询元素需要O(n)的时间

扫描二维码关注公众号,回复: 12664138 查看本文章

解题技巧:
​ 利用快慢指针(有时候需要三个指针)
例如:
链表的翻转,寻找倒数第k个元素,寻找中间位置的元素,判断链表是否有环等等

​ 构建一个虚假的链表头,往其后面添加元素即可
例如
两个排序链表,进行整合排序
​将链表的奇偶数按照原定顺序分离,生成前半部分为奇数,后半部分为偶数的链表

如何训练技巧

​ 在纸上或者白板上出节点之间的相互关系,出修改的方法

Leetcode:25.k个一组翻转链表
给你一个链表, 每k个节点一组进行翻转,请你返回翻转后的链表。k是一个正整数,它的值小于或者等于链表的长度。如果节点总数不是k的整数倍,那么请将最后剩余的节点保持原有顺序
示例:
​ 给定这个链表:1-2-3-4-5
​ 当k=2时,应当返回:2-1-4-3-5
​ 当k=3时,应当返回:3-2-1-4-5
解题思路:
在这里插入图片描述
在这里插入图片描述

​ 栈

特点: 后进后出

算法基本思想:
可以用一个单链表来实现
当解决问题的时候,只关心最近一次的操作,并且在操作完成之后,需要查找到在前一次的操作

Leetcode:20.有效的括号
给当一个只包括’(’,’)’,’{’,’}’,’[’,’],的字符串,判断字符串是否有效。
示例1:输入"()" 输出true
解题思路:
就是准备一个栈,不断往里压左括号,当遇到右括号时,就把栈顶的左括号弹出来,说明这一对括号合法,结束后判断栈中是否还有元素存在

Leetcode:739.每日温度
根据每日气温列表,请重新生成一个列表,对应位置的输入时你需要再等待多久温度才会升高超过该日的天数,如果之后都不会升高,请在该位置用0来代替
示例:temperature = [23, 24, 25, 21, 19, 22, 26, 23]
输出:[1, 1, 4, 2, 1, 1, 0, 0]
解题思路:
利用堆栈,从头扫描一遍,先压入23,24比23高,所以23位置上为1,然后把23出栈,24压栈,接着比较并赋值,当压入25时,21,19都比25小,所以把21,19入栈不对25位置上的值做操作,当压入22时,比栈顶元素19高,所以栈顶元素19位置上的值为1,接着19出栈,栈顶元素是21,22也比21高,所以21位置上的值为2即第五天减去第三天为2,接着21出栈,22压栈最后一次比较。这是对数组进行一次遍历,复杂度为O(n)。

​队列

特点: 先进先出(双链表可以实现队列)
常用的场景: 广度优先搜索

双端队列

​可以利用一个双链表
​队列的头尾两端能在O(1)的时间内进行数据的查看、添加和删除
常用的场景: 实现一个长度动态变化的窗口或者连续区间

Leetcode:239.滑动窗口最大值
给定一个数组nums,有一个大小为k的滑动窗口从数组的最左侧移动到数组的最右侧,你只可以看到滑动窗口k内的数字,滑动窗口每次只向右移动一位,返回滑动窗口的最大值
示例:输入:nums=[1,3,-1,-3,5,3,6,7],和k=3
输出:[3,3,5,5,6,7]
解题思路:
利用双端队列,队列头一直都是窗口中的最大值,同时根据这个下标,判断新的窗口已经不再包含这个最大的数,把旧的数从双端队列删除

第一个窗口:1,3,-1
​ 一开始双端队列放入1,然后3与队尾作比较即1,比1大,1弹出,3成了队头
​ 接着-1与双端队列作比较,比3小,将-1放到队尾,3为最大值 此时队列值为:【3,-1】
接着第二个窗口:3,-1,-3
​ -3比-1小,压入队尾,3为最大值 此时队列值为:【3,-1,-3】
接着第三个窗口:-1,-3,5
​ 将5与队尾依次比较,比-3大,-3被弹出,-1接着被弹出,3不在窗口内,3被弹出,5为最大值 此时队 列值为:【5】
反复下去。。。

这个就是两种操作:将新的数据加入到窗口的尾部并做比较,将旧的数据从头部删除
双端队列可以让上述两种操作在 O(1) 的时间里完成

​ 树的共性
​ 结构直观
​ 通过树问题来考察 递归算法 掌握的熟练程度

面试中常考的树的形状有

普通二叉树
平衡二叉树
完全二叉树
二叉搜索树
四叉树
多叉树

特殊的树:红黑树、自平衡二叉搜索树

关于树的考题:

遍历: 前序遍历、中序遍历、后序遍历

Leetcode:230.二叉搜索中的第K小的元素
给定一个二叉搜索树,编写一个函数来查找其中第k个最小的元素。
解题思路:
​ 按照中序遍历二叉搜索树,遍历出来的肯定是从小到大的
​ 注意二叉搜索树的中序遍历是常考的,还可以求第k大的元素,即倒着的中序遍历

猜你喜欢

转载自blog.csdn.net/qq_44918331/article/details/111693533