利用哈希表求数组中最大无相邻重复数字子序列的长度。

利用哈希表优化算法,求出数组中最大无相邻重复数字子序列的长度。


例题:对于一段给定长度n的数组,求符合任意两个相邻元素都不相等的子序列最大长度

其中第一行输入数组长度,第二行输入一段整数,表示这个数组

例:5

1 2 2 3 5。


一、朴素算法如何解决这个问题?

即利用i,和j,分别遍历数组,求出每个符合条件的子序列长度,再输出最大值。

 不难发现,朴素算法的时间复杂度是O(n*2)。

​
int ans = 1;
int cnt = 1;//cnt 表示当前搜索的符合条件的序列长度。且cnt最小值为1(子序列长度最小为1)
for(int i = 0;i < n-1;i++)
    for(int j = i+1;j <= n-1;j++){
        if(a[i] != a[j]){
            cnt ++;
            ans = max(cnt,ans)
        }
        if(a[i] == a[j]){//如果相邻元素相同,则初始化,即令cnt = 1;
            cnt = 1;
        }
    }
cout << ans << endl;    
        

​

二、利用哈希表优化。

核心步骤:通过只遍历一遍数组,利用O(n)的复杂度,达到寻找并存储符合条件的子序列,并输出子序列长度最大值。

int find(int a[]){
	int ans = 1;
	h[1] = a[0];//在h[1]处新建一个链表,h[1]指向a[0]。
	for(int i = 1;i <= n-1;i++){
		if(a[i]!=a[i-1]){//对于当前子序列,如果相邻元素不相等,则操作对应链表。
			e[idx] = a[i];
			ne[idx] = h[siz];
			h[siz] = idx++;
			cnt ++;
			ans = max(ans,cnt);
		}
		if(a[i]==a[i-1]){//相邻元素相等,则新开链表,并继续搜索a数组剩余元素。
			cnt = 1;
			siz ++;
		}
	}
	return ans;
}

如此,我们便能将O(n*2)的朴素算法利用哈希优化为O(n)的算法。


总结

全部代码:

#include <iostream>

using namespace std;

const int N = 100010;
int a[N],h[N],ne[N],e[N];
int n,idx,siz = 1,cnt = 1;

int max(int a,int b){
	if(a >= b)return a;
	else return b;
}



int find(int a[]){
	int ans = 1;
	h[1] = a[0];
	for(int i = 1;i <= n-1;i++){
		if(a[i]!=a[i-1]){
			e[idx] = a[i];
			ne[idx] = h[siz];
			h[siz] = idx++;
			cnt ++;
			ans = max(ans,cnt);
		}
		if(a[i]==a[i-1]){
			cnt = 1;
			siz ++;
		}
	}
	return ans;
}

int main(){
    cin.tie(0);
    ios::sync_with_stdio(false);
	cin >> n;
	int max1 = cnt;

	for(int i = 0;i < n;i++)cin >> a[i];
	cout << find(a);
	return 0;
}

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值