首页 > 其他分享 >《滑动窗口》不定长滑动窗口(求最长/最大)

《滑动窗口》不定长滑动窗口(求最长/最大)

时间:2024-08-23 17:48:04浏览次数:9  
标签:cnt right 窗口 nums int ans 滑动 不定 left

1. LeetCode 3 无重复字符的最长子串

方法1:滑动窗口 + 哈希

class Solution {
    public int lengthOfLongestSubstring(String s) {
        HashSet<Character> set = new HashSet<Character>();
        int left = 0, ans = 0;
        for (int right = 0; right < s.length(); right++) {
            while (set.contains(s.charAt(right)))
                set.remove(s.charAt(left++));
            ans = Math.max(ans, right - left + 1);
            set.add(s.charAt(right));
        }
        return ans;
    }
}
class Solution:
    def lengthOfLongestSubstring(self, s: str) -> int:
        st = set(); left = ans = 0
        for right, ch in enumerate(s):
            while ch in st:
                st.remove(s[left])
                left += 1
            ans = max(ans, right - left + 1)
            st.add(ch)
        return ans

2. LeetCode 1493 删掉一个元素以后全为1的最长子数组

方法1:滑动窗口

class Solution {
    public int longestSubarray(int[] nums) {
        int left = 0, ans = 0, cnt = 0; // 标记当前 0 的个数
        for (int right = 0; right < nums.length; right++) {
            if (nums[right] == 0)
                cnt += 1;
            while (cnt > 1) {
                if (nums[left] == 0)
                    cnt -= 1;
                left += 1;
            }
            // 保证[left , right]中只有一个 0
            ans = Math.max(ans, right - left + 1);
        }
        return ans - 1;
    }
}
class Solution:
    def longestSubarray(self, nums: List[int]) -> int:
        cnt, left, ans = 0, 0, 0
        for right, x in enumerate(nums):
            if x == 0:
                cnt += 1
            while cnt > 1:
                if nums[left] == 0:
                    cnt -= 1
                left += 1
            # 保证[left, right]中只有一个 0
            ans = max(ans, right - left + 1)
        return ans - 1 # 减去其中需要删除的一个元素

方法2:思维 + 前缀和

class Solution {
    public int longestSubarray(int[] nums) {
        int n = nums.length;
        
        int[] prev = new int[n]; // 当前位置结尾前面连续 1 的个数
        prev[0] = nums[0]; // 初始化
        for (int i = 1; i < n; i++)
            prev[i] = nums[i] == 1 ? prev[i - 1] + 1 : 0;
        
        int[] next = new int[n]; // 当前位置结尾后面连续 1 的个数
        next[n - 1] = nums[n - 1]; // 初始化
        for (int i = n - 2; i >= 0; i--)
            next[i] = nums[i] == 1 ? next[i + 1] + 1 : 0;
        
        int ans = 0;
        for (int i = 0; i < n; i++) { // 枚举要删除的位置
            int prevS = i == 0 ? 0 : prev[i - 1];
            int nextS = i == n - 1 ? 0 : next[i + 1];    
            ans = Math.max(ans, prevS + nextS);
        }
        return ans;
    }
}
class Solution:
    def longestSubarray(self, nums: List[int]) -> int:
        n = len(nums)
        pre = [nums[0]] * n; nxt = [nums[n - 1]] * n
        for i in range(1, n): # 初始化 pre 数组
            pre[i] = 0 if nums[i] == 0 else pre[i - 1] + 1
        for i in range(n - 2, -1, -1):
            nxt[i] = 0 if nums[i] == 0 else nxt[i + 1] + 1
        ans = 0
        for i in range(n):
            preS = 0 if i == 0 else pre[i - 1]
            nxtS = 0 if i == n - 1 else nxt[i + 1]
            ans = max(ans, preS + nxtS)
        return ans

3. LeetCode 2730 找到最长的半重复子字符串

方法1:滑动窗口

class Solution {
    public int longestSemiRepetitiveSubstring(String s) {
        int val = 0, left = 0, ans = 1; // 当只有一个字符时返回 1
        for (int right = 1; right < s.length(); right++) {
            if (s.charAt(right) == s.charAt(right - 1))
                val += 1; // 相邻重复个数加 1
            while (val > 1) {
                if(s.charAt(left) == s.charAt(left + 1))
                    val -= 1;
                left += 1;
            }
            ans = Math.max(ans, right - left + 1);
        }
        return ans;
    }
}
class Solution:
    def longestSemiRepetitiveSubstring(self, s: str) -> int:
        cnt, left, ans = 0, 0, 1
        for right in range(1, len(s)):
            if s[right - 1] == s[right]:
                cnt += 1
            while cnt > 1:
                if s[left] == s[left + 1]:
                    cnt -= 1
                left += 1
            ans = max(ans, right - left + 1)
        return ans

