标签:int asc ram 个数 which exp 迭代 循环 mat
Given a string s and a non-empty string p, find all the start indices of p‘s anagrams in s.
Strings consists of lowercase English letters only and the length of both strings s and p will not be larger than 20,100.
The order of output does not matter.
Example 1:
Input: s: "cbaebabacd" p: "abc" Output: [0, 6] Explanation: The substring with start index = 0 is "cba", which is an anagram of "abc". The substring with start index = 6 is "bac", which is an anagram of "abc".
Example 2:
Input: s: "abab" p: "ab" Output: [0, 1, 2] Explanation: The substring with start index = 0 is "ab", which is an anagram of "ab". The substring with start index = 1 is "ba", which is an anagram of "ab". The substring with start index = 2 is "ab", which is an anagram of "ab".
找出字符串中的所有变位词的头索引,给定两个字符串s和p,在s中找出p的所有变位词的头索引。
思路:用一维数组cnt存储p的所有字符及其出现次数(因为字符由ASCII码组成,所以申请一个大小为128的vector即可,用vector的索引值代表字符,vector的元素值代表字符出现次数),然后开始遍历s的每一位的同时遍历p,这时需要重新申请一个临时数组tmp来代替cnt,并对tmp的 值进行操作(访问过p的值后并让tmp的值减1)。最后将符合条件的头索引放入结果数组res中即可。
这是一个蛮力迭代算法,优点是思路清晰,缺点是所用的时间复杂度较高。O(s * p)
class Solution { public: vector<int> findAnagrams(string s, string p) { if (s.empty()) return {}; vector<int> res, cnt(128, 0); int sn = s.size(), pn = p.size(), i = 0; for (char c : p) cnt[c]++; while (i < sn) { bool success = true; vector<int> tmp = cnt; for (int j = i; j < i + pn; j++) { if (tmp[s[j]]-- <= 0) { success = false; break; } } if (success) res.push_back(i); i++; } return res; } }; // 543 ms
通过上面的思路,很容易想到这是一个滑动窗口模型。
首先建立一个哈希表m统计p中字符出现的次数。使用left和right表示滑动窗口的左右边界,cnt表示字符串p中需要匹配的字符个数。然后开始循环
如果右边界字符已经在m中,说明该字符在p中出现,令cnt减1,然后m中该字符出现的次数也减1,右边界加1。
如果此时cnt为0,则说明p中的字符都匹配成功,将左边界放入结果数组中。
如果此时right与left之差等于p的长度, 说明此时应该去掉最左边的字符,如果这个字符在m中出现次数大于等于0,说明该字符是p中的字符。所以令cnt加1。
class Solution { public: vector<int> findAnagrams(string s, string p) { if (s.empty()) return {}; vector<int> res, m(128, 0); int left = 0, right = 0, cnt = p.size(), n = s.size(); for (char c : p) m[c]++; while (right < n) { if (m[s[right++]]-- >= 1) cnt--; if (cnt == 0) res.push_back(left); if (right - left == p.size() && m[s[left++]]++ >= 0) cnt++; } return res; } }; // 33 ms
[LeetCode] Find All Anagrams in a String
标签:int asc ram 个数 which exp 迭代 循环 mat
原文地址:http://www.cnblogs.com/immjc/p/7655353.html