LeetCode Summary Array and Matrix

================================= Array ===================================


中位数
4. Median of Two Sorted Arrays(两有序数列,求他们的中位数,O(log (m+n)).)
S1:最朴素,两个数列归并排序,选取中间位置。
S2:two pointers
把两个数组都分成两个部分,放在leftpart和rightpart里面,确保两部分个数相同,并且衔接的数大小满足。
"if we cut the sorted array to two halves of EQUAL LENGTHS, then
median is the AVERAGE OF Max(lower_half) and Min(upper_half), i.e. the
two numbers immediately next to the cut".
S3:binary search


Two Pointers
初值:经常一个0,一个n-1
11. Container With Most Water (n个非负点(i, ai),找到两个点,和x轴,包含的水最多。)
S1(Mine):Two pointers
维护两个指针l和r,初值0和len - 1, 谁小移动谁,移动的过程中,不断更新maxAns
S2:Discuss Solution
从最宽的开始,然后往中间移动。
42. Trapping Rain Water(N个非负整数,最多囤多少水)
S1(Mine):朴素枚举,非常慢
S2(Discuss):
从最左和最右开始,往中间,left,right。maxleft和maxright维护当前左右的最大值。
左右两边left和right,谁小就处理谁:更新maxleft/maxright 或者 累计result
WA:累计result时,是maxxxx-height[ ]
75. Sort Colors(给三种颜色排序,同种颜色放一起)
S1:三个计数器对应三种颜色,nums[i]=0时,三个都+1;nums[i]=1时,后两个+1;nums[i]=2时,最后一个加1
相当于,谁要更新,它后面的颜色也得往后挪。
S2: 两个游标zero=0,second=n-1;把0往左移动,2往右移动
while (A[i]==2 && i<second) swap(A[i], A[second--]);
        while (A[i]==0 && i>zero) swap(A[i], A[zero++]);
41. First Missing Positive(给定一个无序数组,找到第一个缺失的数)
用交换,把数放在应该在的位置上
162. Find Peak Element(找到peak点)
维护left,right,往中间
209. Minimum Size Subarray Sum(找到长度最小的子串连续,和>=s)
S1(Mine):sum[i]前i个的和,枚举>=s的和,很慢
S2(Discuss): 两个指针first和last,求和的过程中,根据sum和s的关系,
只要 sum>=s更新(maxLen,last-first)
然后,sum-num[first],去掉首元素,因为sum>=s了
直到sum<s才能加入下一个last
76. Minimum Window Substring(两个串S和T,求S中的最小窗口包含T中所有)
S1(Mine):暴力枚举,太慢
S2(Discuss):map+two pointers
(1)Use two pointers: start and end to represent a window.
(2)Move end to find a valid window.
(3)When a valid window is found, move start to find a smaller window.
283. Move Zeroes(把一串数中,所有的0都放在末尾)
S1(Mine): 枚举
3. Longest Substring Without Repeating Characters(找到最长的没有重复字符的子串)
S1(Mine): 没有重复是,right一直往右至有重复,更新max
30. Substring with Concatenation of All Words(给一个字符串和一串等长单词,找到所有的起始位置,使得每个单词都出现一次)
S1(Mine): 用map和vector暴力,非常非常慢!
S2(Discudd): 
两个map,一个记录每个单词要求出现的次数,一个记录实际出现的次数。
当实际次数> 或者不满足要求时,break。从左至右依次枚举,check成功时,记录结果
5. Longest Palindromic Substring(找到s里最长的回文子串)
S1(Mine): 直接硬来,很慢*3
S2(Discuss): Two pointers.Discuss里的方法好棒
要点: 跳过连续重复的字母;剩下长度<=maxLen直接跳出循环;
循环i找起始位置,jk左右,k跳过重复字母,分别向左向右若回文。


