数据结构-连续相同元素为固定值的最长子串长度

【题目来自灰灰考研】

2016清华大学912

求一个数组A中连续相同数字的和等于s的最长子数组长度.

例如A={1,1,2,1,1,1,2,1}, s=3.则所求子数组长度为 3

要求算法时间复杂度不超过 O(n),空间复杂度不超过 O(1) .

a) 描述算法思想 

b) 伪代码实现 

c) 计算程序的算法复杂度。 

循环遍历数组,每当遇到一个数字时,做如下判断

  1. 如果当前数字不能被目标值整除,那么他肯定不能组合成目标值,直接pass掉,下一轮循环
  2. 如果当前数字可以被目标值整除,那么算出商,也就是如果用当前数字构成目标值的话需要多少个
    1. 判断这个值当前位置和所需要位数的和与数组长度的大小关系:比如说当前数字为2在数组的最后一个位置,目标值为8,如果我想用2构成8那么还需要3个,但是我已经是数组最后一个了,后面不可能有了,这种情况也要pass掉
    2. 如果这个位置和需要的位数也符合要求,那么就是要判断这么多位数是不是连续着都是当前值,比如当前为2,目标为8,那么后面的3个数字也都要是2
      1. 如果满足上述要求,那么这个数字可以构成目标值,接下来就是更新最优解了
#include<iostream>
#include<cstdlib>
#include<cstring>

using namespace std;

int getLongSubArrayLength(int data[], int n, int target)
{
	/*
		代码虽然有两层循环,但是所遍历的数据元素不会重复,所以时间复杂度O(n) 
	*/
	int num, length = 0, i, j;
	
	for(i = 0; i < n; i++)
	{
		// 如果给出的数字不能整除当前数字,那么多个连续的这个数字肯定不能 构成需要的数字 
		if(target % data[i] != 0)
			continue;
		// 算出如果使用当前数字来组成目标,则需要多少个 
		num = target / data[i];
		// 如果需要的位数和当前位置相加大于数组长度,则这个数字也不可能构成目标 
		if((i + num) > n)
			continue;
		// 如果满足可以使用当前数字构成目标的条件了,那么就要判断当前数字的后面是不是有我们需要的那么多位连续了 
		for(j = i + 1; j < i + num; j++)
		{
			if(data[j] != data[i])
			{
				i = j - 1;
				break;
			}
		}
		// 如果上述循环执行完毕,那么就是满足条件了 
		if(j == i + num)
		// 更新最长长度 
			if(num > length)
				length = num;
	}
	return length;
}

int main()
{
	//	int data[] = {1,1,2,1,1,1,2,1};
	//	int data[] = {1,3,4,5,1,3,2,1};
	//	int data[] = {1};
	int result = getLongSubArrayLength(data, 1, 1);
	cout<<"The Result is :"<<result<<endl;
	return 0;
}

test1:

A={1,1,2,1,1,1,2,1} 

s=3

结果 3

test2:

A={1,3,4,5,1,3,2,1} 

s=6

结果 0

test3:

A={1} 

s=1

结果 1

猜你喜欢

转载自blog.csdn.net/LiuKe369/article/details/81322309