寻找最长不重复子序列:一万+长度
思路:碰到一个元素(a[i])后,往回找,有无重复元素:
若有:假设在第 j 位,则起始端更新为 j + 1,从第 j + 1 再开始找
若前面没有相同的元素,则将第 i 位元素纳入子序列中,即,尾下标 = i,并进行下一轮
详见代码
void longestSubSeq_NoDup(const int* a, int n, int& s, int& e)
{
// s = start index of the subsequence
// e = end index of the subsequence (exclusive)
s = 0;
e = n > 0 ? 1 : 0;
int left=0;//记录起始端
//左端的元素都没有重复
for(int i = 0; i < n; i++){
int j = i -1;
//在第i个元素的左边到left之间找
while(j>=left && a[j]!=a[i])j--;
if(j<left){
//说明[left,i-1]间没有和a[i]相同的元素
//可以将当前子串长度与记录的最长字串比对
if(i-j>e-s){
//某些版本是i-j+1:意思是
//若有相同长度的子串,取最后一次出现的起始和终止点
s=j;e=i;
}
}
else left=j+1;
//left <= j <i,说明a[j]与a[i]相同,且a[j+1]!=a[i]
//所以取新的起始端为 j + 1
}
}
//*copy right goes to Dr. Derek Pao, Department of Electrical Engineering, City University of Hong Kong