hot100 |四、子串

1-leetcode560. 和为 K 的子数组

注意:×

  1. 暴力法很简单,下文是前缀和+HashMap的方式解决
  2. 注意要在遍历之前添加0-1这个K-V对
    public int subarraySum(int[] nums, int k) {
        HashMap<Integer, Integer> hashMap = new HashMap<>();
        int preSum = 0;
        int res = 0;
        //一定要添加0-1这个K-V对
        hashMap.put(0,1);

        for (int num : nums) {
            preSum = preSum + num;

            if (hashMap.containsKey(preSum - k)){
                res = res + hashMap.get(preSum - k);
            }

            hashMap.put(preSum, hashMap.getOrDefault(preSum, 0) + 1);
        }
        return res;
    }

2-leetcode239. 滑动窗口最大值

注意:×-错在LinkedList超时

  1. 写这道题前 可以先写一下lc155题的最小栈,因为栈的章节比较靠后,为此直接将lc155的答案放在这个题解的后方粘贴
  2. maxSlidingWindow函数中一定要注意使用的是ArrayList不然就超时报错了
  3. 155的最小栈知道处理的逻辑就很清晰了
// lc239. 滑动窗口最大值
    public int[] maxSlidingWindow(int[] nums, int k) {
        MaxQueue maxQueue = new MaxQueue();
        List<Integer> res = new ArrayList<>();
        for (int i = 0; i < nums.length; i++) {
            if (i<k-1){
                maxQueue.push(nums[i]);
            }else {
                maxQueue.push(nums[i]);
                res.add(maxQueue.getMax());
                maxQueue.pop(nums[i-k+1]);
            }
        }
        int[] arr = new int[res.size()];
        for (int i = 0; i < res.size(); i++) {
            arr[i] = res.get(i);
        }
        return arr;
    }


    class MaxQueue{
        private LinkedList<Integer> queue = new LinkedList<>();

        void push(int num){
            while (!queue.isEmpty() && queue.getLast() < num){
                queue.pollLast();
            }
            queue.addLast(num);
        }

        void pop(int num){
            if (num == queue.getFirst()){
                queue.pollFirst();
            }
        }

        int getMax(){
            return queue.getFirst();
        }

    }

// lc155. 最小栈
    class MinStack {
        private Stack<Integer> trueStack = new Stack<>();
        private Stack<Integer> minStack = new Stack<>();

        public MinStack() {

        }

        public void push(int val) {
            trueStack.push(val);
            if (minStack.isEmpty()){
                minStack.push(val);
            }else {
                if (minStack.peek() > val){
                    minStack.push(val);
                }else {
                    minStack.push(minStack.peek());
                }
            }
        }

        public void pop() {
            trueStack.pop();
            minStack.pop();
        }

        public int top() {
            return trueStack.peek();
        }

        public int getMin() {
            return minStack.peek();
        }
    }

3-leetcode76. 最小覆盖子串

注意:×√

  1. 还是看了一眼答案的
  2. 注意不要再使用string.toCharArray()[index]了,这样会导致超时,直接使用string.charAt(index)就不会超时了
    public String minWindow(String s, String t) {
        HashMap<Character, Integer> window = new HashMap<>();
        HashMap<Character, Integer> need = new HashMap<>();

        for (char c : t.toCharArray()) {
            need.put(c, need.getOrDefault(c, 0) + 1);
        }

        int left = 0, right = 0, valid = 0;
        int start = 0, len = Integer.MAX_VALUE;
        while (right < s.length()) {
            char c = s.charAt(right);
            right++;

            if (need.containsKey(c)) {
                window.put(c, window.getOrDefault(c, 0) + 1);
                if (window.get(c).equals(need.get(c))) {
                    valid++;
                }
            }

            while (valid == need.size()) {
                if (right - left < len) {
                    start = left;
                    len = right - left;
                }
                char d = s.charAt(left);
                left++;

                if (need.containsKey(d)) {
                    if (window.get(d).equals(need.get(d))) {
                        valid--;
                    }
                    window.put(d, window.get(d) - 1);
                }
            }
        }

        return len == Integer.MAX_VALUE ? "" : s.substring(start, start + len);
    }
  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值