首页 > 其他分享 >找到字符串中所有字母异位词

找到字符串中所有字母异位词

时间:2024-02-04 23:12:00浏览次数:35  
标签:子串 count ab 异位 字母 字符串

问题描述:给定一个字符串 s 和一个非空字符串 p,找到 s 中所有是 p 的字母异位词的子串,返回这些子串的起始索引。字符串只包含小写英文字母,并且字符串 s 和 p 的长度都不超过 20100。

说明:字母异位词指字母相同,但排列不同的字符串。不考虑答案输出的顺序。

示例 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" 的字母异位词。

//思路一:固定该滑动窗口大小,逐步平移该窗口
class Solution {
    public List<Integer> findAnagrams(String s, String p) {
        List<Integer> res = new ArrayList<>();

        int l = 0;
        int r = p.length();
        //[l,r) 范围内字符,组成字符串

        while (r<=s.length()){
            String newP = s.substring(l,r);
            if(isAnagram(newP,p)){
                res.add(l);
            }
            l++;
            r++;
        }
        return res;
    }

   //判断两个字符串是否是Anagram
   //先判断长度是否相同,不相同,直接返回false
   //统计 s1字符串中每个小写字母出现的频率,根据s2是否出现相同的字母以及出现的字母的频率是否相同
    private boolean isAnagram(String word1,String word2){
        if(word1.length() != word2.length()){
            return false;
        }

        int[] freq = new int[26];

        for(int i=0;i<word1.length();i++){
            freq[word1.charAt(i)-'a']++;
        }

        for(int i=0;i<word2.length();i++){
            char c = word2.charAt(i);
            if(freq[c-'a']==0){
                // word1 不包括字符 c,但是 word2 包括,则 word1 和 word2 必然不是字母异位词
                return false;
            }
            freq[c-'a']--;
        }
        return true;
    }
}

class Solution {
    public List<Integer> findAnagrams(String s, String p) {
        List<Integer> ret = new ArrayList<>();
        if (s == null || s == "") {
            return ret;
        }
        //统计字符串p中出现的小写字符的频率
        int[] pFreq=new int[256];
        //count是p中的字符数
        int count=p.length();
    
        for(int i=0;i<count;i++){
            pFreq[p.charAt(i)]++;
        }
        int l=0,r=0;
        //[l,r)表示滑动窗口
        while(r<s.length()){
            if(pFreq[s.charAt(r++)]-->=1){
                //每次有一个p中字符进入窗口,扩展窗口,并且count–1
                count--;
            }
            if(count==0){
                //当count == 0的时候,表明我们的窗口中包含了p中的全部字符,得到一个结果。
                ret.add(l);
            }
    
            if (r-l == p.length()) {
                //当窗口包含一个结果以后,为了进一步遍历,我们需要缩小窗口使窗口不再包含全部的p,
                //同样,如果pFreq[char]>=0,表明一个在p中的字符就要从窗口移动到p字符串中,那么count ++
                if (pFreq[s.charAt(l++)]++ >= 0) {
                    count++;   // one more needed to match
                }
            }
        }
        return ret;
    }
}

参考:

标签:子串,count,ab,异位,字母,字符串
From: https://www.cnblogs.com/i9code/p/18007193

相关文章

  • Java 运算符详解与字符串处理技巧
    Java运算符算术运算符算术运算符用于执行常见的数学运算。运算符名称描述示例+加法将两个值相加x+y-减法从一个值中减去另一个值x-y*乘法将两个值相乘x*y/除法将一个值除以另一个值x/y%取模返回除法余数x%y++自增将变量......
  • 代码随想录算法训练营第十一天 | 20. 有效的括号 | 1047. 删除字符串中的所有相邻重
     有效的括号 已解答简单 相关标签相关企业 提示 给定一个只包括 '(',')','{','}','[',']' 的字符串 s ,判断字符串是否有效。有效字符串需满足:左括号必须用相同类型的右括号闭合。左括号必须以正确的顺序闭合。每个右括号都有一个对应......
  • 【DM】根据指定字符分割字符串,返回表
    一、创建记录CREATEORREPLACETYPETYPE_ROW_SPLITSTRASOBJECT(idINT,valNVARCHAR(500));二、创建嵌套表CREATEORREPLACETYPETYPE_TABLE_SPLITSTRisTABLEOFTYPE_ROW_SPLITSTR;三、自定义函数CREATEORREPLACEFUNCTIONsplitTable(strvalINTEXT......
  • 【DM】自定义存储函数(返回字符在字符串中所在位置的下标字符串)
    一、使用while语法--输入:原字符串,查找的字符,分割字符--输出:所在位置下标集合(用输入的分割字符分割)CREATEORREPLACEFUNCTIONdF_strPosition(strInputINVARCHAR(100),strFindinputINVARCHAR(2),strSplitINVARCHAR(2))RETURNVARCHAR(128)ASstrVal......
  • 【DM】判断两个逗号分隔的字符串参数是否存在交集
     CREATEORREPLACEFUNCTIONSIGN_INTERSECTION(V_TAG1VARCHAR2,V_TAG2VARCHAR2)RETURNINTEGERISBEGINIFV_TAG1ISNULLORV_TAG2ISNULLORV_TAG1=''ORV_TAG2=''THENRETURN1;ENDIF;--去掉前缀和尾随逗号V_TAG2......
  • 【学习笔记】字符串
    1.KMP【模板】KMP朴素的比对是如下的:for(inti=0;i<a.size()-b.size();i++){ for(intj=0;j<b.size();j++){ if(a[i+j]!=b[j])break; if(j==b.size()-1)cout<<i<<''; }}设A串长度\(n\),B串长度\(m\),显然这么做是\(O(nm)\)的。很容易想到一个错误优化:如果失......
  • Problem P06. [算法课分治] 找到 k 个最长重复字符串
    注意是在该子字符串内每个字符的出现次数都不少于k。可以采用分治的方法,函数找一个不符合条件的字符,然后将字符串分成两个子字符串,就这样进行递归运算,每次找到符合条件的子字符串就判断一波长度,然后将最长的长度值存下来。#include<iostream>#include<bits/stdc++.h>#includ......
  • 通过删除字母匹配到字典里最长单词
    问题描述:给定一个字符串和一个字符串字典,找到字典里面最长的字符串,该字符串可以通过删除给定字符串的某些字符来得到。如果答案不止一个,返回长度最长且字典顺序最小的字符串。如果答案不存在,则返回空字符串。示例1:输入:s="abpcplea",d=["ale","apple","monkey","plea"]......
  • 验证回文字符串
    问题描述:给定一个非空字符串s,最多删除一个字符。判断是否能成为回文字符串。示例1:输入:"aba"输出:True示例2:输入:"abca"输出:True解释:你可以删除c字符。注意:字符串只包含从a-z的小写字母。字符串的最大长度是50000。publicbooleanvalidPalindrome(St......
  • 反转字符串中元音字母
    问题描述:编写一个函数,以字符串作为输入,反转该字符串中的元音字母。示例1:输入:"hello"输出:"holle"示例2:输入:"leetcode"输出:"leotcede"classSolution{publicStringreverseVowels(Strings){if(s.length()<=1){return......