一.说明

1.本代码部分注释均来自于ai

2.建议了解原理后,再去写题目,不要直接看解析

2.何为滑动窗口:

2练习

1.题目: 长度最小数组

1.c++/c

class Solution {
public:
    int minSubArrayLen(int target, vector<int>& nums) {
        // n:数组nums的长度
        int n = nums.size();
        // l:滑动窗口左指针;r:滑动窗口右指针(初始均为0)
        int l = 0; int r = 0;
        // ret:记录满足条件的最短子数组长度,初始化为INT_MAX(整数最大值)
        int ret = INT_MAX;  // 使ret值为最大
        // sum:记录当前滑动窗口内元素的和
        int sum = 0;
        // 右指针r遍历数组,扩展窗口右边界
        for (r = 0; r < n; ++r) {
            // 将当前右指针元素加入窗口和
            sum += nums[r];
            // 当窗口和>=target时,尝试收缩左指针以寻找更短的有效窗口
            while (sum >= target) {
                // 更新最短长度:当前窗口长度(r-l+1)与历史最小值比较
                ret = min(ret, r - l + 1);
                // 左指针右移,从窗口中移除左元素,减小窗口和
                sum -= nums[l];
                l += 1;
            }
        }
        // 若未找到有效窗口(ret仍为INT_MAX),返回0;否则返回最短长度
        return ret == INT_MAX ? 0 : ret;
    }
};

2.python

class Solution:
    def minSubArrayLen(self, target: int, nums: List[int]) -> int:
        # n:数组nums的长度
        n = len(nums)
        # l:滑动窗口左指针;r:滑动窗口右指针(初始均为0)
        l = 0;r=0
        # ret:记录满足条件的最短子数组长度,初始化为无穷大(用于后续比较更新)
        ret = float("inf")  # 使ret值为最大
        # sum:记录当前滑动窗口内元素的和
        sum = 0
        # 右指针r遍历数组,扩展窗口右边界
        for r in range(0,n):
            # 将当前右指针元素加入窗口和
            sum+=nums[r]
            # 当窗口和>=target时,尝试收缩左指针以寻找更短的有效窗口
            while sum>=target:
                # 更新最短长度:当前窗口长度(r-l+1)与历史最小值比较
                ret=min(ret,r-l+1)
                # 左指针右移,从窗口中移除左元素,减小窗口和
                sum-=nums[l]
                l+=1
        # 若未找到有效窗口(ret仍为无穷大),返回0;否则返回最短长度
        return 0 if ret==float("inf") else ret

2.无重复的最长子串

分析:

1.c++/c

/*class Solution {
public:
    int lengthOfLongestSubstring(string s) {
        // n:字符串长度;l:左指针(窗口左边界的前一位,初始为-1)
        int n = s.size(); int l = -1;
        // long1:记录最长无重复子串的长度;temp:存储当前字符的ASCII码
        int long1 = 0; int temp = 0;
        // 哈希数组:大小150(覆盖ASCII字符),初始值-1(标记字符未出现)
        vector<int> hash(150, -1);
        
        // 右指针r遍历字符串,扩展窗口右边界
        for (int r = 0; r < n; r++) {
            // 获取当前字符的ASCII码(C++中char直接转换为整数)
            temp = s[r];
            
            // 若当前字符已在窗口内(哈希值为1),收缩左指针
            while (hash[temp] == 1) {
                l++;  // 左指针右移
                hash[s[l]] = -1;  // 重置左指针经过字符的哈希状态
            }
            
            // 标记当前字符已加入窗口(哈希值设为1)
            hash[temp] = 1;
            // 更新最长子串长度(当前窗口长度为r - l)
            long1 = max(long1, r - l);
        }
        
        return long1;
    }
};*/
//优化版
class Solution {
public:
    int lengthOfLongestSubstring(string s) {
        // n:字符串长度;l:左指针(窗口左边界的前一位,初始为-1)
        int n = s.size(); int l = -1;
        // long1:记录最长无重复子串的长度
        int long1 = 0;
        // 哈希数组:大小150(覆盖ASCII字符),初始值-1(标记字符未出现)
        vector<int> hash(150, -1);
        
        // 右指针r遍历字符串,扩展窗口右边界
        for (int r = 0; r < n; r++) {
            // 获取当前字符的ASCII码,作为哈希数组索引
            int temp = s[r];
            
            // 若当前字符已出现且上次位置在窗口内,左指针跳至上次位置
            if (hash[temp] > l) {
                l = hash[temp];
            }
            
            // 更新当前字符的最新出现位置(右指针r)
            hash[temp] = r;
            // 更新最长子串长度(当前窗口长度为r - l)
            long1 = max(long1, r - l);
        }
        
        return long1;
    }
};

2.python

"""class Solution:
    def lengthOfLongestSubstring(self, s: str) -> int:
        # n:获取字符串s的长度;l:左指针,初始值-1(窗口左边界的前一位)
        n=len(s);l=-1
        # long:存储最长无重复子串的长度(结果变量);temp:临时存储当前字符的ASCII码
        long=0;temp=0
        # 哈希数组:大小150(覆盖ASCII字符范围),初始值-1(标记字符未出现)
        hash=150*[-1]
        # 右指针r从0遍历到n-1,逐步扩展窗口右边界
        for r in range(0,n):
            # 计算当前右指针指向字符的ASCII码,存入temp
            temp=ord(s[r])
            # 若当前字符已在窗口内(hash[temp] == 1),循环收缩窗口
            while(hash[temp]==1):
                l+=1  # 左指针右移,缩小窗口
                hash[ord(s[l])]=-1  # 重置左指针经过字符的哈希状态(标记为未出现)
            # 标记当前字符已加入窗口(哈希值设为1)
            hash[temp]=1
            # 计算当前窗口长度(r-l),更新最长长度long
            long=max(long,r-l)
        # 返回最长无重复子串的长度
        return long
"""
#优化版        
class Solution:
    def lengthOfLongestSubstring(self, s: str) -> int:
        # n:字符串s的长度;l:左指针,初始值-1(窗口左边界的前一位)
        n=len(s);l=-1
        # long:存储最长无重复子串的长度(结果变量)
        long=0
        # 哈希数组:大小150(覆盖ASCII字符范围),初始值-1(标记字符未出现)
        hash=150*[-1]
        # 右指针r从0遍历到n-1,扩展窗口右边界
        for r in range(0,n):
            # 计算当前字符的ASCII码,存入temp(避免重复调用ord函数)
            temp=ord(s[r])
            # 若当前字符已出现过,且上次出现位置在当前窗口内(>l),左指针直接跳到该位置
            if hash[temp]>l:
                l=hash[temp]
            # 更新当前字符的最新出现位置(当前右指针r)
            hash[temp]=r
            # 计算当前窗口长度(r-l),更新最长长度long
            long=max(long,r-l)
        # 返回最长无重复子串的长度
        return long

二:练习

1.最大连续1的个数 III

答案

2.1658. 将 x 减到 0 的最小操作数

答案

3.904. 水果成篮

答案

4.438. 找到字符串中所有字母异位词

答案

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