数组操作
396. Rotate Function
模拟
189. Rotate Array(旋转数组k位)
记得k%len
S1(Mine):开一个数组另存
349. Intersection of Two Arrays
350. Intersection of Two Arrays II(给定两个数组,找到他们的交)
S1(Mine): 模拟
S2(Discuss): 用set放nums1,然后check是否有nums2,有就加入res并erase
238. Product of Array Except Self(给定一串整数,返回一串数,使得位置i是其他所有数的乘积)
S1(Mine): 直接暴力枚举计算

几个数的和等于或者接近一个target值
15. 3Sum(给定一个整数集合,找到所有的和为0的三元组)
S1(Mine): 3 pointers
排序,选定3个指针,计算和,根据和跟0的关系,调整后面两个指针的位置。
三个指针初值:i循环;j=i+1; k=n-1
S2 - Discuss 
固定一点,另外两点按照TwoSum来移动。
点多的时候,就固定一点,其他的移动。
16. 3Sum Closest 
18. 4Sum 
4个的话,就先固定一个,再固定一个,剩下两个游标根据和多了少了移动
初值:i,j=i+1,low=j+1,high = n-1
1. Two Sum(给定一串整数,求何和为给定值的两个数的下标)
排序
固定一点i,另外两点j,k移动,j,k初值:i+1,n-1
sum小了,则j++;sum大了,则k--
167. Two Sum II - Input array is sorted(有序递增序列,找到合为target的两个数)
left和right,根据和的大小移动两个游标




满足某种条件删除冗余
26. Remove Duplicates from Sorted Array
27. Remove Element
使用一个计数器p,当是/不是冗余时候,A[p++]=冗余/非冗余
for(int i=0;i<n;i++) if(A[i]!=elem) A[begin++]=A[i];

if(A[i] == A[i-1]) count++; else A[i-count] = A[i];// 新的数,加入
80. Remove Duplicates from Sorted Array II(至多出现2次,数组要处理)
S1(Mine):朴素枚举
S2(Discuss):
k是可以容忍的冗余个数,i是当前的位置,当nums的值n大于当前的值时,就往后添加;
nums[i-k]是关键点,表示,i这个位置往前k个,这样就是可以有k个冗余了。
int i = 0;
for (int n : nums)
if (i < k || n > nums[i - k]) nums[i++] = n;
return i;


跳步数能否到达/最少次数
45. Jump Game II(给定一列非负数,表示在该位置可以最多跳几步,求最少的次数跳完整列)
记录当前可以到达的最远位置max,以及上次增加次数时的位置loc,
当当前位置i==loc时,jump++, loc=max,表示需要增加次数
55. Jump Game(判断能否到达)
依次遍历i,记录当前可到达的最远位置,判断n点是否可达。
bool canJump(int A[], int n) {
int i = 0;
for (int reach = 0; i < n && i <= reach; ++i)
reach = max(i + A[i], reach);
return i == n;
}

旋转矩阵
48. Rotate Image(旋转n*n的矩阵)
1. 顺时针:上下颠倒,主对角线对称
1 2 3     7 8 9     7 4 1
4 5 6  => 4 5 6  => 8 5 2
7 8 9     1 2 3     9 6 3
void rotate(vector<vector<int> > &matrix) {
reverse(matrix.begin(), matrix.end());
for (int i = 0; i < matrix.size(); ++i) {
for (int j = i + 1; j < matrix[i].size(); ++j)
swap(matrix[i][j], matrix[j][i]);
}
}
2. 逆时针:左右颠倒,主对角线对称
1 2 3     3 2 1     3 6 9
4 5 6  => 6 5 4  => 2 5 8
7 8 9     9 8 7     1 4 7
void anti_rotate(vector<vector<int> > &matrix) {
for (auto vi : matrix) reverse(vi.begin(), vi.end());
for (int i = 0; i < matrix.size(); ++i) {
for (int j = i + 1; j < matrix[i].size(); ++j)
swap(matrix[i][j], matrix[j][i]);
}
}

