算法 – 如何找到包含序列的所有元素的最小长度子序列

栏目: 编程工具 · 发布时间: 6年前

内容简介:注意:S:{1,2,4,8,9}中有5个不同的元素.最小长度子序列必须包含所有这5个元素.http://stackoverflow.com/questions/6896531/how-to-find-minimal-length-subsequence-that-contains-all-element-of-a-sequence

注意:S:{1,2,4,8,9}中有5个不同的元素.最小长度子序列必须包含所有这5个元素.

算法:

首先,确定阵列中不同元素的数量 – 这可以在线性时间内轻松完成.让有不同的元素.

分配大小为10 ^ 5的数组cur,每个数组cur显示当前子序列中使用的每个元素的数量(见后文).

持有一个cnt变量,显示在考虑的序列中当前有多少个不同的元素.现在,采用两个索引,以下列方式开始和结束数组:

>初始化cnt并开始为0,结束为-1(第一次增量后为0).然后尽可能执行如下:

>如果cnt!= k:

2.1.增量结束.如果end已经是数组的结尾,那么break.如果cur [array [end]]为零,则增加cnt.增量cur [array [end]].

其他:

2.2 {

尝试增加begin迭代器:while cur [array [begin]]> 1,递减它,并增加begin(cur [array [begin]]> 1意味着我们在我们当前的子序列中有另一个这样的元素).毕竟,将[开始,结束]间隔与当前答案进行比较,如果它更好,存储它.

}

在进一步的过程变得不可能之后,你得到了答案.复杂度是O(n) – 只是通过数组中的两个Interator.

执行C:

#include <iostream>

using namespace std;

const int MAXSIZE = 10000;

int arr[ MAXSIZE ];
int cur[ MAXSIZE ];

int main ()
{
   int n; // the size of array
   // read n and the array

   cin >> n;
   for( int i = 0; i < n; ++i )
      cin >> arr[ i ];

   int k = 0;
   for( int i = 0; i < n; ++i )
   {
      if( cur[ arr[ i ] ] == 0 )
         ++k;
      ++cur[ arr[ i ] ];
   }

   // now k is the number of distinct elements

   memset( cur, 0, sizeof( cur )); // we need this array anew
   int begin = 0, end = -1; // to make it 0 after first increment
   int best = -1; // best answer currently found
   int ansbegin, ansend; // interval of the best answer currently found
   int cnt = 0; // distinct elements in current subsequence

   while(1)
   {
      if( cnt < k )
      {
         ++end;
         if( end == n )
            break;
         if( cur[ arr[ end ]] == 0 )
            ++cnt; // this elements wasn't present in current subsequence;
         ++cur[ arr[ end ]];
         continue;
      }
      // if we're here it means that [begin, end] interval contains all distinct elements
      // try to shrink it from behind
      while( cur[ arr[ begin ]] > 1 ) // we have another such element later in the subsequence
      {
         --cur[ arr[ begin ]];
         ++begin;
      }
      // now, compare [begin, end] with the best answer found yet
      if( best == -1 || end - begin < best )
      {
         best = end - begin;
         ansbegin = begin;
         ansend = end;
      }
      // now increment the begin iterator to make cur < k and begin increasing the end iterator again
      --cur[ arr[ begin]];
      ++begin;
      --cnt;
   }

   // output the [ansbegin, ansend] interval as it's the answer to the problem

   cout << ansbegin << ' ' << ansend << endl;
   for( int i = ansbegin; i <= ansend; ++i )
      cout << arr[ i ] << ' ';
   cout << endl;

   return 0;
}

http://stackoverflow.com/questions/6896531/how-to-find-minimal-length-subsequence-that-contains-all-element-of-a-sequence


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

UML和模式应用

UML和模式应用

拉曼 / 李洋、郑䶮 / 机械工业出版社 / 2006-5 / 66.00元

《UML和模式应用(原书第3版)》英文版面世以来,广受业界专家和读者的好评,历经3个版本的锤炼,吸收了大量OOA,D的精华思想和现代实践方法。全书叙述清晰、用词精炼、构思巧妙,将面向对象分析设计的概念、过程、方法、原则和个人的实践建议娓娓道来,以实例为证,将软件的分析和设计的过程叙述得如逻辑推理一般,于细节处见真知。 《UML和模式应用(原书第3版)》是一本经典的面向对象分析设计技术的入门书......一起来看看 《UML和模式应用》 这本书的介绍吧!

JS 压缩/解压工具
JS 压缩/解压工具

在线压缩/解压 JS 代码

MD5 加密
MD5 加密

MD5 加密工具

正则表达式在线测试
正则表达式在线测试

正则表达式在线测试