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方法:弹出值刚好等于队列第一个元素,说明已到达窗口左边界,弹出该元素
每一次移动窗口都将队列第一个元素插入答案数组