螺旋矩阵
54. Spiral Matrix(m*n矩阵,返回螺旋序列)
S1(Mine):上下左右四个方向,flag标记是否走过,没走过走,并且入队列。
59. Spiral Matrix II(生成螺旋矩阵)
标记是否走过,四个方向轮流,四个方向用dx[],dy[],计数%4来找方向


矩阵
73. Set Matrix Zeroes(0所在行列,均置为0)
S1(Mine):第一轮标记0在的行列,row[0]和col[0]来标记,space(1),第二轮置0
74. Search a 2D Matrix(从左上到右下有序,查找值是否存在)
二分,把整个矩阵当做一个数组二分,left = 0, right = row * col - 1;
找值的时候:r = mid / col, c = mid % col;
118. Pascal's Triangle(杨辉三角)
朴素的计算
289. Game of Life(一堆处理矩阵的规则)
S1(Mine): 按照规则暴力即可

区间
56. Merge Intervals(合并区间)
S1(Mine):排序;朴素合并
57. Insert Interval(在有序区间,加入新的区间)
同56
228. Summary Ranges(一串有序数,转换成区间)
S1(Mine): 从左往右扫一遍,遍历即可。




长度柱子
84. Largest Rectangle in Histogram(找到最大的矩形)
在heights的尾部加0,方便最后一根柱子。
维护一个栈s,使得里面的柱子保持高度递增。
当当前高度<=栈顶时,计算栈顶元素高度的矩形面积,并更新maxAns,直至当前高度>栈顶高度,或者栈空
因为栈中元素是递增的,所以,每次的栈顶元素(top),从top到i这段的都是比栈顶元素高的。所以可以用top的高度做矩形高度
一个循环优化:使用while,只有当前i入栈时(高度大于栈顶时)才更新i++。



判断是否存在相同的数,对两个相同数下标距离有要求
217. Contains Duplicate(判断是否存在冗余)
S1(Mine):使用set判断是否有重复
219. Contains Duplicate II(相同数下标的距离最多是k)
S1(Mine):使用map记录出现和位置,重复时计算下标距离。很慢。
S2(Discuss):用set记录出现,遍历nums[i],每次删掉与i距离大于k的数,判断nums[i]是否在set里,在就是true
220. Contains Duplicate III(两数之差最多是t,下标距离最多是k)
S1(Mine): t=0时单独处理,有相同即可; t<>0时,i和j两个下标,遍历nums,j的上限由i决定,判断是否满足t和k
S2(Discuss):桶排序,见Sort.cpp

字符串处理
214. Shortest Palindrome(往字符串s前添加最少的个数,变成回文串)
S1(Mine): 直接模拟
S2(Discuss): KMP,详见该题目的文档
389. Find the Difference(找不同)
S(Mine): 模拟
168. Excel Sheet Column Title(转换成excel数)
171. Excel Sheet Column Number
模拟
273. Integer to English Words(整数转英文单词)
写一个专门处理3位数的函数,int->words
6. ZigZag Conversion
模拟
58. Length of Last Word(给一串)
14. Longest Common Prefix(找到一组字符串的最长前缀)
S(Mine): 枚举比较
28. Implement strStr()(找到一个串在另一个串第一次出现的位置)
S(Mine):暴力枚举
38. Count and Say(念出来数字,找到第n个序列)
暴力枚举找连续相同即可
125. Valid Palindrome(判断串是否回文)
Mine: 全转成大写或者小写来判断
两个指针
151. Reverse Words in a String(若干用空给分割开的单词组成的串,将单词反序)
读到单词,ans= word + ans即可
165. Compare Version Numbers(比较两个版本号的大小)
模拟
297. Serialize and Deserialize Binary Tree(对二叉树进行编码和解码)
Mine: 用了题目中的编码和解码方式。注意不要超时
345. Reverse Vowels of a String(反序所有的元音字母)、
Mine: 用string记录所有的元音,再扫一遍,是原因的从string末尾往前替换。




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值