zoukankan      html  css  js  c++  java
  • 伴随待字闺中的生命周期分析

    标题来源,待字闺中,原创@陈利人 。欢迎大家继续关注微信公众账号“待字闺中”

    原题

    给定一个数组,数组中仅仅包括0和1。

    请找到一个最长的子序列,当中0和1的数量是同样的。

    例1:10101010 结果就是其本身。

    例2:1101000 结果是110100

    请大家展开自己的思路。

    分析

    这个题目,看起来比較简单,一些同学可能觉得题目的描写叙述符合动态规划的特征,然后就開始用动态规划解,努力找状态转移方程。

    这些同学的感觉,是非常正确的。

    但,找状态转移方程,我们要对原来的数组进行变换一下。

    原来是0和1的串,我们将0都换为-1。

    这样题目目标就变成。找到一个最长的子串,子串数字和是0。

    设原数组为A, DP[i]表示从0開始到i的子数组和。DP遍历一遍数组就可以。例1中的数组产生的DP为:

    0 1 2 3 4 5 6 7
    1 0 1 0 1 0 1 0

    这个样例,最后一个值是0,而且长度是偶数位。直接满足了结果。

    再看样例2:

    0 1 2 3 4 5 6
    1 2 1 2 1 0 -1

    5的位置为0,最长子串从0開始到5,长度为6。

    上面这两个样例,所求的子串都是从头開始,假设不是从头開始,会是什么样的呢?看这个样例:1101100

    0 1 2 3 4 5 6
    1 2 1 2 3 2 1

    通过观察上面的表格。我们能够得到。DP[0]==DP[6]==DP[2],DP[1]==DP[3]. 依据DP的定义,假设DP[i]==DP[j]。i 一种方法。我们用map保存DP的值到位置的映射,例如以下表:

    DP值 位置 最大位置 最小位置 最大长度
    1 0,2,6 6 0 6
    2 1,3 3 1 2
    3 4 4 4 0
    最长子串长度       6
     

    我们终于的算法。要综合考虑最长串是否从头開始的。 上面的这个思路。时间复杂度是O(n),空间复杂度也是O(n).详细代码例如以下:

    struct node//保存hash表中的最大最小位置
    {
    	int minIndex;
    	int maxIndex;
    	node(int a=0,int b=0):minIndex(a),maxIndex(b){}
    };
    void InsetIntoHashMap(map<int,node>& hashMap,int key,int index)//把”和“及位置插入hash表中
    {
    	map<int,node>::iterator iter = hashMap.find(key);
    	if(iter == hashMap.end())//该和第一次出现
    	{
    		node value(index,index);
    		hashMap.insert(make_pair(key,value));
    	}
    	else//改动该和的最大最小位置
    	{
    		if(hashMap[key].minIndex > index ) hashMap[key].minIndex = index;
    		else if (hashMap[key].maxIndex < index)hashMap[key].maxIndex = index;
    	}
    }
    vector<int> LongSubSeq(vector<int>& data)
    {
    	int length = data.size(),i,begin=0,end=0,size = 0;
    	vector<int> numbers(length);//把原数组的0转换为1
    	vector<int> sum(length,0);//存放到眼下为止的和
    	for(i=0;i<length;i++)
    	{
    		if(data[i] == 0)numbers[i] = -1;
    		else numbers[i] = 1;
    	}
    	map<int,node> hashMap;
    	node value(-1,-1);
    	hashMap[0] = value;//初始化,由于要做差。而第-1个位置相当于是从和为0開始的
    	for(i=0;i<length;i++) 
    	{
    		if(i != 0) sum[i] = sum[i-1] + numbers[i];
    		else sum[i] = numbers[i];
    		InsetIntoHashMap(hashMap,sum[i],i);
    	}
    	vector<int> res;
    	map<int,node>::iterator iter = hashMap.begin();
    	for(;iter != hashMap.end();iter ++)
    	{
    		if((iter->second).maxIndex - (iter->second).minIndex > size)
    		{
    			size = (iter->second).maxIndex - (iter->second).minIndex;
    			begin = (iter->second).minIndex;
    			end = (iter->second).maxIndex;
    		}
    	}
    	res.push_back(begin);//保存開始和结束的位置
    	res.push_back(end);
    	return res;
    }

    如果您有问题,请指正,谢谢

    版权声明:本文博主原创文章,博客,未经同意不得转载。

  • 相关阅读:
    hdu 1199 Color the Ball 离散线段树
    poj 2623 Sequence Median 堆的灵活运用
    hdu 2251 Dungeon Master bfs
    HDU 1166 敌兵布阵 线段树
    UVALive 4426 Blast the Enemy! 计算几何求重心
    UVALive 4425 Another Brick in the Wall 暴力
    UVALive 4423 String LD 暴力
    UVALive 4872 Underground Cables 最小生成树
    UVALive 4870 Roller Coaster 01背包
    UVALive 4869 Profits DP
  • 原文地址:https://www.cnblogs.com/blfshiye/p/4818166.html
Copyright © 2011-2022 走看看