数组06-滑动窗口

目录

LeetCode——209. 长度最小的子数组

分析:

LeetCode——844. 比较含退格的字符串

分析:


LeetCode——209. 长度最小的子数组

给定一个含有 n 个正整数的数组和一个正整数 target

找出该数组中满足其总和大于等于 target 的长度最小的 连续子数组 [numsl, numsl+1, ..., numsr-1, numsr] ,并返回其长度如果不存在符合条件的子数组,返回 0

示例 1:

输入:target = 7, nums = [2,3,1,2,4,3]
输出:2
解释:子数组 [4,3] 是该条件下的长度最小的子数组。

示例 2:

输入:target = 4, nums = [1,4,4]
输出:1

示例 3:

输入:target = 11, nums = [1,1,1,1,1,1,1,1]
输出:0

提示:

  • 1 <= target <= 109

  • 1 <= nums.length <= 105

  • 1 <= nums[i] <= 105

分析:

解法一:暴力破解 嵌套循环递归更新最小子数组长度。

class Solution {
    public int minSubArrayLen(int target, int[] nums) {
        int n = nums.length;
        int res = Integer.MAX_VALUE;
        for (int i = 0; i < n; i++) {
            int sum = 0;
            for (int j = i; j < n; j++) {
                sum += nums[j];
                if (sum >= target) {
                    res = Math.min(res, j - i + 1);
                    break;
                }
            }
        }
        return res == Integer.MAX_VALUE ? 0 : res;
    }
}
  • 时间复杂度:O(n^2)

  • 空间复杂度:O(1)

意料之中的超时了...

数组06-滑动窗口_第1张图片

解法二:双指针中的滑动窗口 适用于求子串长度的场景。

滑动窗口:定义一个start指针和end指针表示长度为end-start+1的窗口,起始位置都为0.

随着end向右滑动,获得第一个满足要求的窗口sum>=target,记录比较窗口长度取较小的值。

此时需要移动start指针,直到窗口内的元素不满足sum>target。

进行迭代,直到end指针指向数组最后一位。

Code

class Solution {
    public int minSubArrayLen(int target, int[] nums) {
        int res = Integer.MAX_VALUE;
        int l = 0;
        int r = 0;
        int sum = 0;
        while (r < nums.length) {
            sum += nums[r];
            while (sum >= target) {
                res = Math.min(res, r - l + 1);
                sum -= nums[l];
                l++;
            }
            r++;
        }
        return res == Integer.MAX_VALUE? 0 : res;
    }
}
  • 时间复杂度:O(n)

  • 空间复杂度:O(1)

LeetCode——844. 比较含退格的字符串

给定 st 两个字符串,当它们分别被输入到空白的文本编辑器后,如果两者相等,返回 true# 代表退格字符。

注意:如果对空文本输入退格字符,文本继续为空。

示例 1:

输入:s = "ab#c", t = "ad#c"
输出:true
解释:s 和 t 都会变成 "ac"。

示例 2:

输入:s = "ab##", t = "c#d#"
输出:true
解释:s 和 t 都会变成 ""。

示例 3:

输入:s = "a#c", t = "b"
输出:false
解释:s 会变成 "c",但 t 仍然是 "b"。

提示:

  • 1 <= s.length, t.length <= 200

  • st 只含有小写字母以及字符 '#'

分析:

解法一:重构字符串 最容易想到的,根据规则重构字符串然后比较。

class Solution {
    public boolean backspaceCompare(String s, String t) {
        return getStr(s).equals(getStr(t));
    }
    public static String getStr(String s) {
        StringBuilder stringBuilder = new StringBuilder();
        for (int i = 0; i < s.length(); i++) {
            if (s.charAt(i) == '#') {
                if (stringBuilder.length()>0) {
                   stringBuilder.deleteCharAt(stringBuilder.length()-1);
                }
                continue;
            } else {
                stringBuilder.append(s.charAt(i));
            }
        }
        return stringBuilder.toString();
    }
}
  • 时间复杂度:O(N+M)

  • 空间复杂度:O(N+M)

解法二:双指针 #只会消除前面的字符串,不影响后面的,从末尾开始查找第一个有效的字符逐个比较。

class Solution {
    public boolean backspaceCompare(String S, String T) {
        int i = S.length() - 1, j = T.length() - 1;
        int skipS = 0, skipT = 0;
​
        while (i >= 0 || j >= 0) {
            while (i >= 0) {
                if (S.charAt(i) == '#') {
                    skipS++;
                    i--;
                } else if (skipS > 0) {
                    skipS--;
                    i--;
                } else {
                    break;
                }
            }
            while (j >= 0) {
                if (T.charAt(j) == '#') {
                    skipT++;
                    j--;
                } else if (skipT > 0) {
                    skipT--;
                    j--;
                } else {
                    break;
                }
            }
            if (i >= 0 && j >= 0) {
                if (S.charAt(i) != T.charAt(j)) {
                    return false;
                }
            } else {
                if (i >= 0 || j >= 0) {
                    return false;
                }
            }
            i--;
            j--;
        }
        return true;
    }
}

你可能感兴趣的:(LeetCode刷题之路,算法,leetcode,数据结构)