No.217
复盘:
核心思路:排序后临近元素进行判定,如果相同则返回true
我的解法:自己手写了个快排。。然后再判定
题解:
1、排序:时间:O(NlogN) 空间:O(log N)
直接使用库函数sort()完成快排,然后判定
2、哈希表:时间复杂度:O(N),空间复杂度:O(N)
使用哈希表存储数组元素,如果插入新元素的时候哈希表中已有该元素,则说明该元素重复了。
No.53
复盘:
核心思路:遍历一遍,找出和最大的连续子数组
我的解法:暴力遍历,逐个算出所有连续子数组的和并找出最大值【必然超时了,菜是原罪】
题解:
1、动态规划:时间:O(N) 空间:O(1)
(1)在遍历的同时记录之前的和最大的连续子数组pre
(2)然后再加上当前元素:pre + x,和pre比较,取最大值为pre
(3)最后用pre和之前记录的最大的和maxAns比较,取最大值为maxAns
2、分治:时间复杂度:O(N),空间复杂度:O(logN)
把这个数组当作一个线段树来遍历,将整个数组分成两部分,再继续分,分到只有一个元素之后递归求得和最大的连续子数组
【还是不是太懂,等算法课老师讲了分治再看看】
No.1
复盘:
核心思路:用效率最高的方式遍历数组,找出和为指定数的两个数组元素
我的解法:暴力枚举,把每一个数和后面所有的数的和都求一遍,找出答案。
题解:
1、哈希表:时间:O(N) 空间:O(N)
遍历一遍数组,把数组元素x存入哈希表,然后只需要在哈希表中查找是否存在和为ans - x的索引的元素就行。找到之后再返回两者的数组下标。
No.88
复盘:
核心思路:合并数组并排序
我的解法:由于数组原本就是有序的,因此我先是创建了一个新数组,然后从两个数组头开始比较数组的值,哪个值更小就用哪个值
题解:
1、动态规划:时间:O(N) 空间:O(1)
(1)在遍历的同时记录之前的和最大的连续子数组pre
(2)然后再加上当前元素:pre + x,和pre比较,取最大值为pre
(3)最后用pre和之前记录的最大的和maxAns比较,取最大值为maxAns
2、分治:时间复杂度:O(N),空间复杂度:O(logN)
把这个数组当作一个线段树来遍历,将整个数组分成两部分,再继续分,分到只有一个元素之后递归求得和最大的连续子数组
【还是不是太懂,等算法课老师讲了分治再看看】
No.350
复盘:
核心思路:用哈希表存储,找出相同标识的元素
我的解法:使用了两个哈希表,其实一个就够
题解:
哈希表:
1、在使用auto it迭代器遍历哈希表的时候,这时迭代器的为格式为pair<int,int> &,是哈希表元素的地址
因此读取元素的时候要使用it.first/it.second,而不能使用->
2、先遍历短的数组空间复杂度更低
3、没有必要先把两个数组都存到哈希表中,使用一个哈希表就行了,遍历完短的哈希表然后再和另一个数组的数比较
排序 + 双指针:
1、排序之后可以直接通过指针比较值的大小,仅需创建返回的vector就行了,这样空间复杂度是O(1)
No.121
复盘:
这次解题的思路是对的,这种在数组中寻找差值或和的题一般都是使用动态规划,但是在求最大利润的时候我还是写复杂了。
遍历一遍数组,每一天的最大利润c都为当天股价a和之前股价b的最大差值,即c = a - b,我写的时候和之前的每一天逐个求差找最大利润,这样效率太低了。
实际上对于每一天来说a都是固定的,那么求最大利润c即求最小的b
因此题目转化为:寻找每天之前的最低股价b即可
所以从遍历开始的时候就记录最低股价就能获得每一天之前的最低股价
No.566
复盘:
1、这道题的核心思路就是用最简单的方式遍历原来的二维数组。
2、我的思路是如果给的行列数符合要求则遍历一遍二维数组,逐个将原来数组中的元素存进要输出的二维数组中
做的时候遇到一个问题就是vector的二维数组push_back之前要先初始行数组,然后才能存元素进去。
题解中这样可以直接初始化所有行:
vector<vector> ans(r, vector©);
3、当然,我的思路还是复杂了一点,我遍历输出的res数组的同时还需要把原来的数组遍历一遍。
题解的思路是直接利用数组的下标将原来的二维数组转化为一维数组:
二维数组下标(i , j) → i × n + j
因此可以直接求出i、j的值:
i = x / n
j = x % n
然后一步就可以完成转化了
ans[x / c][x % c] = nums[x / n][x % n];
No.118
复盘:
1、这道题挺简单,只要得出相加的式子就行
2、需要注意的还是vector二维数组开辟的方法,题566中是矩阵,每一行的元素数量相同,所以可以直接开辟空间
这道题的杨辉三角每行的元素数量不同,所以要根据每一行不同的列数开辟空间
我是先开辟一行的空间再逐个push_back进数组
题解中是遍历的时候根据列数修改每行的空间,使用了resize函数:
ret[i].resize(i + 1);
No.36
复盘:
1、这题也不算很难,核心思路是把 9 * 9的矩阵按照题目中判定的三种条件划分成三个数组:行、列、以及 3 * 3的宫
然后再根据所划分的数组进行判断,如果有元素出现的次数超过一次则说明数组无效
2、需要思考的就是如何通过一次遍历把数组划分成三种情况,行列都比较简单,直接取行列的编号就行了
3 * 3 的宫的话,可以把原来 9 * 9 的矩阵分成 9 个 3 * 3 的宫,因此行列就各自除3得到对应宫的编号
No.73
复盘:
1、这道题的核心思路是:如何用最少的额外空间来标记哪些行和列需要置零
2、我的思路是用m+n的额外空间来记录置零行列的数据,比起直接用m * n的矩阵空间来说开销小了一点,但是还是不够小
3、题解的思路真的挺巧妙的,甚至可以只需要额外两个甚至一个变量的空间就可以完成标记
巧妙的地方在于原地算法,利用了矩阵原本的空间来进行标记
首先是两个额外变量的情况:只需要用两个额外变量记录原本矩阵的第一行和第一列的存在0的情况
然后再用第一行和第一列的空间来标记哪些行列需要置零即可
然后是只使用了一个额外变量的情况,只需要记录第一列是否存在零的情况即可,第一列数据用来标记行
由于是行遍历的顺序,所以如果这样的话每一列的第一个元素会被提前更新,那么只需要从最后一行开始遍历
这样就不会提前更新每行第一个列变量了