给定一个长度为n的数组arr,返回arr的最长无重复元素子数组的长度,无重复指的是所有数字都不相同。
子数组是连续的,比如[1,3,5,7,9]的子数组有[1,3],[3,5,7]等等,但是[1,3,7]不是子数组
数据范围:
,
[2,3,4,5]
4
[2,3,4,5]是最长子数组
[2,2,3,4,3]
3
[2,3,4]是最长子数组
[9]
1
[1,2,3,1,2,3,2,2]
3
最长子数组为[1,2,3]
[2,2,3,4,8,99,3]
5
最长子数组为[2,3,4,8,99]
class Solution {
public:
/**
*
* @param arr int整型vector the array
* @return int整型
*/
int maxLength(vector<int>& arr) {
map<int, int> num_index; //检查是否越界了的map工具
map<int, int>::iterator iter; //迭代器
int before = 0;
int after = 1;
int max_len = 1;
int arr_len = arr.size();
num_index[arr[0]] = 0;
int temp_len = 1;
int next_before = 0;
//下面开始在线的动态测量过程
for (after = 1; after < arr_len; after++)
{
if (before > arr_len - max_len) //设置一个判断是否可以直接终止的情况,为了节省时间
break;
iter = num_index.find(arr[after]); //判断是否在当前的map中
if (iter == num_index.end()) //当前集合没有该键值对
{
num_index[arr[after]] = after; //匹配该值和所在的位置索引值
temp_len++;
}
else //当前集合存在该键值对,重复了
{
next_before = iter->second;
if (temp_len > max_len) //更新最大长度值
{
max_len = temp_len;
}
temp_len = after - next_before;
if (next_before - before < after - next_before) //map删除前面的,保留后面的,最后再加上一个after
{
for (int i = before; i <= next_before; i++) //一个一个删除前面的部分
{
num_index.erase(arr[i]);
}
num_index[arr[after]] = after;
}
else //直接清空map,从next_before往后一个一个加进来,加到after
{
num_index.clear();
for (int i = next_before + 1; i <= after; i++)
{
num_index[arr[i]] = i;
}
}
before = next_before + 1;
}
}
if (temp_len > max_len)
max_len = temp_len;
return max_len;
}
};
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.Queue;
/**
* NC41 最长无重复子数组
*/
public class Solution41 {
/**
* @param arr int整型一维数组 the array
* @return int整型
*/
public int maxLength(int[] arr) {
// write code here
HashSet<Integer> set = new HashSet<>();
int l = 0;
int r = 0;
int max = 0;
while (r < arr.length) {
if (!set.contains(arr[r])) {
set.add(arr[r++]);
} else {
while (arr[l] != arr[r]) {
set.remove(arr[l++]);
}
set.remove(arr[l++]);
}
max = Math.max(max, set.size());
}
return max;
}
public int maxLength1(int[] arr) {
// write code here
HashSet<Integer> set = new HashSet<>();
int l = 0;
int r = 0;
int max = 0;
while (r < arr.length) {
while (set.contains(arr[r])) {
set.remove(arr[l++]);
}
set.add(arr[r++]);
max = Math.max(max, set.size());
}
return max;
}
public int maxLength2(int[] arr) {
// write code here
Queue<Integer> queue = new LinkedList<>();
int max = 0;
for (int num : arr) {
while (queue.contains(num)) {
queue.poll();
}
queue.add(num);
max = Math.max(max, queue.size());
}
return max;
}
public int maxLength3(int[] arr) {
// write code here
HashMap<Integer, Integer> map = new HashMap<>();
int max = 0;
for (int i = 0, j = 0; i < arr.length; i++) {
if (map.containsKey(arr[i])) {
j = Math.max(j, map.get(arr[i]) + 1);
}
map.put(arr[i], i);
max = Math.max(max, i - j + 1);
}
return max;
}
public int maxLength4(int[] arr) {
// write code here
HashMap<Integer, Integer> map = new HashMap<>();
int max = 0;
for (int i = 0, j = 1; i < arr.length; i++) {
j = Math.min(j + 1, i - map.getOrDefault(arr[i], -1));
max = Math.max(max, j);
map.put(arr[i], i);
}
return max;
}
public static void main(String[] args) {
Solution41 solution41 = new Solution41();
System.out.println(solution41.maxLength(new int[]{2, 2, 3, 4, 3}));
System.out.println(solution41.maxLength1(new int[]{2, 2, 3, 4, 3}));
System.out.println(solution41.maxLength2(new int[]{2, 2, 3, 4, 3}));
System.out.println(solution41.maxLength3(new int[]{2, 2, 3, 4, 3}));
System.out.println(solution41.maxLength4(new int[]{2, 2, 3, 4, 3}));
}
} #
# 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
#
#
# @param arr int整型一维数组 the array
# @return int整型
#
class Solution:
def maxLength(self , arr: List[int]) -> int:
# write code here
pre_dis = 0
maxl = 0
dis = {}
for i in range(len(arr)):
num = arr[i]
if num in dis:
pre_dis = max(pre_dis,dis[num])
maxl = max(maxl,i+1-pre_dis)
dis[num]=i+1
return maxl
class Solution {
public:
/**
*
* @param arr int整型vector the array
* @return int整型
*/
int maxLength(vector<int>& arr) {
// corner case
if (arr.empty()) return 0;
int ans = 0, start = 0;
unordered_map<int, int> last;
for (int i = 0; i < arr.size(); ++i) {
if (last.find(arr[i]) != end(last) && last[arr[i]] >= start)
start = last[arr[i]] + 1;
ans = max(ans, i - start + 1);
last[arr[i]] = i;
}
return ans;
}
}; public int maxLength (int[] arr) {
// write code here
if (arr == null || arr.length == 0) return 0;
Set<Integer> set = new LinkedHashSet<>();
int index = 0; //记录最长无重复子数组的开始索引
int max = 0;
for (int i = 0; i < arr.length; i++) {
while (set.contains(arr[i])) {
set.remove(arr[index++]); //存在重复的就从index开始删除,直至不含arr[i]
}
set.add(arr[i]); //添加arr[i]
max = Math.max(max, i - index + 1); //取最大值
}
return max;
} public class Solution {
/**
*
* @param arr int整型一维数组 the array
* @return int整型
*/
public int maxLength (int[] arr) {
// write code here
int max = 0 ;
int start = 0 ;
Map<Integer,Integer> repeatIndex = new HashMap();
for (int i = 0 ;i < arr.length;i++){
if(repeatIndex.containsKey(arr[i])){
int repeatNumIndex = repeatIndex.get(arr[i]);
start = Math.max(repeatNumIndex+1,start);
}
repeatIndex.put(arr[i],i);
int curLength = i - start+1;
max = Math.max(max,curLength);
}
return max;
}
}
import java.util.*;
public class Solution {
/**
*
* @param arr int整型一维数组 the array
* @return int整型
*/
public int maxLength (int[] arr) {
// write code here
int[] map = new int[100001];
int left = 0;
int right = 0;
int res = 0;
while (right < arr.length) {
int cur = arr[right++];
map[cur]++;
while (map[cur] > 1) {
int del = arr[left++];
map[del]--;
}
res = Math.max(res, right - left);
}
return res;
}
}
/* 滑动窗口,用set维护一个不重复的窗口 */
public int maxLength (int[] arr) {
int res = 0;
Set<Integer> set = new HashSet<>();
for(int l = 0, r = 0; r < arr.length; r++) {
int a = arr[r];
while(set.contains(a)) {
set.remove(arr[l++]);
}
set.add(a);
res = Math.max(res, r - l + 1);
}
return res;
} import java.util.*;
public class Solution {
/**
*
* @param arr int整型一维数组 the array
* @return int整型
*/
public int maxLength (int[] arr) {
// write code here
//由题可知数据范围,1≤n≤100000,这样判断是否重复所需时间为O(1)
byte[] freq = new byte[100000];
//滑动窗口双指针
int l=0, r=-1;
//最长无重复子串
int res=0;
while(l<arr.length){
//如果 r+1不越界,对应值且没有重复的标记,则 r++
if(r+1<arr.length && freq[arr[r+1]]==0){
r++;
freq[arr[r]]++;
}else{
//否则 不断缩小左边界(l++),相应标记复位
freq[arr[l]]--;
l++;
}
//判断窗口大小是否需要更改
res=Math.max(res,r-l+1);
}
return res;
}
} import java.util.*;
public class Solution {
public int maxLength (int[] arr) {
int len = arr.length;
int left = 0;
int right = 0;
int res = 0;
boolean valid = false; // 表示窗口是否满足无重复元素
HashMap<Integer, Integer> map = new HashMap<>(); // 窗口中各个数字出现的情况,key:数字,value:该数出现的次数
while (right < len) {
int add = arr[right];
right++;
map.put(add, map.getOrDefault(add, 0) + 1);
if (map.get(add) == 1) { // 判断该数是否只出现一次
valid = true;
} else {
valid = false;
}
// 缩小窗口
while (!valid) {
int remove = arr[left];
map.put(remove, map.get(remove) - 1);
if (map.get(remove) == 1){ // 如果该数出现的次数减为1则窗口满足条件
valid = true;
}
left++;
}
// 更新结果
res = Math.max(res, right - left);
}
return res;
}
} /**
*
* @param arr int整型一维数组 the array
* @param arrLen int arr数组长度
* @return int整型
*/
int maxLength(int* arr, int arrLen ) {
int n[100000] = {0};
int left = 0;
int right = 0;
int res = 0;
while (right < arrLen) {
if (n[arr[right]] > 0) {
n[arr[left]] = 0;
left++;
} else {
n[arr[right]] = 1;
res = res > right - left + 1 ? res : right - left + 1;
right++;
}
}
return res;
} import java.util.*;
public class Solution {
public int maxLength (int[] arr) {
if(arr.length<2) return arr.length;
// write code here
Stack<Integer> stack = new Stack<>();
int res_lat = 0;
for(int i=0;i<arr.length;i++){
int pre =stack.search(arr[i]);
int lat =stack.size()-stack.search(arr[i])+1;
if(pre==-1){
stack.push(arr[i]);
res_lat=res_lat>stack.size()?res_lat:stack.size();
}else{
res_lat=res_lat>stack.size()?res_lat:stack.size();
for(int j=0;j<lat;j++){
stack.remove(0);
}
stack.push(arr[i]);
}
}
return res_lat;
}
} import java.util.*;
public class Solution {
/**
* 有点类似滑动窗口,从左到右遍历,遇到重复的,找到重复的索引,左指针++
* @param arr int整型一维数组 the array
* @return int整型
*/
public int maxLength (int[] arr) {
// write code here
int start = 0;
int end = -1;
int maxLen = 0;
Map<Integer,Integer> map = new HashMap<>();
for (int i = 0; i < arr.length; i++) {
if (map.containsKey(arr[i]) && map.get(arr[i]) >= start) {
start = map.get(arr[i]) + 1;
}
map.put(arr[i],i);
end++;
if (end-start+1>maxLen){
maxLen = end-start+1;
}
}
return maxLen;
}
} class Solution {
public:
int maxLength(vector<int>& arr) {
// write code here
int m[40000] = {0};//用map更好
unsigned int ans = 1, l = 0;//l记录重复位置
arr.push_back(arr[arr.size() - 1]);//尾部添加一个重复数据使其必然触发(3)条件
for(int i = 0; i < arr.size(); ++i){
if(m[arr[i]]){// (3)
if(ans < i - l)
ans = i - l;
if(m[arr[i]] > l)//只需在重复时记录下重复数据的位置
l = m[arr[i]];
}
m[arr[i]] = i + 1;
}
return ans;
}
}; class Solution {
public:
/**
*
* @param arr int整型vector the array
* @return int整型
*/
int maxLength(vector<int>& arr) {
// write code here
int l = 0, r = 0, ans = 0;;
set<int> s;
while (r < arr.size()) {
if (!s.count(arr[r])) {
s.insert(arr[r++]);
} else{
s.erase(arr[l++]);
}
ans = ans > s.size() ? ans : s.size();
}
return ans;
}
};