4. LeetCode 904 水果成篮

方法1:滑动窗口 + 哈希表

class Solution {
    public int totalFruit(int[] fruits) {
        // 标记区间数字出现次数
        HashMap<Integer, Integer> map = new HashMap<Integer, Integer>();
        // left:左端点 ans:最终答案
        int left = 0, ans = 0;
        for (int right = 0; right < fruits.length; right++) {
            map.merge(fruits[right], 1, Integer::sum);
            while (map.size() > 2) {
                if (map.merge(fruits[left], -1, Integer::sum) == 0)
                    map.remove(fruits[left]);                
                left += 1;
            }
            ans = Math.max(ans, right - left + 1);
        }   
        return ans;
    }
}
class Solution:
    def totalFruit(self, fruits: List[int]) -> int:
        cnt = Counter() # python的计数器
        left, ans = 0, 0
        for right, x in enumerate(fruits):
            cnt[x] += 1 # 如果不存在会自动创建
            while len(cnt) > 2:
                cnt[fruits[left]] -= 1
                if cnt[fruits[left]] == 0: # 需要手动删除
                    cnt.pop(fruits[left])
                left += 1
            ans = max(ans, right - left + 1)
        return ans

5. LeetCode 1695 删除子数组的最大得分

方法1:滑动窗口 + 哈希表

class Solution {
    public int maximumUniqueSubarray(int[] nums) {
        HashMap<Integer, Integer> map = new HashMap<Integer, Integer>();
        int left = 0, val = 0, ans = 0;
        for (int right = 0; right < nums.length; right++) {
            map.merge(nums[right], 1, Integer::sum);
            val += nums[right];
            while (map.get(nums[right]) > 1) {
                map.merge(nums[left], -1, Integer::sum);
                // 此处可以删除键值为 0 的键
                val -= nums[left]; left++;
            }
            ans = Math.max(ans, val);
        }
        return ans;
    }
}
class Solution:
    def maximumUniqueSubarray(self, nums: List[int]) -> int:
        cnt = Counter() # 统计每个数字出现的次数
        left, val, ans = 0, 0, 0
        for right, x in enumerate(nums):
            cnt[x] += 1; val += x
            while cnt[x] > 1:
                cnt[nums[left]] -= 1
                val -= nums[left]
                # 此处可以删除个数为 0 的键
                left += 1
            ans = max(ans, val)
        return ans

6. LeetCode 2958 最多 K 个重复元素的最长子数组

方法1:滑动窗口 + 哈希表

class Solution {
    public int maxSubarrayLength(int[] nums, int k) {
        HashMap<Integer, Integer> map = new HashMap<Integer, Integer>();
        int left = 0, ans = 0;
        for (int right = 0; right < nums.length; right++) {
            map.merge(nums[right], 1, Integer::sum);
            while (map.get(nums[right]) > k) {
                map.merge(nums[left], -1, Integer::sum);
                // 此处可以删除键值为 0 的键
                left++;
            }
            ans = Math.max(ans, right - left + 1);
        }
        return ans;
    }
}
class Solution:
    def maxSubarrayLength(self, nums: List[int], k: int) -> int:
        cnt = Counter() # 统计每个数字出现的次数
        left, ans = 0, 0
        for right, x in enumerate(nums):
            cnt[x] += 1
            while cnt[x] > k:
                cnt[nums[left]] -= 1
                # 此处可以删除个数为 0 的键
                left += 1
            ans = max(ans, right - left + 1)
        return ans

7. LeetCode 1004 最大连续1的个数III

方法1:滑动窗口

class Solution {
    public int longestOnes(int[] nums, int k) {
        int cnt = 0, left = 0, ans = 0;
        for (int right = 0; right < nums.length; right++) {
            cnt += nums[right] == 0 ? 1 : 0;
            while (cnt > k) {
                cnt -= nums[left] == 0 ? 1 : 0;
                left += 1;
            }
            ans = Math.max(ans, right - left + 1);
        }
        return ans;
    }
}
class Solution:
    def longestOnes(self, nums: List[int], k: int) -> int:
        cnt, left, ans = 0, 0, 0
        for rigth, x in enumerate(nums):
            cnt += 1 if x == 0 else 0
            while cnt > k:
                cnt -= 1 if nums[left] == 0 else 0
                left += 1
            ans = max(ans, rigth - left + 1)
        return ans

8. LeetCode 2024 考试的最大困扰度

方法1:滑动窗口

class Solution {
    public int maxConsecutiveAnswers(String answerKey, int k) {
        return Math.max(longest(answerKey, k, 'T'), longest(answerKey, k, 'F'));
    }

