zoukankan      html  css  js  c++  java
  • LeetCode——字符串的排列/找到字符串中所有字母异位词

    Q:给定两个字符串 s1 和 s2,写一个函数来判断 s2 是否包含 s1 的排列。
    换句话说,第一个字符串的排列之一是第二个字符串的子串。

    示例1:
    输入: s1 = "ab" s2 = "eidbaooo"
    输出: True
    解释: s2 包含 s1 的排列之一 ("ba").
    示例2:
    输入: s1= "ab" s2 = "eidboaoo"
    输出: False

    注意:
    输入的字符串只包含小写字母
    两个字符串的长度都在 [1, 10,000] 之间

    A:
    滑动窗口(不过我把代码的s1和s2写反了,原理没错)

    public boolean checkInclusion(String s1, String s2) {
            if (s1.length() == 0)
                return s2.length() == 0;
            if (s2.length() == 0)
                return true;
            if (s1.length() < s2.length())
                return false;
            Map<Character, Integer> window = new HashMap<>();
            Map<Character, Integer> needs = new HashMap<>();
            for (int i = 0; i < s2.length(); i++) {
                if (needs.containsKey(s2.charAt(i))) {
                    needs.put(s2.charAt(i), needs.get(s2.charAt(i)) + 1);
                } else {
                    needs.put(s2.charAt(i), 1);
                }
            }
            int count = needs.size();//符合的大小数目
            int left = 0, right = 0;
            while (right < s1.length()) {
                //先处理右指针
                char curr = s1.charAt(right);
                if (needs.containsKey(curr)) {
                    if (window.containsKey(curr)) {
                        window.put(curr, window.get(curr) + 1);
                    } else {
                        window.put(curr, 1);
                    }
                    if (window.get(curr).equals(needs.get(curr))) {
                        count--;
                    }
                }
                right++;
                //再处理左指针
                while (right - left > s2.length()) {
                    char l = s1.charAt(left);
                    if (window.containsKey(l)) {
                        //左指针在处理前是满足相等的,要把这个数组加回去
                        if (window.get(l).equals(needs.get(l))) {
                            count++;
                        }
                        window.put(l, window.get(l) - 1);
                    }
                    left++;
                }
                //左右指针处理完了,此时count=0,返回true
                if (count == 0)
                    return true;
            }
            return false;
        }
    

    Q:给定一个字符串 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" 的字母异位词。

    A:

        public List<Integer> findAnagrams(String s, String p) {
            List<Integer> array = new ArrayList<>();
            if (s.length() == 0 || p.length() == 0 || s.length() < p.length())
                return array;
            int left = 0, right = 0;
            Map<Character, Integer> need = new HashMap<>();
            Map<Character, Integer> window = new HashMap<>();
            for (int i = 0; i < p.length(); i++) {
                if (need.containsKey(p.charAt(i))) {
                    need.put(p.charAt(i), need.get(p.charAt(i)) + 1);
                } else {
                    need.put(p.charAt(i), 1);
                }
            }
            int count = need.size();
            while(right < s.length()){
                char r = s.charAt(right);
                if(need.containsKey(r)){
                    if(window.containsKey(r)){
                        window.put(r,window.get(r)+1);
                    }else{
                        window.put(r,1);
                    }
                    if(window.get(r).equals(need.get(r))){
                        count--;
                    }
                }
                right++;
                while(right-left>p.length()){
                    char l = s.charAt(left);
                    if(window.containsKey(l)){
                        if(window.get(l).equals(need.get(l))){
                            count++;
                        }
                        window.put(l, window.get(l) - 1);
                    }
                    left++;
                }
                if(count == 0){
                    array.add(left);
                }
            }
            return array;
        }
    
  • 相关阅读:
    支付宝-单笔转账接口
    # Creating Server TCP listening socket *:6379: bind: No such file or directory
    Window 下安装 Redis,配置redis环境变量
    Ajax的跨域(一)
    web人脸识别(二)
    web人脸识别(一)
    给GridView添加列头复选框
    计算两个时间相差多少年月日的sql算法
    MUI下拉加载安卓手机无效的解决方法
    博主回来了!
  • 原文地址:https://www.cnblogs.com/xym4869/p/12750775.html
Copyright © 2011-2022 走看看