十六白银——滑动窗口经典问题

3. 无重复字符的最长子串 - 力扣(LeetCode)

这里黑马的赋值没有讲清楚   所以附上一些基本语法

1. 构造
定义一个map需要指定键值类型:
map<KeyType, ValueType> map;
KeyType和ValueType可以是任意有效类型。
2. 赋值
向map插入元素使用数组语法:
map[key] = value;
如果key不存在,会插入一个新的键值对。
如果key存在,会覆盖原有的值。
3. 键的要求
- key必须是可赋值和可复制的。
- key通常需要实现 operator< 用于排序。
- key不能修改,否则会破坏map的排序。
4. 值的要求
- 值可以是任意类型,可以修改。
- 插入相同键的不同值类型会导致编译错误。
5. 其他操作
- 检查键是否存在: count(key)
- 删除键值对: erase(key)
- 清空所有元素: clear()
- 迭代遍历所有键值对:for(auto& kv : map)
6. unordered_map
unordered_map的用法与map基本一致,但不需要排序,允许键修改。
遍历顺序不确定。
以上是C++ map和unordered_map的基本用法。让我知道如果需要补充解释哪些部分。

为什么left = std::max(left, map[s[right]] + 1);?需要这个max??

map[s[right]] = right;这一步是等于更新right的值   然后再去计算最大的长度

当第二次遇到a时,我们就更新left成为第一个b所在的位置,此时惊奇的发现left要移动的位置恰好就是map.get(’a‘) + 1=1,我们将'a'用序列来表示,放在一起就是map.get(s.charAt(i)) + 1。这句话是if条件判断里面的核心依据。

leetcode159

首先我们必须知道  hashmap的规则是同一个value对应同一个key   也就是说  只有只有新的字符串加入的时候,hash map才会增加。这也就对应了代码中的if hash map.size小于3的情况。

为什么else后面的那个是带星号的呢?

hashmap 是 unordered_map<char, int>,它存储的是字符到其出现索引的映射。
min_element 函数的作用是找到容器中最小的元素。
但是这里我们需要找到的是 hashmap 中最小的索引,也就是最早出现的字符的索引。
unordered_map 在遍历时返回的是 pair<char, int>,其中第一个元素是键,第二个元素才是值。
所以直接调用 min_element 会返回一个 pair。
而我们需要的值是这个 pair 的第二个元素,也就是索引。
为了获取 pair 中的第二个元素,需要加上星号操作符:*
int del_idx = *min_element(hashmap.begin(), hashmap.end());
这里的*作用就是取出 min_element 返回的 pair 中的值部分,也就是最小的索引。
加上*之后,del_idx 就获取到了 hashmap 中最小索引对应的字符,这样就可以删除最早出现的字符,保证窗口内最多只有 2 个不同的字符。
所以这里使用 * 解引用操作符是为了从 pair 对象中取出我们需要的索引值。

209. 长度最小的子数组 - 力扣(LeetCode)

567. 字符串的排列 - 力扣(LeetCode)

结合题解的动画来看 会好懂很多

上述代码中  for (int i = 0; i < n; ++i) {
            ++cnt1[s1[i] - 'a'];
            ++cnt2[s2[i] - 'a'];
        }是什么意思?涉及到了什么基本语法?

Claude
应用  3 小时前
这段代码是在统计两个字符串s1和s2中的字符出现次数,使用数组 cnt1 和 cnt2 来记录每个字符出现的次数。
for 循环的作用是初始化统计数组 cnt1 和 cnt2。
具体来看:
1. cnt1[s1[i] - 'a'] 表示获取字符串s1中第i个字符,并将其转换为数组下标。因为直接获取字符会返回ASCII码,而我们需要换成数组下标,所以要减去 'a' 的ASCII码,使其对应的是a-z的下标区间。
2. ++cnt1[s1[i] - 'a'] 对响应下标位置加1,表示记录对应字符出现次数。
3. cnt2数组使用同样的方式处理字符串s2。
所以这段代码使用了两个数组 cnt1 和 cnt2 分别统计了字符串 s1 和 s2 中每个字符出现的次数。
涉及到的基本语法知识有:
1. 数组作为统计字符出现次数的统计表
2. s[i]获取字符串的第i个字符
3. 将字符转换为数值进行统计,这里使用了字符对应的ASCII码
4. ++数组下标实现对特定字符出现次数的统计
5. for循环遍历字符串进行统计
综上,这段代码巧妙利用了数组和ASCII码对应关系来统计字符出现频次,涉及到字符串、数组、循环等基本语法的应用。 (已编辑) 


xiong gavin
  3 小时前

 能详细讲讲++cnt1[s1[i] - 'a']涉及到的基本语法吗?


好的,关于 ++cnt1[s1[i] - 'a'] 这一语句涉及的基本语法知识,我来详细解释一下:
1. cnt1是一个数组,用于统计字符串s1中每个字符出现的次数。
2. s1[i] 表示访问字符串s1的第i个字符。字符串可以像数组一样通过下标索引访问每个字符。
3. 'a' 是一个字符常量,表示字母a。字符常量的值就是该字符对应的ASCII码值,这里'a'的值是97。
4. s1[i] - 'a' 对两个字符进行相减运算,由于字符有对应的ASCII码,所以相当于求两个ASCII码值的差。因为a-z对应的ASCII码是连续的,所以这个差值刚好就是目标字符相对于a的序号。
5. cnt1[s1[i] - 'a'] 利用上述差值作为下标访问数组cnt1。由于cnt1数组大小是26,刚好与a-z的个数对应。因此任一小写字母作为下标都可以访问cnt1的对应元素。
6. ++cnt1[s1[i] - 'a'] 对数组cnt1的指定元素进行++操作,将对应字符的统计数加1。这样就可以统计字符串中每个字符出现的次数。
所以++cnt1[s1[i] - 'a']通过字符到ASCII码到数组下标的转换,巧妙地利用了数组来统计字符串中字符出现的频次。整个语句涉及到了字符串、数组、字符与ASCII码之间的关系等基本语法知识。 (已编辑) 


xiong gavin
  3 小时前
@Claude
那for (int i = n; i < m; ++i) {
            ++cnt2[s2[i] - 'a'];
            --cnt2[s2[i - n] - 'a'];
            if (cnt1 == cnt2) {
                return true;
            }
        }又是什么意思?


这段代码的作用是实现滑动窗口,在字符串s2中检查是否存在和s1字符相同的长度为n的子串。
具体来看:
1. i从n开始遍历,因为前n个字符已经统计过了,现在要开始滑动窗口。
2. ++cnt2[s2[i] - 'a'] 对应将新进入窗口的字符s2[i]统计次数加1。
3. --cnt2[s2[i - n] - 'a'] 对应将离开窗口的字符s2[i-n]统计次数减1。
4. cnt1 == cnt2 检查当前滑动窗口字符统计是否与s1相同。
5. 如果相同,直接返回true。
6. 窗口滑动过程不断重复上述操作。
所以这段代码通过滑动窗口和字符统计数组的配合,巧妙实现了在s2中检查是否存在和s1字符组成相同的长度为n的子串。
整段代码显示了滑动窗口算法与数据结构设计的综合应用和配合,是一段程序设计很棒的代码。

438. 找到字符串中所有字母异位词 - 力扣(LeetCode)

这个代码讲解很不错

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值