【LeetCode】Array
[11] Container With Most Water [Medium]
O(n^2)的暴力解法直接TLE。
正确的解法是Two Pointers。 O(n)的复杂度。保持两个指针i,j;分别指向长度数组的首尾。如果ai 小于aj,则移动i向后(i++)。反之,移动j向前(j--)。如果当前的area大于了所记录的area,替换之。这个想法的基础是,如果i的长度小于j,无论如何移动j,短板在i,不可能找到比当前记录的area更大的值了,只能通过移动i来找到新的可能的更大面积。
class Solution {
public:
int maxArea(vector<int>& height) {
int i = ;
int j = height.size() - ;
int ans = ;
while(i < j) {
int area = (j - i) * min(height[i], height[j]);
ans = max(ans, area);
if (height[i] <= height[j]) {
++i;
}
else {
--j;
}
}
return ans;
}
};
[15] 3Sum [Medium]
它要求返回结果不重复,所以去重。不能用unique,会TLE,直接在循环里面跳过。
先排序,两根指针,夹逼定理
class Solution {
public:
vector<vector<int>> threeSum(vector<int>& nums) {
vector<vector<int>> result;
if (nums.size() < ) {
return result;
}
sort(nums.begin(), nums.end());
for (int i = ; i < nums.size(); ) {
int j = i + ;
int k = nums.size() - ;
while (j < k) {
if (nums[i] + nums[j] + nums[k] == ) {
result.push_back(vector<int>{nums[i], nums[j], nums[k]});
++j, --k;
while (j < k && nums[j-] == nums[j]) { ++j; }
while (j < k && nums[k+] == nums[k]) { --k; }
}
else if (nums[i] + nums[j] + nums[k] < ) {
++j;
while (j < k && nums[j-] == nums[j]) { ++j; }
}
else {
--k;
while (j < k && nums[k+] == nums[k]) { --k; }
}
}
++i;
while (nums[i-] == nums[i]) { ++i; }
}
return result;
}
};
[16] 3Sum Closest [Medium]
三个数求和,返回离target最近的和。
Two Pointers, 跟15题一样, 先排序,两根指针左右夹逼。
class Solution {
public:
int threeSumClosest(vector<int>& nums, int target) {
int result = ;
int min_gap = INT_MAX;
sort(nums.begin(), nums.end());
for (int i = ; i < nums.size() - ; ++i) {
int start = i + , end = nums.size() - ;
while (start < end) {
int temp = nums[i] + nums[start] + nums[end];
int gap = abs(temp - target);
if (gap < min_gap) {
min_gap = gap;
result = temp;
}
if (temp == target) break;
if (temp > target) {
--end;
}
else if (temp < target) {
++start;
}
}
}
return result;
}
};
[17] 4Sum [Medium]
四个数求和,求出和target相等的元组, 思路和3sum一个样,包括和去重的方式都一样。
还是先排序,然后两根指针。
class Solution {
public:
vector<vector<int>> fourSum(vector<int>& nums, int target) {
vector<vector<int>> result;
if (nums.size() < ) {
return result;
}
sort(nums.begin(), nums.end());
for (int i = ; i < nums.size()-; ) {
for(int j = i+; j < nums.size()-; ) {
int start = j + , end = nums.size() - ;
while (start < end) {
int sum = nums[i] + nums[j] + nums[start] + nums[end];
if (sum == target) {
result.push_back(vector<int>{nums[i], nums[j], nums[start], nums[end]});
++start, --end;
while (start < end && nums[start-] == nums[start]) {
++start;
}
while (start < end && nums[end+] == nums[end]) {
--end;
}
}
else if (sum < target) {
++start;
while (start < end && nums[start-] == nums[start]) {
++start;
}
}
else {
--end;
while (start < end && nums[end+] == nums[end]) {
--end;
}
}
}
++j;
while (nums[j-] == nums[j]) { ++j; }
}
++i;
while(nums[i-] == nums[i]) { ++i; }
}
return result;
}
};
[45] Jump Game II [Hard]
这个题需要记忆。再考肯定不会。。。要记忆。。。
给你一个数组,数组元素的值是从当前index最多能往前面移动的步数,求到数组末尾最少移动的步数。
我是参考了这个:https://www.tianmaying.com/tutorial/LC45
/*
将每个位置都看作一个点,并从第i个点向它之后的nums[i]个点都连一条长度为1的有向边,而现在的问题就是从0号点到达size-1号点需要的最短距离,这就是一个很简单的最短路问题,实际上由于边的长度均为1,而且不存在环,我们可以用宽度优先搜索(时间复杂度为O(n^2),即边数)来进行相关的计算。 不难发现,这道题目转换出的最短路问题存在三个条件: 边的长度均为1
不存在环
连出的边是连续的
我们是不是可以用这三个“很强”的条件来做一些优化呢,答案自然是肯定的! ——如果令f[i]表示从0号点到达i号点的最短路径,那么对于任意i<j,有f[i]<=f[j],即f是非递减的,这个结论的证明是显然的,在此不作过多赘述。 在有了这样的结论之后,我们就会发现,其实对于f数组来说,它会是一段段的存在,先是一个0,然后是一段1,然后是一段2,依此类推,那么现在问题来了,每一段的长度是多少呢? 这个问题很好回答,如果我们令l[k]表示f数组中值为k的一段的左边界,r[k]表示f数组中值为k的一段的有边界,那么有 l[k] = r[k - 1] + 1,这是显然的
r[k] = max{i + nums[i] | l[k - 1] <= i <= r[k - 1]},由于f值为k的位置一定是从f值为k-1的位置走来的,所以只需要看从所有f值为k-1的位置里最远可以到达的地方即可。
也就是说,我们可以在对nums的一遍扫描中,依次求出所有的l[k]和r[k],而f数组也就自然求解出来了——答案也就得到了。
*/
class Solution {
public:
int jump(vector<int>& nums) {
int k = , l = , r = ;
while (r < nums.size()-) {
int next_r = r;
for (int i = l; i <= r; ++i) next_r = max(next_r, nums[i]+i);
++k; l = r + ; r = next_r;
}
return k;
}
};
[48] Rotate Image [Medium]
题目要求一个方阵顺时针旋转90°。
经过研究发现顺时针旋转90°,相当于先转置,再每行逆序。要学会矩阵转置的写法。
class Solution {
public:
void rotate(vector<vector<int>>& matrix) {
const int N = matrix.size();
//trans
for (int i = ; i < N; ++i) {
for (int j = i+; j < N; ++j) {
swap(matrix[i][j], matrix[j][i]);
}
} //reverse
for (int i = ; i < N; ++i) {
int start = , end = N - ;
while (start < end) {
swap(matrix[i][start++], matrix[i][end--]);
}
}
}
};
[54] Spiral Matrix [Medium]
打印旋转矩阵。 设置有用的四个变量 beginx, beginy, endx, endy。然后用一个i去遍历。
class Solution {
public:
vector<int> spiralOrder(vector<vector<int>>& matrix) {
vector<int> ans;
if (matrix.size() == ) {
return ans;
}
const int m = matrix.size();
const int n = matrix[].size();
int beginx = , beginy = ;
int endx = n-, endy = m - ;
while (true) {
for (int i = beginx; i <= endx; ++i) {
ans.push_back(matrix[beginy][i]);
}
++beginy;
if (beginy > endy) break; for (int i = beginy; i <= endy; ++i) {
ans.push_back(matrix[i][endx]);
}
--endx;
if (beginx > endx) break; for (int i = endx; i >= beginx; --i) {
ans.push_back(matrix[endy][i]);
}
--endy;
if (beginy > endy) break; for (int i = endy; i >= beginy; --i) {
ans.push_back(matrix[i][beginx]);
}
++beginx;
if (beginx > endx) break;
}
return ans;
}
};
[56] Merge Intervals [Hard]
合并线段(数轴) 参考57题。 在 Insert Interval的基础上,一个新的interval集合,然后每次从旧的里面取一个interval出来,然后插入到新的集合中。
/**
* Definition for an interval.
* struct Interval {
* int start;
* int end;
* Interval() : start(0), end(0) {}
* Interval(int s, int e) : start(s), end(e) {}
* };
*/
class Solution {
public:
vector<Interval> merge(vector<Interval>& intervals) {
vector<Interval> ans;
if (intervals.size() == ) {
return ans;
}
ans.push_back(intervals[]);
for (int i = ; i < intervals.size(); ++i) {
insert_interval(ans, intervals[i]);
}
return ans;
}
vector<Interval> insert_interval(vector<Interval>& intervals, Interval newInterval) {
vector<Interval>::iterator it = intervals.begin();
while (it != intervals.end()) {
if (it->start > newInterval.end) {
break;
}
else if (it->end < newInterval.start) {
it++;
continue;
}
else {
newInterval.start = min(newInterval.start, it->start);
newInterval.end = max(newInterval.end, it->end);
intervals.erase(it);
}
}
intervals.insert(it, newInterval);
return intervals;
}
};
[57] Insert Interval [Hard]
先判断是否能放在最前面,然后在现有的intervals中一个一个遍历。有覆盖就更新newInterval,然后把原本的那段删除。
/**
* Definition for an interval.
* struct Interval {
* int start;
* int end;
* Interval() : start(0), end(0) {}
* Interval(int s, int e) : start(s), end(e) {}
* };
*/
class Solution {
public:
vector<Interval> insert(vector<Interval>& intervals, Interval newInterval) {
vector<Interval>::iterator it = intervals.begin();
while (it != intervals.end()) {
if (it->start > newInterval.end) {
break;
}
else if (it->end < newInterval.start) {
++it;
continue;
}
else {
newInterval.start = min(it->start, newInterval.start);
newInterval.end = max(it->end, newInterval.end);
intervals.erase(it);
}
}
intervals.insert(it, newInterval);
return intervals;
}
};
[59] Spiral Matrix II [Medium]
跟前一题Spiral Matrix的区别是前一题是遍历, 这个题是造一个矩阵出来。 思路写法都一样。
class Solution {
public:
vector<vector<int>> generateMatrix(int n) {
vector<vector<int>> matrix(n, vector<int>(n, ));
if (n == ) {
return matrix;
}
int number = ;
int beginx = , beginy = , endx = n - , endy = n - ;
while (true) {
for (int i = beginx; i <= endx; ++i) {
matrix[beginy][i] = number++;
}
++beginy;
if (beginy > endy) { break; } for (int i = beginy; i <= endy; ++i) {
matrix[i][endx] = number++;
}
--endx;
if (beginx > endx) { break; } for (int i = endx; i >= beginx; --i) {
matrix[endy][i] = number++;
}
--endy;
if (beginy > endy) { break; } for (int i = endy; i >= beginy; --i) {
matrix[i][beginx] = number++;
}
++beginx;
if (beginx > endx) { break; }
}
return matrix;
}
};
[73] Set Matrix Zeroes [Medium]
如果矩阵中一个元素为0, 那么把该元素所在的行和列都置零。O(1)的空间复杂度
思路:有个简单的O(m+n)的空间复杂度的,就是设两个布尔数组,来控制行和列是否为0.
但是如果要降低到O(1)的话,就可以牺牲第0行和第0列来存这两个数组。提前用两个变量保存好第0行,第0列是否置0.
class Solution {
public:
void setZeroes(vector<vector<int>>& matrix) {
const int m = matrix.size();
if (m == ) return;
const int n = matrix[].size();
bool row_has_zero = false;
bool col_has_zero = false;
for (size_t i = ; i < m; ++i) {
if (matrix[i][] == ) {
col_has_zero = true;
break;
}
}
for (size_t j = ; j < n; ++j) {
if (matrix[][j] == ) {
row_has_zero = true;
break;
}
} for (size_t i = ; i < m; ++i) {
for (size_t j = ; j < n; ++j) {
if (matrix[i][j] == ) {
matrix[i][] = ;
matrix[][j] = ;
}
}
} for (size_t i = ; i < m; ++i) {
for (size_t j = ; j < n; ++j) {
if (matrix[i][] == || matrix[][j] == ) {
matrix[i][j] = ;
}
}
} if (col_has_zero == true) {
for (size_t i = ; i < m; ++i) {
matrix[i][] = ;
}
} if (row_has_zero == true) {
for (size_t j = ; j < n; ++j) {
matrix[][j] = ;
}
}
return;
}
};
[118] Pascal's Triangle [Easy]
class Solution {
public:
vector<vector<int>> generate(int numRows) {
vector<vector<int>> ans;
if (numRows == ) return ans;
for (size_t i = ; i < numRows; ++i) {
vector<int> ans_row(i+, );
if (i == || i == ) {
ans.push_back(ans_row);
continue;
}
for (size_t j = ; j < i ; ++j) {
ans_row[j] = ans[i-][j-] + ans[i-][j];
}
ans.push_back(ans_row);
}
return ans;
}
};
[119] Pascal's Triangle II [Easy]
只要求O(k)的额外空间。我自己写的解法用了两个数组,其实一个就够了。
class Solution {
public:
vector<int> getRow(int rowIndex) {
vector<int> ans(rowIndex+, );
vector<int> help(rowIndex+, );
if (rowIndex == || rowIndex == ) {
return ans;
}
for (size_t i = ; i < rowIndex+; ++i) {
help = ans;
for (size_t j = ; j < i; ++j) {
ans[j] = help[j-] + help[j];
}
ans[i] = ;
}
return ans;
}
};
一个数组的还没看懂(好困,睡了==)
class Solution {
public:
vector<int> getRow(int rowIndex) {
vector<int> A(rowIndex+, );
A[] = ;
for(int i=; i<rowIndex+; i++)
for(int j=i; j>=; j--)
A[j] += A[j-];
return A;
}
};
【LeetCode】Array的更多相关文章
- 【LeetCode】697. Degree of an Array 解题报告
[LeetCode]697. Degree of an Array 解题报告 标签(空格分隔): LeetCode 题目地址:https://leetcode.com/problems/degree- ...
- 【LeetCode】659. Split Array into Consecutive Subsequences 解题报告(Python)
[LeetCode]659. Split Array into Consecutive Subsequences 解题报告(Python) 标签(空格分隔): LeetCode 作者: 负雪明烛 id ...
- 【LeetCode】153. Find Minimum in Rotated Sorted Array 解题报告(Python)
[LeetCode]153. Find Minimum in Rotated Sorted Array 解题报告(Python) 标签: LeetCode 题目地址:https://leetcode. ...
- 【LeetCode】154. Find Minimum in Rotated Sorted Array II 解题报告(Python)
[LeetCode]154. Find Minimum in Rotated Sorted Array II 解题报告(Python) 标签: LeetCode 题目地址:https://leetco ...
- 【leetcode】905. Sort Array By Parity
题目如下: 解题思路:本题和[leetcode]75. Sort Colors类似,但是没有要求在输入数组本身修改,所以难度降低了.引入一个新的数组,然后遍历输入数组,如果数组元素是是偶数,插入到新数 ...
- 53. Maximum Subarray【leetcode】
53. Maximum Subarray[leetcode] Find the contiguous subarray within an array (containing at least one ...
- 27. Remove Element【leetcode】
27. Remove Element[leetcode] Given an array and a value, remove all instances of that value in place ...
- 【leetcode】893. Groups of Special-Equivalent Strings
Algorithm [leetcode]893. Groups of Special-Equivalent Strings https://leetcode.com/problems/groups-o ...
- 【LeetCode】数组--合并区间(56)
写在前面 老粉丝可能知道现阶段的LeetCode刷题将按照某一个特定的专题进行,之前的[贪心算法]已经结束,虽然只有三个题却包含了简单,中等,困难这三个维度,今天介绍的是第二个专题[数组] 数组( ...
随机推荐
- linux 性能测试之基准测试工具
https://niyunjiu.iteye.com/blog/316302 system: lmbench unixbench5.1.2 ubench freebench nbench ltp xf ...
- jmeter 参数化3_User Defined Variables(用户自定义变量)
User Defined Variables: 一般用于Test Plan中不需要随请求迭代的参数设置,如:Host.Port Number 操作路径:Thread Group-->Add-- ...
- Vue 滚动条动画
<template> <div class="home-main"> <div class="progress-main"> ...
- 磁盘I/O工作原理
原创转载请注明出处:https://www.cnblogs.com/agilestyle/p/11524947.html TODO Reference https://time.geekbang.or ...
- 【leetcode】714. Best Time to Buy and Sell Stock with Transaction Fee
题目如下: Your are given an array of integers prices, for which the i-th element is the price of a given ...
- Linux服务的安装与使用
Spotlight on Unix 监控Linux服务器的安装与使用 详细请看:https://spotlight-on-unix.software.informer.com/download/#do ...
- ini操作
关于C#操作INI文件的总结 INI文件其实是一种具有特定结构的文本文件,它的构成分为三部分,结构如下: [Section1] key = value2 key = value2 …… [Sectio ...
- Rainbow的信号 CH3801
题目链接 题意:求n个整数任意取一个区间,一起进行xor,and,或or的操作,求xor的期望值,and的期望值,or的期望值. 思路:区间取的左端点为l,右端点为r,当r==l时,选的概率为1/n/ ...
- UE编辑器
引用ue的js 下载地址http://pan.baidu.com/s/1gdrQ35L <script type="text/javascript" src="__ ...
- 单例模式@Singleton在测试中的运用
前言 单例模式是一种比较常用的设计模式,目的是:保证一个类仅有一个实例,并提供一个访问它的全局访问点. 测试种可能用到的场景 : 在很多时候,有些对象我们希望在整个程序只有一个实例,如线程池.数据库连 ...