LeetCode第 318 场周赛第二题_最长连续不重复子串的变种题

第 318 场周赛第二题另附周赛的模板题

2461. 长度为 K 子数组中的最大和

给你一个整数数组 nums 和一个整数 k 。请你从 nums 中满足下述条件的全部子数组中找出最大子数组和:

子数组的长度是 k,且
子数组中的所有元素 各不相同 。
返回满足题面要求的最大子数组和。如果不存在子数组满足这些条件,返回 0 。

子数组 是数组中一段连续非空的元素序列。

示例 1:

输入:nums = [1,5,4,2,9,9,9], k = 3
输出:15
解释:nums 中长度为 3 的子数组是:
- [1,5,4] 满足全部条件,和为 10 。
- [5,4,2] 满足全部条件,和为 11 。
- [4,2,9] 满足全部条件,和为 15 。
- [2,9,9] 不满足全部条件,因为元素 9 出现重复。
- [9,9,9] 不满足全部条件,因为元素 9 出现重复。
因为 15 是满足全部条件的所有子数组中的最大子数组和,所以返回 15 。
示例 2:

输入:nums = [4,4,4], k = 3
输出:0
解释:nums 中长度为 3 的子数组是:
- [4,4,4] 不满足全部条件,因为元素 4 出现重复。
因为不存在满足全部条件的子数组,所以返回 0 。
 

提示:

1 <= k <= nums.length <= 105
1 <= nums[i] <= 105

class Solution {
    public long maximumSubarraySum(int[] nums, int k) {
        
        //初始化数组和是第一个数
        //初始化最大数组和是0
        long sum = nums[0];
        long max = 0;

        int l = 0;
        int r = 1;
        int n = nums.length;
        Map<Integer,Integer> map = new HashMap<>();
        for(int num : nums){
            map.put(num,0);
        }

        //初始化第一个数出现的次数是1
        map.put(nums[0],1);

        while(r<n){
            if(map.get(nums[r]) == 0 ){
                map.put(nums[r],1);
                sum += nums[r];
                r++;
                if(r-l == k){
                    max = Math.max(max,sum);

                    //l++必须把nums[l]出现的次数置0
                    //sum -= nums[l]
                    sum -= nums[l];
                    map.put(nums[l],0);
                    l++;
                }
            }else{
                
                //l++必须把nums[l]出现的次数置0
                //sum -= nums[l]
                map.put(nums[l],0);
                sum -= nums[l];
                l++;
            }
        }

        //如果k == 1,排序找最大值也是猥琐至极,不会取k == 1的情况了
        Arrays.sort(nums);
        return k == 1 ? nums[n-1] : max;
    }
}



剑指 Offer II 016. 不含重复字符的最长子字符串_模板题目

 

给定一个字符串 s ,请你找出其中不含有重复字符的 最长连续子字符串 的长度。

示例 1:

输入: s = "abcabcbb"
输出: 3 
解释: 因为无重复字符的最长子字符串是 "abc",所以其长度为 3。
示例 2:

输入: s = "bbbbb"
输出: 1
解释: 因为无重复字符的最长子字符串是 "b",所以其长度为 1。
示例 3:

输入: s = "pwwkew"
输出: 3
解释: 因为无重复字符的最长子串是 "wke",所以其长度为 3。
     请注意,你的答案必须是 子串 的长度,"pwke" 是一个子序列,不是子串。
示例 4:

输入: s = ""
输出: 0
 

提示:

0 <= s.length <= 5 * 104
s 由英文字母、数字、符号和空格组成
 

注意:本题与主站 3 题相同: https://leetcode-cn.com/problems/longest-substring-without-repeating-characters/

class Solution {
    public int lengthOfLongestSubstring(String s) {
        

        int max = 1;
        int n = s.length();
        if(n == 0) return 0;

        int l = 0;
        int r = 1;

        Map<Character,Integer> map = new HashMap<>();
        for(char c : s.toCharArray()){
            map.put(c,0);
        }

        map.put(s.charAt(0),1);

        //799. 最长连续不重复子序列模板
        while(r < n){
            char c = s.charAt(r);
            if(map.get(c) == 0){
                map.put(c,1);
                r++;
                max = Math.max(max,r-l);
            }else{
                char cL = s.charAt(l);
                map.put(cL,0);
                l++;
            }
        }
        return max;
    }
}

 最后附上AcWing上求最长连续不重复子串的模板,它真的是一个练习板子很好的网站

799. 最长连续不重复子序列

给定一个长度为 nn 的整数序列,请找出最长的不包含重复的数的连续区间,输出它的长度。

输入格式

第一行包含整数 nn。

第二行包含 nn 个整数(均在 0∼1050∼105 范围内),表示整数序列。

输出格式

共一行,包含一个整数,表示最长的不包含重复的数的连续区间的长度。

数据范围

1≤n≤1051≤n≤105

输入样例:

5
1 2 2 3 5

输出样例:

3
import java.util.*;
import java.math.*;

class Main{
    
    //哈哈哈哈,自己用哈希表写出来了
    static int N = 100010;
    static int[] a = new int[N];
    public static void main(String[] args){
        Scanner scanner = new Scanner(System.in);
        int n = scanner.nextInt();
        Map<Integer,Integer> map = new HashMap<>();
        
        
        for(int i = 1;i<=n;i++){
            a[i] = scanner.nextInt();
        }
        
        for(int i = 1;i<=n;i++){
            map.put(a[i],0);
        }
        
        int l = 1;
        int r = 2;
        int max = 1;
        map.put(a[l],1);
        while(r<=n){
            if(map.get(a[r]) == 0){
                map.put(a[r],1);
                r++;
                max = Math.max(max,r-l);
            }else{
                map.put(a[l],0);
                l++;
            }
        }
        
        System.out.print(max);
    }
}

 码字不易,来自一名非科班的转码生。如果你也喜欢刷算法题的话,一键三连走一波。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值