LeetCodeHot100| 438.找到字符串中所有字符异位次、和为k 的子数组
438.找到字符串中所有字符异位次
给定两个字符串 s 和 p,找到 s 中所有 p 的 异位词 的子串,返回这些子串的起始索引。不考虑答案输出的顺序。
示例 1:
输入: s = "cbaebabacd", p = "abc"
输出: [0,6]
解释:
起始索引等于 0 的子串是 "cba", 它是 "abc" 的异位词。
起始索引等于 6 的子串是 "bac", 它是 "abc" 的异位词。
示例 2:
输入: s = "abab", p = "ab"
输出: [0,1,2]
解释:
起始索引等于 0 的子串是 "ab", 它是 "ab" 的异位词。
起始索引等于 1 的子串是 "ba", 它是 "ab" 的异位词。
起始索引等于 2 的子串是 "ab", 它是 "ab" 的异位词。
遇到的问题
- 怎么判断三个字符如何相等?
- 如何判断当前字符是在abc中的一个?
思路分析
因为字符串p的异位词的长度异p相同,所以需要维护一个滑动窗口,在窗口中维护每种字符的数量。
变量 differ 来记录字符串p中数量不同的字母的个数,并且在滑动窗口中维护它
class Solution {
public:vector<int> findAnagrams(string s, string p) {int sLen = s.size(),pLen = p.size(); // 两种字符串的长度分别是// 需要判断的特殊时候if(sLen < pLen) { return Vector<int>(); // 直接返回定义的空向量。}vector<int> ans; // 定义需要返回的向量vector<int> count(26); // 用count记录26个字母for(int i = 0; i < pLen; ++i) {// 遍历整个的长度++count[s[i] - 'a']; //?--count[p[i] - 'a'];// ?}int differ = 0; // 用一个differ来记录窗口与字符串p数量不同的个数,不为0就是不行的if(differ == 0) { ans.emplace_back(0); // ?}// 这里是开始维护一个窗口吗?for (int i = 0; i < sLen - pLen; ++i) {if (count[s[i] - 'a'] == 1) { // 窗口中字母 s[i] 的数量与字符串 p 中的数量从不同变得相同--differ;} else if (count[s[i] - 'a'] == 0) { // 窗口中字母 s[i] 的数量与字符串 p 中的数量从相同变得不同++differ;}--count[s[i] - 'a'];if (count[s[i + pLen] - 'a'] == -1) { // 窗口中字母 s[i+pLen] 的数量与字符串 p 中的数量从不同变得相同--differ;} else if (count[s[i + pLen] - 'a'] == 0) { // 窗口中字母 s[i+pLen] 的数量与字符串 p 中的数量从相同变得不同++differ;}++count[s[i + pLen] - 'a'];if (differ == 0) {ans.emplace_back(i + 1);}}}
};
和为k 的子数组
给你一个整数数组 nums 和一个整数 k ,请你统计并返回 该数组中和为 k 的子数组的个数 。
子数组是数组中元素的连续非空序列。
示例 1:
输入:nums = [1,1,1], k = 2
输出:2
示例 2:
输入:nums = [1,2,3], k = 3
输出:2
遇到的问题
要计算子数组且连续非空?
如何计算连续空间内的啥内容相加?
解题思路
我们建立哈希表 mp,以和为键,出现次数为对应的值,记录字符 pre[i] 为 [0…i] 里所有数的和所出现的次数。
代码
class Solution {
public:int subarraySum(vector<int>& nums, int k) {// 返回统计和为k的子串的数量const int n = nums.size(); // 字符串的大小int count = 0; // 零时的子串的和的统计int arr[n]; // 数字是为啥?for (int i = 0; i < n; i++) { arr[i] = nums[i]; // 第一遍把字符串的值全部赋给数组}for( int start = 0;start < nums.size();++start) { // 这一遍是遍历?int sum = 0;for(int end =start; end >= 0;--end) { // 零时变量end直到变为0sum += arr[end];if(sum == k) { count++;}}}return count; // 最后return这个数值}
};
更简单的方法
class Solution {
public:int subarraySum(vector<int>& nums, int k) {unordered_map<int, int> mp; // 定义一个哈希表键值对mp[0] = 1;int count = 0, pre = 0;for(auto& x:nums) { // 使用自定类型来遍历numspre += x; //pre[i] 为 [0..i] 里所有数的和if(mp.find(pre - k) != mp.end()) { count+= mp[pre - k]; //}mp[pre]++;}return count;}};
