[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的更多相关文章

  1. 【LeetCode】697. Degree of an Array 解题报告

    [LeetCode]697. Degree of an Array 解题报告 标签(空格分隔): LeetCode 题目地址:https://leetcode.com/problems/degree- ...

  2. 【LeetCode】659. Split Array into Consecutive Subsequences 解题报告(Python)

    [LeetCode]659. Split Array into Consecutive Subsequences 解题报告(Python) 标签(空格分隔): LeetCode 作者: 负雪明烛 id ...

  3. 【LeetCode】153. Find Minimum in Rotated Sorted Array 解题报告(Python)

    [LeetCode]153. Find Minimum in Rotated Sorted Array 解题报告(Python) 标签: LeetCode 题目地址:https://leetcode. ...

  4. 【LeetCode】154. Find Minimum in Rotated Sorted Array II 解题报告(Python)

    [LeetCode]154. Find Minimum in Rotated Sorted Array II 解题报告(Python) 标签: LeetCode 题目地址:https://leetco ...

  5. 【leetcode】905. Sort Array By Parity

    题目如下: 解题思路:本题和[leetcode]75. Sort Colors类似,但是没有要求在输入数组本身修改,所以难度降低了.引入一个新的数组,然后遍历输入数组,如果数组元素是是偶数,插入到新数 ...

  6. 53. Maximum Subarray【leetcode】

    53. Maximum Subarray[leetcode] Find the contiguous subarray within an array (containing at least one ...

  7. 27. Remove Element【leetcode】

    27. Remove Element[leetcode] Given an array and a value, remove all instances of that value in place ...

  8. 【leetcode】893. Groups of Special-Equivalent Strings

    Algorithm [leetcode]893. Groups of Special-Equivalent Strings https://leetcode.com/problems/groups-o ...

  9. 【LeetCode】数组--合并区间(56)

    写在前面   老粉丝可能知道现阶段的LeetCode刷题将按照某一个特定的专题进行,之前的[贪心算法]已经结束,虽然只有三个题却包含了简单,中等,困难这三个维度,今天介绍的是第二个专题[数组] 数组( ...

随机推荐

  1. java 两个对象共使一个方法

  2. python socket基本连接功能实现

    socket是在应用层和传输层之间的一个抽象层,它把TCP/IP层复杂的操作抽象为几个简单的接口供应用层调用已实现进程在网络中通信 在应用中,要写两个程序来通信,一个是服务器端程序,一个是客户端程序 ...

  3. vs2005下opengl(glut)的配置记录

    摘自:http://blog.csdn.net/joeblackzqq/article/details/6956959 首先参考了网上的安装配置环境部分:http://blog.csdn.net/Id ...

  4. 安装Windows与CentOS双系统

    1.安装Windows系统 安装过程除了分区时要预留出部分空间来安装CentOS之外,其它操作与正常安装一样. 2.安装CentOS系统 使用光盘引导安装,因安装为服务器版,建议选择无界面,最小化安装 ...

  5. Install packages failed: Installing packages: error occurred. ------简单的问题常常会被忽略

    用 pip install 安装了wxpy这个库,但是使用的时候却报错:ImportError: No module named wxpy 我先用 pip list 查看了一下,发现这个库是已经存在的 ...

  6. nyoj 78:圈水池 【凸包入门】

    题目链接 将所有点按从左至右顺序排序,然后将所有点先从左到右扫描再从右到左扫描,逐渐将凸包轮廓“勾勒”出来 (凸包轮廓满足,轮廓上连续的三个点按先后顺序给出的话呈逆时针方向) 最后删去一个重复的起(终 ...

  7. sublime text 3插件下载教程

    Sublime官网下载地址:http://www.sublimetext.com/ 安装插件:(插件包管理Preferences Browse Packages) 插件官网:http://www.fe ...

  8. boost multi array

    Boost MultiArray is a library that simplifies using arrays with multiple dimensions. 1. #include < ...

  9. STM32输入捕获TIM2四通道

    相比于一通道,原子的例程里因为清了计数时间,所以要对程序进行修改. 记录上升沿后的计数,然后记录下降沿的计数.相减后计算高电平时间,对于定时器中断间隔的边界要分开处理. 这里因为我的接收机时间是1ms ...

  10. C#中的6种常见的集合

    1.动态数组(ArrayList) 动态数组(ArrayList)代表了可被单独索引的对象的有序集合.它基本上可以替代一个数组.但是,与数组不同的是,您可以使用索引在指定的位置添加和移除项目,动态数组 ...