子串字谜substring anagrams

[抄题]:

给定一个字符串 s 和一个 非空字符串 p ,找到在 s 中所有关于 p 的字谜的起始索引。
字符串仅由小写英文字母组成,字符串 s 和 p 的长度不得大于 40,000。
输出顺序无关紧要.

样例

给出字符串 s = "cbaebabacd" p = "abc"
返回 [0, 6]

子串起始索引 index = 0 是 "cba",是"abc"的字谜.
子串起始索引 index = 6 是 "bac",是"abc"的字谜.

 [暴力解法]:

时间分析:

空间分析:

[思维问题]:

[一句话思路]:

先初始化,再统计p位之后的绝对值之和。

[输入量]:空: 正常情况:特大:特小:程序里处理到的特殊情况:异常情况(不合法不合理的输入):

[画图]:

sliding window的原理是数数字,向右滑动时,count(r)++,count(l)--

[一刷]:

  1. 字符串处理一个个的字母时,要用.tochararray先把字符串转成数组
  2. det也是数组,absSum是其的绝对值求和
  3. det 有几个元素算几个,用for (int item : det)简写
  4. s.toCharArray();表示对方法的调用
  5. list一定要用linkedlist or arraylist来实现,不能直接复制粘贴

[二刷]:

  1. 特殊判断必须要写
  2. 搞清楚det的含义 = sc - pc pc增加,det = r - l r增加
  3. 在之后的数组中,都是计算cntS[] 数组的数量
  4. absSum要用Math.abs

[三刷]:

[四刷]:

[五刷]:

  [五分钟肉眼debug的结果]:

[总结]:

根据表格进行联想

[复杂度]:Time complexity: O(n) Space complexity: O(n)

[英文数据结构或算法,为什么不用别的数据结构或算法]:

[其他解法]:

[Follow Up]:

[LC给出的题目变变变]:

242. Valid Anagram 用deta求absSum

567. Permutation in String 两根指针?不懂

 [代码风格] :

  1. cntS 才符合骆驼命名法
public class Solution {
    /**
     * @param s: a string
     * @param p: a string
     * @return: a list of index
     */
    public List<Integer> findAnagrams(String s, String p) {
        //initialization
        List<Integer> ans = new LinkedList<>();
         //corner case
        if (s.length() < p.length()) {
            return ans;
        }
        char[] sc = s.toCharArray();
        char[] pc = p.toCharArray();
        
        int[] cntS = new int[256];
        int[] cntP = new int[256];
        int[] det = new int[256];
        //count first
        int absSum = 0;
        for (int i = 0; i < p.length(); i++) {
            cntS[sc[i]]++;
            cntP[pc[i]]++;
            
            det[sc[i]]++;
            det[pc[i]]--;
        }
        for (int item : det) {
            absSum += Math.abs(item);
        }
        if (absSum == 0) {
            ans.add(0);
        }
        //count rest
        for (int i = p.length(); i < s.length(); i++) {
            int r = sc[i];
            int l = sc[i - p.length()];
            System.out.println("sc[i]="+sc[i]);
            System.out.println("r="+r);
            
            cntS[r]++;//both s
            cntS[l]--;
            
            absSum = absSum - Math.abs(det[r]) - Math.abs(det[l]);//abs
            
            det[l]--;
            det[r]++;
            
            absSum = absSum + Math.abs(det[r]) + Math.abs(det[l]);
            
            if (absSum == 0) {
                ans.add(i - p.length() + 1);
            }
        }
        return ans;
    }
}
View Code

 

转载于:https://www.cnblogs.com/immiao0319/p/8450432.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值