[Leetcode学习-java]Find All Anagrams in a String(获取所有异序词)

问题:

难度:easy

说明:

输入字符串s,p,然后在s中查找所有符合p的异序词,返回异序词开头索引。

输入案例:

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".

我的代码:

首先想到就是把p的字符记录到hashmap里面,然后每次进来一个就减去1,完成了之后就添加开头index,否则进行下一个,然后hashmap里面的数据都要复位,但是代码跑了600多ms。

public List<Integer> findAnagrams2(String s, String p) {
            int len = s.length();
            char[] sc = s.toCharArray();

            int plen = p.length();
            char[] pc = p.toCharArray();
            int[] map = new int[26];
            List<Integer> findList = new ArrayList<Integer>();

            // 放hashmap
            for(int i = 0;i < plen;i ++) {
                map[pc[i] - 'a'] ++;
            }


            for(int i = 0;i < len;i ++) {
                if(p.indexOf(sc[i]) != -1) {
                    // 每次需要重新拿一个数组
                    int[] temp = Arrays.copyOf(map, 26);
                    int index = 0;

                    // 连续查找
                    for(int j = i;j < len;j ++) {
                        int ji = sc[j] - 'a';
                        // 发现不适合就跳出
                        if(temp[ji] == 0) break;
                        temp[ji] --;
                        index ++;

                        // 如果发现连续长度已经足够,就添加
                        if(index == plen) {
                            findList.add(i);
                        }
                    }
                }
            }

            return findList;
        }

其它代码:

滑动窗口代码,这个真的好多了,时间复杂度就On:

public List<Integer> findAnagrams(String s, String p) {
    List<Integer> res = new ArrayList<>();
    // 双指针
    int left=0;
    int right=0;

    int[] counts = new int[128];
    // 放入hashmap进行统计
    for(char x: p.toCharArray()){
        counts[x] ++;
    }

    // left会根据right移动到不存在的点而移动
    // 并且left作为开头,让right和left的区间锁定适合p的乱序字符
    // -1就是不存在,然后left会移动并且填补(就是+1的意思)
    while(right<s.length()){
        counts[s.charAt(right)] --;
        while(counts[s.charAt(right)] < 0){
            counts[s.charAt(left ++)] ++;
        }
        right ++;
        if(right-left==p.length())res.add(left);
    }
    return res;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值