[leetcode] 438. Find All Anagrams in a String

Description

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的变体(字符串序可以不一样,字符一样)的位置。

首先统计字符串p中字符出现的次数,然后从s的开头开始,每次找p字符串长度个字符,来验证字符个数是否相同,如果不相同出现了直接break,如果一直都相同了,则将起始位置加入结果res中

  • 这算是暴力破解的一个题目了,一看到字符串的题目,如果不考虑顺序,hash表是一个常用的方法。

C++

class Solution {
public:
    vector<int> findAnagrams(string s, string p) {
        if(s.empty()) return {};
        vector<int> result;
        vector<int> cnt(128,0);
        for(char c:p){
            cnt[c]++;
        }
        for(int i=0;i<s.size();i++){
            vector<int> temp=cnt;
            bool success=true;
            for(int j=i;j<i+p.size();j++){
                if(temp[s[j]]>0){
                    temp[s[j]]--;
                }else{
                    success=false;
                    break;
                }
            }
            if(success){
                result.push_back(i);
            }
        }
        return result;
    }
};

Python

滑动窗口+Counter简直是绝了,比我当时一个一个遍历(超时)的去判断好多了。

class Solution:
    def findAnagrams(self, s: str, p: str) -> List[int]:
        # Counter count, sliding_window
        p_counter = Counter(p)
        window_counter = Counter(s[:len(p)])
        res = []
        for i in range(len(s)-len(p)+1):
            if p_counter==window_counter:
                res.append(i)
            window_counter[s[i]]-=1
            if window_counter[s[i]]==0:
                del window_counter[s[i]]
            if i+len(p)<len(s):
                window_counter[s[i+len(p)]]+=1
        return res

或者下面的写法也是可以的:

class Solution:
    def findAnagrams(self, s: str, p: str) -> List[int]:
        p_counter = Counter(p)
        window_counter = Counter(s[:len(p)])
        res = []
        if p_counter==window_counter:
            res.append(0)
        for i in range(len(p),len(s)):
            window_counter[s[i]]+=1
            window_counter[s[i-len(p)]]-=1
            if window_counter[s[i-len(p)]]==0:
                del window_counter[s[i-len(p)]]
            if window_counter==p_counter:
                res.append(i-len(p)+1)
        return res

参考文献

[LeetCode] Find All Anagrams in a String 找出字符串中所有的变位词

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

农民小飞侠

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值