leetcode每日一题复盘(字符串,滑动窗口)

leetcode 459 重复的子字符串 

一开始想到了用模拟法,但是获取子字符串之间间隔的方式不对,我想的是遍历找到第一个与s[0]相同的字符,以他们下标的差作为间隔,再以两次for循环检查字符串中每一个字符

思路是每次但是方式错了导致时间复杂度很大,间隔length范围缩小为字符串的一半,通过取余判断数量是否匹配,不匹配直接免除检查遍历


移动构造法:

如果字符串存在重复子字符串,那么s+s中(去头去尾)必然能找到s

例如abab abab 把开头a,末尾b去掉,bababa 依然能找到abab

这样就可以用库函数find找到位置

class Solution {
public:
    bool repeatedSubstringPattern(string s) {
        string t = s + s;
        t.erase(t.begin()); t.erase(t.end() - 1); // 掐头去尾
        if (t.find(s) != std::string::npos) return true; // r
        return false;
    }
};

另一种方法,大同小异:

把头去掉,如果find返回的不是第二个字符串的开头,则true

class Solution {
public:
    bool repeatedSubstringPattern(string s) {
        return (s + s).find(s, 1) != s.size();
    }
};

leetcode 232 用栈实现队列 

代码部分比较简单,主要是对stack的用法不熟悉

stack是一个容器适配器,用其他容器创建堆栈。如果未提供容器,则使用默认的 deque 容器,容器适配器不适用迭代器

template <class T, class Container = deque<T> > class stack;

支持普通构造,拷贝构造,移动构造,赋值操作

stack的部分方法:

emplace():在栈顶构造并插入元素

empty():判断栈是否为空

pop():弹出栈顶第一个元素

push():在栈顶插入元素

top():返回栈顶元素的值

swap():交换两个栈的元素

size():返回栈中元素数量

stack类重载了运算符:

是则返回true,否则返回false

==:判断两个栈是否相等

!=: 判断两个栈是否相等

>:比较是否大于另一个栈

<:比较是否小于另一个栈

>=,<=:同理

leetcode 150 逆波兰表达式求值

 题目的要点之一就是要理解什么是逆波兰表达式,题目给出了逆波兰表达式的定义

题目也挑明了用栈进行操作,具体思路是遇到数字就入栈,遇到符号就弹出栈顶两个进行计算并将结果压入栈中

题目难在怎么将字符串里面的值提取出来,一开始我是想把字符串变成字符,用栈来存放字符,但是这样还是没能解决转换成整型的问题

对此我们需要用到库函数stoll,将字符串转换成long long型(官方修改了用例只能用long long型才能通过)

stoll():将字符串转换为long long int类型的整数,并将其值返回

支持三个参数

str:指定带有整数的string对象

idx:此参数指定指向size_t类型的对象的指针,该对象的值由功能设置为数值后str中下一个字符的位置。此参数也可以是空指针,在这种情况下,将不使用该参数。

base:设定数字的进制,默认是10


stol():将字符串转换成long int类型的整数,并将其值返回

支持三个参数

str:指定带有整数的string对象

idx:此参数指定指向size_t类型的对象的指针,该对象的值由功能设置为数值后str中下一个字符的位置。此参数也可以是空指针,在这种情况下,将不使用该参数。

base:设定数字的进制,默认是10

leetcode 239 滑动窗口最大值 

一开始用的暴力法差三个用例过不了超时了,这里讲一下我没想到的两种普遍解法

优先队列 

利用优先队列的性质:自动对队列内元素进行排序,排序顺序是从大到小

这样维护优先队列就可以很方便的得出队列内最大的元素

怎么维护优先队列呢?我们需要分两种情况,一种是新加入队列的元素小于原队列内最大元素(此时最大元素已超出左边界),另一种是新加入队列元素大于原队列最大元素(此时也带来另一个问题,弹出元素是新加入元素,这并不是我们想要的)

为了解决这个问题,我们将队列存放元素类型改为键值对,存放数组元素大小和下标,通过判断最大值的下标是否超过边界,超过则弹出,对应第一种情况,不超过则不理会解决第二种情况

每一次窗口移动,都把队列第一个插入到结果数组中

单调队列 

第二种方法详情请看:代码随想录 (programmercarl.com)

个人感觉没有第一种方法好理解,但是效率更高 

简而言之是维护一个从大到小排序的队列,重载pop,push方法,保证队列内元素都是逆序的

push方法:如果插入元素小于队列最后一个元素,正常插入;如果大于,则调用容器自带pop_back()方法将前面所有元素弹出,相当于只剩下新元素

pop方法:弹出值刚好等于队列第一个元素,说明已到达窗口左边界,弹出该元素

每一次移动窗口都将队列第一个元素插入答案数组

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值