2023年系统刷题计划

2023年系统刷题计划

2023年2月毕业快三年了,从技术来讲,兜兜转转的自己的提升还是太慢了。时常会想起左程云提及的一段话。“年轻人总会找借口说这个东西不是我感兴趣的,所以做不好是应该的。但他们没有注意的是,你面对的事情中感兴趣的事情总是少数,这就使得大多数的时候你做事情的态度总是很懈怠、很消极,这使你变成了一个懈怠的人。当你真正面对自己感兴趣的东西时,你发现你已经攥不紧拳头了。”感慨归感慨,真正实际的事情还是要落到实处,扎根脚底。从自己最弱的算法开始整起来吧。

计划总体使用半年左右时间。对算法和数据结构进行系统性研究一遍。截止到 2023年8月兑现承诺。

目标:每种数据结构、每种算法都应该整理文章、码出最优代码。

一、栈和队列

  • 计划用时:1周
查看更多

如何仅用递归函数和栈操作逆序一个栈

如何仅用递归函数和栈操作逆序一个栈

一、题目

将一个栈用递归实现逆序,即:插入栈比如是:1、2、3、4、5。栈中存储从底到顶是1、2、3、4、5。逆序后,希望存储的从底到顶是5、4、3、2、1。只能使用递归

二、思路

递归就是使用了操作系统为我们程序提供的栈空间,这块空间也是栈结构。也就是说我们需要操作系统的栈为我们存储什么东西。我们标记操作系统的栈为 A;业务栈为 B。

在这个题目中,我们需要栈 A 为我们保存栈 B 每一个元素。因此,

  • 我们先做第一步,拿到栈 B 的最底的元素,并让他出栈 B。这个过程也利用操作系统栈来保存栈 B 从底到顶的元素。
查看更多

最大子矩阵的大小

最大子矩阵的大小

一、题目

给定一个由 0 和 1 组成的矩阵 matrix ,找出只包含 1 的最大矩形,并返回其面积。

注意:此题 matrix 输入格式为一维 0/1 字符串数组。

leetcode:https://leetcode.cn/problems/PLYXKQ/

二、思路

要求出最大的子矩阵,我们先做一个假设,如果想要组成一行 N 列的矩阵,我们可以先求出二维数组中每一列的矩阵大小。然后我们再将这些列数据组合起来。如下图

假设有一个二维数组:

查看更多

滑动窗口的最大值

滑动窗口的最大值

一、题目

给你一个整数数组 nums,有一个大小为 k 的滑动窗口从数组的最左侧移动到数组的最右侧。你只可以看到在滑动窗口内的 k 个数字。滑动窗口每次只向右移动一位。

返回 滑动窗口中的最大值 。

leetcode:https://leetcode.cn/problems/sliding-window-maximum/

二、思路

这个题目 O(k*N) 的时间复杂度是达不到要求的,需要得到一个 O(N) 的时间复杂度。那么我们的思考过程,我们要拿到每次滑动窗口的最大值,重点是要在滑动的时候就求出这个窗口内的最大值,而且我们是可以做到的。那么我们选择什么数据结构来存储这个最大值呢,这个数据结构需要可以两端都可以进出,选择双端队列再合适不过了

假设我们遍历到 arr[i] 这个位置,对于插入队列:如果队列为空,直接插入队尾;否则我们拿 queue.back() 值进行比较。队列插入的是下标,而非值。

查看更多

用一个栈实现另一个栈的排序

用一个栈实现另一个栈的排序

一、题目

栈排序。 编写程序,对栈进行排序使最小元素位于栈顶。最多只能使用一个其他的临时栈存放数据,但不得将元素复制到别的数据结构(如数组)中。该栈支持如下操作:push、pop、peek 和 isEmpty。当栈为空时,peek 返回 -1。

leetcode:https://leetcode.cn/problems/sort-of-stacks-lcci/

二、思路

想要对栈进行排序,并且从栈低到栈顶为从大到小。可以使用一个辅助栈,那么我们只需要让辅助栈的栈低到栈顶为从小到大即可。也就是我们将元素按照一定逻辑插入到辅助栈中,实现辅助栈的栈低到栈顶为从小到大即可。

我们从栈中取出一个元素记为 cur,当去插入到辅助栈中时,和辅助栈的 top 值进行比较(如果没有top,直接插入)

查看更多

由两个栈组成的队列

由两个栈组成的队列

一、题目

用两个栈实现一个队列。队列的声明如下,请实现它的两个函数 appendTail 和 deleteHead ,分别完成在队列尾部插入整数和在队列头部删除整数的功能。(若队列中没有元素,deleteHead 操作返回 -1 )

leetcode:https://leetcode.cn/problems/yong-liang-ge-zhan-shi-xian-dui-lie-lcof/

二、实现思路

  • 两个栈,一个栈 A 只用来进元素,一个栈 B 只用来出元素
  • 进的时候,只通过栈 A。出的时候

查看更多

设计一个有getMin功能的栈

设计一个有getMin功能的栈

一、题目

设计一个支持 push ,pop ,top 操作,并能在常数时间内检索到最小元素的栈。

实现 MinStack 类:

MinStack() 初始化堆栈对象。
void push(int val) 将元素val推入堆栈。
void pop() 删除堆栈顶部的元素。
int top() 获取堆栈顶部的元素。
int getMin() 获取堆栈中的最小元素。

对应的 leetcode 地址:https://leetcode.cn/problems/min-stack/submissions/

二、实现思路

查看更多

K个一组反转链表

一、题目

给你链表的头节点 head ,每 k 个节点一组进行翻转,请你返回修改后的链表。

k 是一个正整数,它的值小于或等于链表的长度。如果节点总数不是 k 的整数倍,那么请将最后剩余的节点保持原有顺序。

你不能只是单纯的改变节点内部的值,而是需要实际进行节点交换。

Leetcode:https://leetcode.cn/problems/reverse-nodes-in-k-group/description/

二、分析

这道题目本身比较简单,主要需要关注节点指针的边界问题。

查看更多

数组的partition调整

数组的partition调整

一、题目

给定一个有序数组 arr,调整 arr 使得这个数组的左半部分没有重复元素且升序,而不用保证右部分是否有序

例子:

1
2
3
arr = {1, 2, 2, 2, 3, 3, 4, 5, 6, 6, 7, 7, 8, 8, 8, 9}
调整之后:
arr = {1 2 3 4 5 6 7 8 9 6 2 7 2 8 8 3}

二、思路

这道题目的思路较为简单,我们需要一个分界位置,假定为 u,那么我们设定 [0 ... u] 上的元素是没有重复元素且生序的。u 从 0 开始。然后 arr[u+1, i] 上的元素不用管他是否有重复元素,其中 i 是遍历数组的索引。

查看更多