找出包含序列的所有元素的最小长度子序列

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/MOU_IT/article/details/88751693

1、题目描述

    给定一个序列如S = {1,8,2,1,4,1,2,9,1,8,4},我们需要找到包含S的所有元素的最小长度子序列(不重复,顺序不重要)。如何有效地找到这个子序列?注意:S:{1,2,4,8,9 }中有5个不同的元素,最小长度子序列必须包含所有这5个元素。

2、解题思想

(1)暴力求解(时间O(n^2),空间0)

      找出序列中的所有子串,判断每个子串是否包含所有元素。时间复杂度为O(n^2),这种做法面试通不过。

(2)使用哈希表(时间O(n),空间O(m)--m为不同元素个数)

    首先遍历序列,找出序列中的有元素,用一个map来保存每个元素在序列中已经找到的个数,初时刻,这个map的所有元素的初始值全部为0。使用两个指针beginend分表保存序列的窗口,使用一个count变量保存已经找到的序列中不同元素的个数。

    从头开始遍历序列,遇到一个元素elem时,如果map[elem]的值为0,则map[elem]加1且count加1。如果map[elem]的值大于0,则map[elem]加1,count不变。当count的值等于序列中不相同的元素个数时,表示找到一个满足需求的子窗口,此时保存这个窗口的大小和起始位置。接着begin指针往后移动,直到map中有一个元素的map[elem]为0,然后count--,寻找下一个满足需求的窗口。代码实现如下:

#include<iostream>
#include<vector>
#include<map>
using namespace std;

/*
	找出包含序列的所有元素的最小长度子序列
*/
void MinLengthSeq(vector<int> input) {
	int begin = 0;                         //保存窗口的起始位置
	int count = 0;                         //保存已找到的不同元素的个数
	int windos = input.size();             //保存最小的窗口大小
	int start = 0;                         //保存所找到的最小窗口的位置
	map<int, int> has_found_elem;          //统计找到的每个元素的个数

	for (int i = 0; i < input.size(); i++)
		has_found_elem[input[i]] = 0;		

	for (int i = 0; i < input.size(); i++) {
		if (has_found_elem[input[i]] == 0) {     //如果找到一个不同的元素,count++,map中元素个数加一
			has_found_elem[input[i]]++;
			count++;
		}
		else                                     //如果找到相同的元素,count不变,map中元素个数加一
			has_found_elem[input[i]]++;        

		if (count == has_found_elem.size()) {    //如果count大小等于不相同的元素个数,则找到一个窗口
			if (windos > i - begin + 1) {
				windos = i - begin + 1;
				start = begin;
			}
			while (has_found_elem[input[begin]] > 0) { //begin指针往后移动机,直到map中有一个元素个数为0
				has_found_elem[input[begin]]--;		
				if (has_found_elem[input[begin++]] == 0)
					break;	
			}
			count--;                             //count--,去寻找下一个满足要求的窗口
		}
	}
	cout << "length:" << windos << endl;
	cout << "start:" << start << endl;

}

参考:https://blog.csdn.net/yangwenxue_admin/article/details/44568069

猜你喜欢

转载自blog.csdn.net/MOU_IT/article/details/88751693