    public int longest(String s, int k, char ch) {
        int cnt = 0, left = 0, ans = 0;
        for (int right = 0; right < s.length(); right++) {
            cnt += s.charAt(right) == ch ? 1 : 0;
            while (cnt > k) {
                cnt -= s.charAt(left) == ch ? 1 : 0;
                left += 1;
            }
            ans = Math.max(ans, right - left + 1);
        }
        return ans;
    }
}
class Solution:
    def maxConsecutiveAnswers(self, answerKey: str, k: int) -> int:
        return max(self.longest(answerKey, k, 'T'), self.longest(answerKey, k, 'F'))

    def longest(self, s: str, k: int, ch: str) -> int:
        cnt, left, ans = 0, 0, 0
        for rigth, x in enumerate(s):
            cnt += 1 if x == ch else 0
            while cnt > k:
                cnt -= 1 if s[left] == ch else 0
                left += 1
            ans = max(ans, rigth - left + 1)
        return ans

9.

标签:cnt,right,窗口,nums,int,ans,滑动,不定,left
From: https://www.cnblogs.com/XuGui/p/18376749

相关文章

  • 【开发工具】| Visual Studio 2019如何打开汇编语言窗口
    文章目录引言开启方式①首先设置visualStudio开启反汇编窗口。②打开反汇编窗口引言汇编语言是一种低级编程语言,它非常接近计算机的机器语言。机器语言是计算机能够直接理解和执行的二进制指令集,而汇编语言则是这些二进制指令的文本表示形式,使用助记符来代替难以记......
  • 不定期一VP退役远离我
    写在前面由于本人很菜,所以都是div2。24/08/21linkCF1993A记一下每种选项的个数再和\(n\)取个\(\min\)即可。CF1993B首先先特判掉全奇全偶的情况。然后就发现操作只能使偶数变成奇数,且答案只能为\(k\)或\(k+1\),\(k\)为偶数个数,所以只需要把偶数从小到大的与最大的......
  • 【Qt】Qt窗口 | QDialog 对话框
    文章目录一.对话框二.对话框的分类1.非模态对话框2.模态对话框3.混合属性对话框三.自定义对话框1.代码实现2.ui文件实现四.内置对话框1.QMessageBox消息对话框2.QColorDialog颜色对话框3.QFileDialog文件对话框4.QFontDialog字体对话框5.QInputDialo......
  • 239. 滑动窗口最大值
    题目描述给你一个整数数组nums,有一个大小为k的滑动窗口从数组的最左侧移动到数组的最右侧。你只可以看到在滑动窗口内的k个数字。滑动窗口每次只向右移动一位。返回滑动窗口中的最大值。解题思路这里我们可以自己设计个队列,这个队列里面主体数据结构我们使用Java里的De......
  • ProcessBar窗口类
    一、设计器二、设计器源码usingSystem;usingSystem.Collections.Generic;usingSystem.ComponentModel;usingSystem.Data;usingSystem.Drawing;usingSystem.Linq;usingSystem.Text;usingSystem.Threading.Tasks;usingSystem.Windows.Forms;usingSystem.Threa......
  • WPF 模拟UWP原生窗口样式——亚克力|云母材质、自定义标题栏样式、原生DWM动画 (附我封
    先看一下最终效果,左图为使用亚克力材质并添加组合颜色的效果;右图为MicaAlt材质的效果。两者都自定义了标题栏并且最大限度地保留了DWM提供的原生窗口效果(最大化最小化、关闭出现的动画、窗口阴影、拖拽布局器等)。接下来把各部分的实现一个个拆开来讲讲。一、使用窗口材质特......
  • 《滑动窗口》定长滑动窗口
    LeetCode1456定长子串中元音的最大数目方法1:滑动窗口classSolution{publicintmaxVowels(Strings,intk){intn=s.length(),count=0,ans=0;for(inti=0;i<n;i++){count+=isVowel(s.charAt(i));if(......
  • 【TCP】核心机制:滑动窗口、流量控制和拥塞控制
    文章目录滑动窗口窗口滑动滑动窗口丢包流量控制拥塞控制窗口大小变化过程滑动窗口有一类算法题,就是通过滑动窗口的思想来解决的,算法中的“滑动窗口”借鉴自TCP的滑动窗口TCP是要保证可靠传输的==>代价,降低了传输的效率(重传,确认重传等操作)TCP希望能在可靠传输......
  • echats鼠标滑动,连续修改点的位置
    定义图表myChart.value=markRaw(echarts.init(document.getElementById("theEcharts")));myChart.value.setOption(options.value);监听鼠标按下,监听鼠标移动,监听鼠标抬起//加条件判断,按下后滑动才能改变图表letetype=0myChart.value.getZr().on('m......
  • StringGrid单元格绑定ComboBox、DateTimePicker或窗口传值
    一、初始化控件状态procedureTForm7.FormCreate(Sender:TObject);beginwithStringGrid1dobeginColWidths[0]:=15;Cells[1,0]:='Combobox';ColWidths[1]:=100;Cells[2,0]:='DateTimePicker';ColWidths[2]:=100;......