• hot100----字串


    560. 和为 K 的子数组

    给你一个整数数组 nums 和一个整数 k ,请你统计并返回 该数组中和为 k 的连续子数组的个数 。

    子数组是数组中元素的连续非空序列。

    示例 1:
    
    输入:nums = [1,1,1], k = 2
    输出:2
    示例 2:
    
    输入:nums = [1,2,3], k = 3
    输出:2
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    提示:

    1 <= nums.length <= 2 * 104
    -1000 <= nums[i] <= 1000
    -107 <= k <= 107

    public class Solution {
        public int subarraySum(int[] nums, int k) {
            int count = 0, pre = 0;
            HashMap < Integer, Integer > mp = new HashMap < > ();
            mp.put(0, 1);
            for (int i = 0; i < nums.length; i++) {
                pre += nums[i];
                if (mp.containsKey(pre - k)) {
                    count += mp.get(pre - k);
                }
                mp.put(pre, mp.getOrDefault(pre, 0) + 1);
            }
            return count;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    思路:前缀和+哈希

    239. 滑动窗口最大值

    给你一个整数数组 nums,有一个大小为 k 的滑动窗口从数组的最左侧移动到数组的最右侧。你只可以看到在滑动窗口内的 k 个数字。滑动窗口每次只向右移动一位。

    返回 滑动窗口中的最大值

    示例 1:
    
    输入:nums = [1,3,-1,-3,5,3,6,7], k = 3
    输出:[3,3,5,5,6,7]
    解释:
    滑动窗口的位置                最大值
    ---------------               -----
    [1  3  -1] -3  5  3  6  7       3
     1 [3  -1  -3] 5  3  6  7       3
     1  3 [-1  -3  5] 3  6  7       5
     1  3  -1 [-3  5  3] 6  7       5
     1  3  -1  -3 [5  3  6] 7       6
     1  3  -1  -3  5 [3  6  7]      7
    示例 2:
    
    输入:nums = [1], k = 1
    输出:[1]
     
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    提示:

    1 <= nums.length <= 105
    -104 <= nums[i] <= 104
    1 <= k <= nums.length

    public class Solution {
        public int[] maxSlidingWindow(int[] nums, int k) {
            Deque<Integer> deque = new LinkedList<>();
            List<Integer> result = new ArrayList<>();
    
            for (int i = 0; i < nums.length; i++) {
                // 判断队列中的第一个索引是否已经离开当前滑动窗口的范围
                if (!deque.isEmpty() && deque.peekFirst() <= i - k) {
                    deque.pollFirst();
                }
    
                // 删除队列中所有小于当前元素值的索引
                while (!deque.isEmpty() && nums[deque.peekLast()] < nums[i]) {
                    deque.pollLast();
                }
    
                deque.offerLast(i);
    
                // 记录滑动窗口中的最大值
                if (i >= k - 1) {
                    result.add(nums[deque.peekFirst()]);
                }
            }
    
            // 将结果列表转换为数组并返回
            return result.stream().mapToInt(Integer::intValue).toArray();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28

    76. 最小覆盖子串

    给你一个字符串 s 、一个字符串 t 。返回 s 中涵盖 t 所有字符的最小子串。如果 s 中不存在涵盖 t 所有字符的子串,则返回空字符串 “” 。

    注意:

    对于 t 中重复字符,我们寻找的子字符串中该字符数量必须不少于 t 中该字符数量。
    如果 s 中存在这样的子串,我们保证它是唯一的答案。

    示例 1:
    
    输入:s = "ADOBECODEBANC", t = "ABC"
    输出:"BANC"
    解释:最小覆盖子串 "BANC" 包含来自字符串 t 的 'A''B''C'。
    示例 2:
    
    输入:s = "a", t = "a"
    输出:"a"
    解释:整个字符串 s 是最小覆盖子串。
    示例 3:
    
    输入: s = "a", t = "aa"
    输出: ""
    解释: t 中两个字符 'a' 均应包含在 s 的子串中,
    因此没有符合条件的子字符串,返回空字符串。
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    提示:

    m == s.length
    n == t.length
    1 <= m, n <= 105
    s 和 t 由英文字母组成

    进阶:你能设计一个在 o(m+n) 时间内解决此问题的算法吗?

    import java.util.HashMap;
    import java.util.Map;
    
    public class Solution {
        public String minWindow(String s, String t) {
            // 构建 t 的字符频率哈希表
            Map<Character, Integer> targetFreqMap = new HashMap<>();
            for (char c : t.toCharArray()) {
                targetFreqMap.put(c, targetFreqMap.getOrDefault(c, 0) + 1);
            }
            
            int left = 0;         // 左指针
            int right = 0;        // 右指针
            int count = 0;        // 计数器,记录窗口中包含的 t 的字符总数
            int minLength = Integer.MAX_VALUE;  // 最小子串长度
            int minStart = 0;     // 最小子串的起始位置
            
            // 用于记录窗口中字符的频率
            Map<Character, Integer> windowFreqMap = new HashMap<>();
    
            while (right < s.length()) {
                char currChar = s.charAt(right);
                
                // 更新窗口中字符的频率
                windowFreqMap.put(currChar, windowFreqMap.getOrDefault(currChar, 0) + 1);
                
                // 如果当前字符在 t 中存在,并且窗口中该字符的出现次数不超过 t 中的出现次数,则 count 增加 1
                if (targetFreqMap.containsKey(currChar) && windowFreqMap.get(currChar) <= targetFreqMap.get(currChar)) {
                    count++;
                }
                
                // 窗口包含了 t 的所有字符
                while (count == t.length()) {
                    // 更新最小子串长度和起始位置
                    if (right - left + 1 < minLength) {
                        minLength = right - left + 1;
                        minStart = left;
                    }
                    
                    char leftChar = s.charAt(left);
                    
                    // 移动左指针,缩小窗口
                    if (targetFreqMap.containsKey(leftChar) && windowFreqMap.get(leftChar) <= targetFreqMap.get(leftChar)) {
                        count--;
                    }
                    
                    windowFreqMap.put(leftChar, windowFreqMap.getOrDefault(leftChar, 0) - 1);
                    
                    left++;
                }
                
                right++;
            }
            
            if (minLength == Integer.MAX_VALUE) {
                return "";
            } else {
                return s.substring(minStart, minStart + minLength);
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
  • 相关阅读:
    SQL注入的原理分析
    百度地图数据可视化
    Vega Prime入门教程12.10:DevToolCRO与部署
    Prometheus安装部署和Exporter集成
    spring复习02,xml配置管理bean
    彩虹女神跃长空,Go语言进阶之Go语言高性能Web框架Iris项目实战-用户系统EP03
    医学分析专业名词解释
    【深度学习21天学习挑战赛】4、初尝循环神经网络(RNN)——股票预测
    windows jdk 11.0.21版本安装配置
    [Java、Android面试]_19_单例模式(高频问题)
  • 原文地址:https://blog.csdn.net/qq_57818853/article/details/133303824