力扣滑动窗口(1)

79 阅读1分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第24天,点击查看活动详情

992. K 个不同整数的子数组

思路:

求“每个同学都有苹果,恰好有 3 个苹果的同学有多少位”,即“拥有 3 个 或 2 个 或 1 个苹果的同学数”减去“拥有 2 个或 1 个苹果的同学数”

代码:

class Solution {
public:
    int getsubstr(vector<int> &nums, int k) {
        unordered_map<int, int> hash;
        int cnt = 0, res = 0;
        for (int i = 0, j = 0; j < nums.size(); j++) {
            hash[nums[j]]++;
            if (hash[nums[j]] == 1) cnt++;
            while (cnt > k) {
                hash[nums[i]]--;
                if (hash[nums[i]] == 0) cnt--;
                i++;
            }
            res += j - i + 1;
        }return res;
    }
    int subarraysWithKDistinct(vector<int>& nums, int k) {
        return getsubstr(nums, k) - getsubstr(nums, k - 1);
    }
};

1358. 包含所有三种字符的子字符串数目

思路:

代码:

class Solution {
public:
    int getsubstr(string s, int k) {
         int cnt = 0, ans = 0;
        unordered_map<char, int> hash;
        for (int i = 0, j = 0; j < s.size(); j++) {
            hash[s[j]]++;
            if (hash[s[j]] == 1) cnt++;
            while (cnt > k) {
                hash[s[i]]--;
                if (hash[s[i]] == 0) cnt--;
                i++;
            }
            ans += j - i + 1;
            
        }
        return ans;
    }
    int numberOfSubstrings(string s) {
        
        return getsubstr(s, 3) - getsubstr(s, 2);
    }
};

930. 和相同的二元子数组

思路:

代码:

class Solution {
public:
    int getsubstr(vector<int> &nums, int goal) {
        int sum = 0,ans = 0;
        for (int i = 0, j = 0; j < nums.size(); j++) {
            sum += nums[j];
            while (sum > goal) {
                sum -= nums[i++];
            } 
            ans += j - i + 1;
        }
        return ans;
    } 
    int numSubarraysWithSum(vector<int>& nums, int goal) {
        if (goal == 0) return getsubstr(nums, goal);
        return getsubstr(nums, goal) - getsubstr(nums, goal - 1);
    }
};

剑指 Offer 48. 最长不含重复字符的子字符串

思路:

代码:

class Solution {
public:
    int lengthOfLongestSubstring(string s) {
        unordered_map<char, int> hash;
        int cnt = 0, ans = 0;
        for (int i = 0, j = 0; j < s.size(); j++) {
            hash[s[j]]++;
            while (hash[s[j]] > 1) {
                hash[s[i++]]--;
            }
            ans = max(ans, j - i + 1);
        }return ans;
    }
};

995. K 连续位的最小翻转次数

思路:

翻转奇数次变成nums[i]^1 翻转偶数次变成nums[i]

代码:

class Solution {
public:
    int minKBitFlips(vector<int>& nums, int k) {
        queue<int>que;
        int n = nums.size();
        int ans = 0;
        for (int i = 0; i < nums.size(); i++) {
            while (!que.empty() && que.front() + k <= i) {
                que.pop();
            }
            if (que.size() % 2 == nums[i]) {
                if (i + k > n) return - 1;
                que.push(i);
                ans++;
            }
        }
        return ans;
    }
};