This commit is contained in:
youngyangyang04
2020-07-27 17:03:01 +08:00
parent 2e7218c187
commit 7f5c3afc05
3 changed files with 35 additions and 8 deletions

View File

@ -3,15 +3,26 @@ https://leetcode-cn.com/problems/sliding-window-maximum/
## 思路
这是使用单调队列的经典题目。
暴力方法遍历一遍的过程中每次从窗口中在找到最大的数值这样很明显是O(n * k)的算法。
有的同学可能会想用一个大顶堆也就是优先级队列来存放这个窗口里的k个数字这样就可以知道最大的最大值是多少了 但是问题是这个窗口是移动的,而大顶堆每次只能弹出最大值,我们无法移除其他数值,这样就造成大顶堆维护的不是滑动窗口里面的数值了。所以不能用大顶堆。
使用单调队列,即单调递减或单调递增的队列。 它不是一个独立的数据结构,需要使用其他数据结构来实现单调队列,例如: dequedeque是双向队列可以选择 从头部或者尾部pop同样也可以从头部或者尾部push。
不要以为实现的单调队列就是 对窗口里面的数进行排序,如果排序的话,那和优先级队列又有什么区别了呢。
详情看代码吧,已经简洁。
## C++代码
```
class Solution {
public:
class MyQueue {
class MyQueue { //单调队列(从大到小)
public:
deque<int> que;
deque<int> que; // 使用deque来实现单调队列
void pop(int value) {
if (!que.empty() && value == que.front()) {
que.pop_front();
@ -31,14 +42,14 @@ public:
vector<int> maxSlidingWindow(vector<int>& nums, int k) {
MyQueue que;
vector<int> result;
for (int i = 0; i < k; i++) {
for (int i = 0; i < k; i++) { // 先将前k的元素放进队列
que.push(nums[i]);
}
result.push_back(que.front());
result.push_back(que.front()); // result 记录前k的元素的最大值
for (int i = k; i < nums.size(); i++) {
que.pop(nums[i - k]);
que.push(nums[i]);
result.push_back(que.front());
que.pop(nums[i - k]); // 模拟滑动窗口的移动
que.push(nums[i]); // 模拟滑动窗口的移动
result.push_back(que.front()); // 记录对应的最大值
}
return result;
}

View File

@ -3,7 +3,22 @@ https://leetcode-cn.com/problems/reverse-string/
## 思路
遍历数组的前一半,同时和后一半做交换就可以了
一些同学直接用C++里的一个库函数 reverse调一下直接完事了 相信每一门编程语言都有这样的库函数,但是如果这么做题的话,这样大家不会清楚反转字符串的实现原理了。
那么如果在现场面试中,我们什么时候使用库函数,什么时候不要用库函数呢。
如果题目关键的部分直接用库函数就可以解决,建议不要使用库函数,毕竟面试官一定不是考察你对库函数的熟悉程度, 如果使用python 和 java 的同学更需要注意这一点因为python java 提供的库函数十分丰富。
如果库函数仅仅是 解题过程中的一小部分,并且你已经很清楚这个库函数的内部实现原理的话,可以考虑使用库函数。
建议我们平时在leetcode上练习算法的时候本着这样的原则去练习这样才有助于我们对算法的理解。
接下来我们再来讲一下如何解决反转字符串的问题。
这道题目遍历数组的前一半,同时和后一半做交换就可以了
此时我们再看一下代码实现
## 代码

View File

@ -4,6 +4,7 @@
https://leetcode-cn.com/problems/reverse-string-ii/
## 思路
先做0344.反转字符串,在做这道题目更好一些
for循环中i 每次移动 2 * k然后判断是否需要有反转的区间