array
Lzed
我好菜啊
展开
-
Leetcode 268 - Missing Number(等差数列 or 位运算)
题意给一个大小为n的数组,里面的元素为[0, n]中缺了一个数字,求缺的那个数字。要求:O(n)O(n)时间。O(1)O(1)空间。思路算法1如果数组包含[1, n]那么它的和为n(n+1)2\frac{n(n+1)}{2}。那么我们现在只需要对数组求和,两个相减,得到的就是缺失的那个数字了。算法2利用异或。我们知道^为:1 ^ 1 = 0, 0 ^ 1 = 1。那么,就可以得到这样两个结论:原创 2017-02-16 12:39:03 · 280 阅读 · 0 评论 -
Leetcode 18 - 4Sum
题意给一个数组和target,要求在数组中找到四个数,使a + b + c + d = target。思路类似于3Sum,排序后枚举其中两个数a和b,然后问题就转化成了2Sum。时间复杂度O(n3)O(n^3)代码class Solution {private: vector<vector<int>> ans;public: vector<vector<int>> fourSum原创 2017-02-23 11:48:10 · 244 阅读 · 0 评论 -
Leetcode 442 - Find All Duplicates in an Array (array)
题意同448,但是要求找出出现了两次的元素。思路算法1还是特别trick的一道题,但是既然写了448,我们大致就可以围绕那个方向了。我们还是假设x出现了,我们另a[abs(x) - 1]变为负数,代表x出现了一次。但是如果x出现了两次呢?要是我们再取一次反的话,就和没有出现的没有区别了。然后我的想法是如果y = a[abs(x) - 1]本身已经为负数了,说明已经出现了一次,将y减小n即可。如果遇到原创 2017-02-14 23:31:00 · 177 阅读 · 0 评论 -
Leetcode 31 - Next Permutation
题意实现next_permutation()。思路首先,我们知道,要使下一个数尽量小,那我们就需要下一个变大的数尽量在后面。假如我们选择位置k的数和某一个位置进行交换,我们需要考虑:为什么不选择k+1及其之后的位置?因为k+1到n的位置上的数已经达到了最大。即k+1到n的数组是降序的。比如我们k+1到n的数字为:1, 2, 3, 4。那么我们可以选择2换到前面使之增大。但是若其为:4, 3, 2,原创 2017-02-24 09:48:31 · 197 阅读 · 0 评论 -
Leetcode 169 - Majority Element(Moore投票算法)
题意给一个数组,求它的majority,对majority的定义为:出现次数超过⌊n2⌋\lfloor \frac{n}{2} \rfloor的元素。思路算法1O(nlogn)O(nlogn)时间。排序,然后返回中间的那个元素即可。算法2O(n)O(n)时间和O(n)O(n)空间。我们用unordered_map来存储每个元素出现的次数,最后返回出现次数超过⌊n2⌋\lfloor \frac{n}{原创 2017-02-15 22:03:10 · 215 阅读 · 0 评论 -
Leetcode 238 - Product of Array Except Self(递推)
题意给定一个数组a[],对于其中的每一个元素x,求数组中所有数相乘并除以该元素x的结果。并且不能使用除法。思路算法1O(n)O(n)时间和O(n)O(n)空间。我们维护一个l[i]和r[i]数组,分别代表从左往右乘到元素aia_i的积和从右往左乘到元素aia_i的积。那么,对于我们要求的结果ansi=li−1⋅ri+1ans_i = l_{i - 1} · r_{i + 1}。算法2O(n)O(n)原创 2017-02-15 22:31:50 · 156 阅读 · 0 评论 -
Leetcode 217 - Contains Duplicate(hash)
题意判断一个数组中是否有元素出现了2次或以上。思路用一个unordered_set记录一下就好。代码class Solution {public: bool containsDuplicate(vector<int>& nums) { unordered_set<int> has; for (auto x : nums) { if (原创 2017-02-15 22:58:33 · 169 阅读 · 0 评论 -
Leetcode 219 - Contains Duplicate II(hash or sort)
题意给定一个数组nums和一个数k,判断是否存在numsi=numsjnums_i = nums_j且|j−i|≤k|j - i| \leq k。思路算法1建立一个pair<int, int>为numsinums_i和ii,我们排序O(nlogn)O(nlogn)排序后遍历一遍就可以了。算法2用unordered_map存储元素x最后一次出现的下标,每次O(1)O(1)的去查找和判断就可以了。时间复原创 2017-02-15 22:59:22 · 181 阅读 · 0 评论 -
Leetcode 128 - Longest Consecutive Sequence
题意给一个数组,求这个数组中一个最大的子集,要求其是连续的。要求:O(n)O(n)时间思路首先,显然不能排序了。 我们考虑把这个数插入到unordered_set里面。假设我们从数组中选一个数x作为子集的一部分,那么我们需要找一个区间[l,r][l, r],使x∈[l,r]x \in [l, r]且[l,r][l, r]里面的所有数都应该在数组中出现过。判断一个数是否出现过,我们可以直接在unode原创 2017-02-25 15:42:32 · 242 阅读 · 0 评论 -
Leetcode 48 - Rotate Image(旋转矩阵)
题意给一个n x n的矩阵,顺时针90°旋转该矩阵。要求:O(1)O(1)空间思路先画一个图看一下转化关系: 那么,我们只需要从A(i,j)A_{(i, j)}转换到A(j,n−1−i)A_{(j, n - 1 - i)}即可。可以通过2步旋转。A(i,j)A_{(i, j)}到A(j,i)A_{(j, i)}:以对角线为对称线旋转即可。A(j,i)A_{(j, i)}到A(j,n−1−i原创 2017-02-25 16:48:33 · 351 阅读 · 0 评论 -
Leetcode 380 - Insert Delete GetRandom O(1)
题意设计一个数结构,支持:insert(x):O(1)O(1)插入元素x,如果已经存在返回falseremove(x):O(1)O(1)删除元素x,如果x不存在返回falsegetRandom():O(1)O(1)的等概率从里面随机返回一个元素思路unordered_map支持O(1)O(1)插入和删除,只需要O(1)O(1)的随机返回元素。我们用一个数组映射一下,用arr[pos] = x原创 2017-02-27 08:44:53 · 183 阅读 · 0 评论 -
Leetcode 448 - Find All Numbers Disappeared in an Array (Array)
题意给一个大小为n的数组a,数组内的元素范围为[1, n]。已知数组内有些元素出现了两次或1次,求数组内没有出现的元素。要求:O(n)O(n)时间无额外空间。保存结果的那个vector不算额外空间。思路非常trick的一道题啊。O(n)O(n)的时间就排除了排序,虽然计数排序可以,但是好像会用额外空间?然后无额外空间的话,我们只能利用现有空间了。那么,假如我们可以用额外空间的话,那么一个比较原创 2017-02-14 21:46:52 · 181 阅读 · 0 评论 -
Leetcode 16 - 3Sum Closest
题意给一个数组和一个target,要求在数组中找三个数a, b, c,使a + b + c更接近于target。思路和3Sum类似,转化为2Sum处理。先排序,然后枚举a,那么就转化成了b + c更接近于x = target - a。然后从a的位置之后,设置两个指针j和k指向首和尾,然后按照一定规则往中间走(用z记录距离target的绝对值):b+c<xb + c < x:更新z,并且j后挪一位。原创 2017-02-23 09:27:22 · 189 阅读 · 0 评论 -
Leetcode 78 - Subsets(枚举)
题意求一个set的所有子集思路算法1二进制枚举算法2回溯法。代码//algorithm 1class Solution {public: vector<vector<int>> subsets(vector<int>& nums) { int n = nums.size(); vector<vector<int>> ans; for (in原创 2017-02-17 15:16:00 · 188 阅读 · 0 评论 -
Leetcode 228 - Summary Ranges(Two pointers)
题意求数组内所有连续的范围。思路用两个指针i和j,分别指向每个范围的开始位置和结束位置就好。然后去遍历数组。string to_string(int x):将x转化为一个string返回。细节注意只有一个元素或者j指向最后一个元素的情况。因此我们在遍历数组的时候,可以用j == n作为终止条件,并且终止条件特判一下避免出错。代码class Solution {private: vector原创 2017-02-17 16:16:49 · 168 阅读 · 0 评论 -
Leetcode 118 - Pascal's Triangle(模拟)
题意给定n,生成n行的Pascal三角形。思路a[i,j]=a[i−1,j−1]+a[i−1,j]a[i, j] = a[i - 1, j - 1] + a[i - 1, j]。边界情况特判一下就好。代码class Solution {private: vector<vector<int>> pas; public: vector<vector<int>> generate(i原创 2017-02-17 16:26:06 · 262 阅读 · 0 评论 -
Leetcode 381 - Insert Delete GetRandom O(1) - Duplicates allowed
题意同380 - Insert Delete GetRandom O(1),只不过支持重复元素。思路pre我们先考虑还是用unordered_map+vector来做,既然支持重复元素,那么我们可以将重复元素穿成一条链,即unordered_map的结构为unordered_map<int, vector<int>> has,其中vector存储的为对应在arr里的下标。insert(val):原创 2017-02-27 20:02:53 · 307 阅读 · 0 评论 -
Leetcode 54 - Spiral Matrix(螺旋打印矩阵)
题意将一个矩阵螺旋打印出来。思路算法1一个需要记录很多变量的思路。首先,我们要确定走的方向是up还是down还是right还是left。然后,确定走的方向后,我们再确定每次要走多少步,分别用rs和cs来表示。当我们在最外围的时候,rs和cs都不变,但是当我们第三次转向及以后的过程中,rs和cs每次都要-1了。虽然变量很多但是想清楚了再写一遍能A。算法2直接模拟螺旋形的过程:我们分别用u, r, d,原创 2017-02-19 17:42:23 · 190 阅读 · 0 评论 -
Leetcode 289 - Game of Life(array)
题意给出一个矩阵的一个状态,根据一定规则来计算下一个状态。思路算法1O(mn)O(mn)的额外空间。新开一个数组来获得下一个状态即可,这样可以保证状态互不干扰。算法2O(1)O(1)额外空间,O(mn)O(mn)时间。要更新一个位置(i,j)(i, j)的时候,我们需要知道它的neibor的状态,但是neibor的状态可能已经被更新过,但是我们依赖的是以前的状态,然后最后的结果统计又依赖于最后的状态原创 2017-02-20 21:33:29 · 171 阅读 · 0 评论 -
Leetcode 11 - Container With Most Water(two pointers)
题意给定一堆竖着的线,找两条线,使这两条线围城的容器的面积最大。思路首先,我们先贪心的去考虑:假设我们直接取最两边的两条线i和j,能否获得最大高度?显然是不一定的。然后,我们去需要取移动两边的选取i和j了。然后基于如下事实:若ai<aja_i <a_j,那么我们向左移动j不会更新最优解。因为此时的面积S=ai(j−i)S = a_i(j - i),并且若向左移动j到k的位置,那么此时的面积S′=mi原创 2017-02-20 20:41:02 · 197 阅读 · 0 评论 -
Leetcode 57 - Insert Interval(区间问题)
题意给一些互不重合并且已经排好序的区间,现在加入一个新的区间b,要求将b合并进去。思路算法1其实和区间合并那道题差不多,但是需要判断的是我们的新区间b需要加入的位置。当新区间b.start <= a[i].start的时候,需要将b加入进去。有一些细节需要注意一下。但是感觉稍微有点难写呐= =首先,判断第一个插入的是a[0]还是b:如果是a[0],之后的循环就从1开始;否则从0开始。对于之后的循环:原创 2017-02-19 20:45:25 · 201 阅读 · 0 评论 -
Leetcode 56 - Merge Intervals(区间合并)
题意给定若干个区间,合并这些区间。思路算法1先将区间排序,然后每次选定一个区间i,遍历之后的区间j,找到最后一个能够合并的区间后,合并。然后区间的起点的i跳转到j + 1。算法2假如我们现在结果ans里面已经有一些区间了,最后一个区间为x(x.end一定是ans里面最大的)。对于下一个区间y,如果y.start <= x.end,说明能够和x重合,我们将x.end更新为max(x.end, y.en原创 2017-02-19 19:22:30 · 235 阅读 · 0 评论 -
Leetcode 15 - 3Sum(双指针)
题意给一个数组,要求求数组里面所有的a, b, c,使得a + b + c = 0,要求解不重复。思路算法1排序 + 二分。先排序,然后枚举a和b,那么c = -a - b,然后二分查找一下c。时间复杂度O(n2logn)O(n^2logn)注意去重:只要a和b不重复,那么c一定不会重复,于是枚举a和b时要跳过相同的值。算法2枚举 + Hash我们用unordered_map存储每个元素出现的最后一原创 2017-02-23 08:47:27 · 213 阅读 · 0 评论 -
Leetcode 42 - Trapping Rain Water(Array)
题意给一些bar,求这些bar能够积水的面积。思路扫描。先考虑对于一个bar,能够积水的区域: 即向左有一个bar: ll,向右有一个bar: rr,以now为底的这个bar能够围成的面积为min(l,r)−nowmin(l, r) - now,很明显我们能够知道l和r越大, 那么我们的结果越优。所以,我们需要维护最大的l和r。那么,对于该题,我们只需要将每个bar能够积水的区域累加起来即可。用l原创 2017-02-27 11:25:56 · 221 阅读 · 0 评论