🚩传送门:牛客题目

题目

给定一个数组 [NC]41. 最长无重复子数组 - 图1,返回 [NC]41. 最长无重复子数组 - 图2的最长无重复元素子数组的长度,无重复指的是所有数字都不相同。

子数组是 连续 的,比如[1,3,5,7,9]的子数组有[1,3],[3,5,7]等等,但是[1,3,7]不是子数组

示例1

输入:[2,3,4,5] 返回值:4 说明:[2,3,4,5]是最长子数组

示例2

输入:[2,2,3,4,3] 返回值:3 说明:[2,3,4]是最长子数组

示例3

输入:[9] 返回值:1

示例4

输入:[1,2,3,1,2,3,2,2] 返回值:3 说明:最长子数组为 [1,2,3]

示例5

输入:[2,2,3,4,8,99,3] 返回值:5 说明:最长子数组为 [2,3,4,8,99]

解题思路:双指针

利用 [NC]41. 最长无重复子数组 - 图3 存储数据来进行判重,当遇到重复的冲突数据的时候 。需要判断 左边冲突点pre 谁数字更大。

谁的下标更大,谁就是最新的 pre

pre:用来存储合法区间 (start,end]中的 [NC]41. 最长无重复子数组 - 图4

[NC]41. 最长无重复子数组 - 图5 的意义为了计算从 [NC]41. 最长无重复子数组 - 图6[NC]41. 最长无重复子数组 - 图7 的有效区间

算法流程:

  1. 遇到一个数字首先判重,是否和[NC]41. 最长无重复子数组 - 图8中的数字产生冲突

    冲突:在 pre左边冲突点中选择较大值赋值给 [NC]41. 最长无重复子数组 - 图9

  2. 利用公式 [NC]41. 最长无重复子数组 - 图10 计算有效区间长度,看能否刷新 [NC]41. 最长无重复子数组 - 图11 最大长度值

  3. 将当前的数字和下标加入[NC]41. 最长无重复子数组 - 图12用于判重

    无论[NC]41. 最长无重复子数组 - 图13是否包含此数都刷新重新存储

image.png

image.png

复杂度分析

时间复杂度: [NC]41. 最长无重复子数组 - 图16 ,其中 [NC]41. 最长无重复子数组 - 图17 是数组的长度。

空间复杂度:[NC]41. 最长无重复子数组 - 图18 ,其中 k 去重个数

我的代码

  1. public class Solution {
  2. public static int maxLength(int[] arr) {
  3. HashMap< Integer, Integer > map = new HashMap < > ();
  4. int res=0;
  5. int pre=-1; //pre指向合法区间(start,end]的start
  6. for(int i=0;i<arr.length;i++){
  7. //1.判断是否产生冲突点
  8. if(map.containsKey(arr[i]))
  9. pre=Math.max(map.get(arr[i]),pre); //pre应选此次和上一次的冲突点的较大值
  10. //2.更新res:更新公式 i-pre
  11. res=Math.max(res,i-pre);
  12. //3.将当前最新元素入map用于判断重复
  13. map.put(arr[i], i);
  14. }
  15. return res;
  16. }
  17. }