文字列の最も長い非繰り返し文字のサブ文字列を検索します
タイトル説明
配列arrが与えられた場合、arrの最も長く繰り返されるサブストリングの長さを返します(繰り返されないということは、すべての文字が異なることを意味します)。
説明を入力してください:
入力には2行が含まれ、最初の行には整数n(1≤n≤105)n(1 \ leq n \ leq 10 ^ 5)が含まれます。n (1≤n≤1 05)、配列arrの長さを表し、2行目には配列arr(1≤arr[i]≤106)arr(1 \ leq arr [i] \ leq 10 ^ 6)を表すn個の整数が含まれます。a r r (1≤a r r [ i ]≤1 06)。
出力の説明:
arrの最も長い繰り返し不可能な文字の長さを表す整数を出力します。
例1
入る
4
2 3 4 5
出力
4
例2
入る
5
2 2 3 4 3
出力
3
回答:
貪欲。ハッシュテーブルを使用して、各要素の最新の位置を記録します。位置iへの現在のトラバーサルを想定すると、preは、arr [i-1]で終了する必要があるという条件の下で、最も長く繰り返されないサブストリングの開始前の位置を示します。pre <hash [arr [i]]の場合、arr [i]がpreの後に表示されることを示し、preをhash [arr [i]]に更新します。それ以外の場合、pre +1からiまでの位置は繰り返されない要素です。最大長を直接更新するだけです。
コード:
#include <cstdio>
using namespace std;
const int N = 1000010;
int n;
int a[N];
int main(void) {
scanf("%d", &n);
int pre = 0, ret = 0;
int val;
for (int i = 0; i < n; ++i) {
scanf("%d", &val);
if (!a[val] || a[val] < pre) {
if (i - pre + 1 > ret) ret = i - pre + 1;
} else pre = a[val];
a[val] = i + 1;
}
return 0 * printf("%d\n", ret);
}