牛客-NC41-最长无重复子数组



方法一:HashSet+滑动窗口

思路:一道滑动窗口题(纯暴力是会超时的,注意看上图的备注信息。),其实很好理解:我们要找最长且无重复的子数组,无重复需要使用HashSet进行去重。要找到最长的,可以使用滑窗的思想去动态地改变长度。有以下情况(1)没有重复数组元素时,right指针一直往右移动,同时更新maxLen和window表。(2)当出现重复数组元素时,我们需要移除left指针所对应的元素,同时移动left指针,知道当前window表中不再出现重复元素(这里没有更新maxLen的原因是right指针没变,left在往右移动,所以此时形成的子数组长度肯定小于maxLen)。于是可以写出如下代码:

import java.util.*;


public class Solution {
   
    /** * * @param arr int整型一维数组 the array * @return int整型 */
    public int maxLength (int[] arr) {
   
        // write code here
        // 特判
        int n = arr.length;
        if (n <= 1) return n;
        int maxLen = 1;
        
        int left = 0, right = 0;
        HashSet<Integer> window = new HashSet<>();
        while (right < n) {
   
            while (window.contains(arr[right])) {
   
                window.remove(arr[left]);
                left++;
            }
            maxLen = Math.max(maxLen, right - left + 1);
            window.add(arr[right]);
            right++;
        }
        return maxLen;
    }
}

时间复杂度: O(N), 最坏情况是left和right都遍历了一遍字符串。
空间复杂度: O(N), 我们需要window表来存放遍历到的值。

方法二:HashSet+滑动窗口(优化)

思路:对方法一做以下优化:当窗口存在重复元素,是一个一个元素的缩小窗口,可以使用HashMap记住每个元素在数组中的索引,当遇到重复元素时,可以直接跳到重复元素的后面。

import java.util.*;


public class Solution {
   
    /** * * @param arr int整型一维数组 the array * @return int整型 */
    public int maxLength (int[] arr) {
   
        // write code here
        // 当窗口存在重复元素,是一个一个元素的缩小窗口。
        // 可以使用hashmap记住每个元素在数组中的索引,当遇到重复元素时,可以直接跳到重复元素的后面。
        int n = arr.length;
        if (n <= 1) return n;
        int maxLen = 1;

        int left = 0, right = 0;
        HashMap<Integer, Integer> window = new HashMap();
        while (right < n) {
   
            Integer rightIndex = window.getOrDefault(arr[right], -1);
            left = Math.max(left, rightIndex + 1);
            maxLen = Math.max(maxLen, right - left + 1);
            window.put(arr[right], right);
            right++;
        }
        return maxLen;
    }
}

时间复杂度: O(N), 最坏情况是left和right都遍历了一遍字符串。
空间复杂度: O(N), 我们需要window表来存放遍历到的值。
总结:本题自己想到使用滑窗和set来解决,写到后面对于当遇到重复元素怎么处理犯了愁。不知道left和right指针怎么移动才是正确的,没想到是只需要移动left指针,right指针是不能动的。通过移动left指针来让该窗口中没有重复的数组元素,达到去重的目的。另外,这里给出LeetCode上两道与之解法相近的题目,分别是无重复字符的最长子串以及剑指 Offer 48. 最长不含重复字符的子字符串

全部评论

相关推荐

沉淀一会:1.同学你面试评价不错,概率很大,请耐心等待; 2.你的排名比较靠前,不要担心,耐心等待; 3.问题不大,正在审批,不要着急签其他公司,等等我们! 4.预计9月中下旬,安心过节; 5.下周会有结果,请耐心等待下; 6.可能国庆节前后,一有结果我马上通知你; 7.预计10月中旬,再坚持一下; 8.正在走流程,就这两天了; 9.同学,结果我也不知道,你如果查到了也告诉我一声; 10.同学你出线不明朗,建议签其他公司保底! 11.同学你找了哪些公司,我也在找工作。
点赞 评论 收藏
分享
Hello_WordN:咱就是说,除了生命其他都是小事,希望面试官平安,希望各位平时也多注意安全
点赞 评论 收藏
分享
评论
点赞
收藏
分享
牛客网
牛客企业服务