点击这里查看原文

假设一个数组仅仅由1和-1组成,求该数组的和为0的最长子串的长度。

例如:

{1,-1,1,-1,1,1,1} 输出:4.

昨天机试的时候做到这道题,不会做,今天思考一下。

普通的解法

枚举所有的子串,然后得到和为0的最长的长度,复杂度是O(n*n),这个应该会超时,昨天只能保存,不能运行,我猜这样应该不行,需要下面方法。其实看到这题,我想到的是最长回文子串这道题,仔细想想,还是挺像的,该搞一个传送门的。

正确的解法

解法:动态规划,dp0[i]表示以i结尾的加和为0 得到最长子串长度,dp1[i] 表示以i结尾的加和为1的最长子串长度,dp2[i]表示以i结尾的加和为-1 的最长子串长度。于是可以得到下面的递推关系:

上面这段话摘自那个博客,n的平方复杂度不行,那大概就是nlogn或者n,需要考虑dp,然后分析,数组只有1或者-1,然后需要获得结果为0的长度,所以碰到1,我们希望能知道前面和为-1的最长,遇到-1,我们需要知道和为1的最长,所以我们就需要维护到当前位置,以当前位置结尾的和为0,1,-1的最长长度,然后思考怎么递推。显然,1 + 0 = 1, 1 + (-1) = 0,转移到1和0,很容易,转移到-1,怎么处理,什么结果加上1能得到结果是-1,当然是-2,但是我没维护和为2的,这就需要巧妙的思想。

利用当前段的结果为0,加上这段之前的结果为-1,这样就能导出当前段为-1的,这样的思想很巧妙,仔细想想怎么回事,是不是有点kmp,马拉车算法之类的思想。

好了,贴一下那位大神的代码:

#include<iostream>
#include<vector>
using namespace std;
int getLongestLength(int array[],int size){
if(size<=1) return 0;
vector<int>dp0(size);
vector<int>dp1(size);
vector<int>dp2(size);
dp0[0]=0;
if(array[0]==1){
dp1[0]=1;
dp2[0]=0;
}else{
dp1[0]=0;
dp2[0]=1;
}
int result =0;
for(int i =1;i<size;i++){
if(array[i]==1){
dp0[i]=dp2[i-1]==0?0:dp2[i-1]+1;
dp1[i]=dp0[i-1]==0?1:dp0[i-1]+1;
dp2[i]=dp0[i]==0?0:dp2[i-dp0[i]]+dp0[i];
}else{
dp0[i]=dp1[i-1]==0?0:dp1[i-1]+ 1;
dp1[i]=dp0[i]==0?0:dp1[i-dp0[i]]+dp0[0];
dp2[i]=dp0[i-1]==0?0:dp0[i-1]+1;
}
if(result<dp0[i]) result =dp0[i];
} return result;
}
int main(){
int nums[]={-1,1,-1,1};
cout<<getLongestLength(nums,4);
}

我认为也需要判断一下dp2[i-dp0[i]]的结果不为0,才行。没有画图,不知道解释清楚没有。

还可以这样做,维护前缀和s,i<j, s(j) = s(i)的时候,可以知道i + 1 到j和为0,即可满足要求。这个好像容易理解一些。

百度搜索1,-1,最长字串 可以找到解法。延伸到数组里面只有0和1,比如只有a和b,求最长子串a和b的个数相等之类的。还有什么变形,想出来再记下来吧。

int getLongestString(vector<int> & v) {
int n = v.size();
if(n < 2) return 0;
map<int, int> m;
int s = 0;
int res = 0;
for(int i = 0; i < n; i++) {
s += v[i];
if(s == 0) {
res = max(res, i + 1); continue;
}
if(!m.count(s)) {
m[s] = i;
} else {
int len = i - m[s];
res = max(res, len);
}
}
return res;
}

[getLongestLength] 加和为0的最长子串长度的更多相关文章

  1. Uva 12012 Detection of Extraterrestrial 求循环节个数为1-n的最长子串长度 KMP

    题目链接:option=com_onlinejudge&Itemid=8&page=show_problem&problem=3163">点击打开链接 题意: ...

  2. python实现求最长子串长度

    给定一个字符串,求它最长的回文子串长度,例如输入字符串'35534321',它的最长回文子串是'3553',所以返回4. 最容易想到的办法是枚举出所有的子串,然后一一判断是否为回文串,返回最长的回文子 ...

  3. Leetcode3--->无重复字符的最长子串长度

    题目:给定一个字符串string,找出string中无重复字符的最长子串. 举例: Given "abcabcbb", the answer is "abc", ...

  4. leetcode3:不重复的最长子串长度

    package hashmap; import java.util.HashMap; import java.util.Map; public class hashmap { public stati ...

  5. 【LeetCode】无重复字符串最长子串

    题目描述 给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度. 示例 1: 输入: "abcabcbb" 输出: 3 解释: 因为无重复字符的最长子串是 "a ...

  6. leecode第三题(无重复字符的最长子串)

    class Solution { public: int lengthOfLongestSubstring(string s) { int len=s.size(); ||len==)//边界 ret ...

  7. [LeetCode] Longest Substring with At Most Two Distinct Characters 最多有两个不同字符的最长子串

    Given a string S, find the length of the longest substring T that contains at most two distinct char ...

  8. Problem 2128 最长子串(kmp+strstr好题经典)

     Problem 2128 最长子串 Accept: 134    Submit: 523Time Limit: 3000 mSec    Memory Limit : 65536 KB  Probl ...

  9. leetcode刷题第三天<无重复字符的最长子串>

    给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度. 示例 : 输入: "abcabcbb" 输出: 解释: 因为无重复字符的最长子串是 . 示例 : 输入: &quo ...

随机推荐

  1. css中文字体unicode对照表

    为什么要使用Unicode编码代替中文字体 在CSS中使用中文字体通常直接设置字体名称,比如设置字体为宋体:font-family:’宋体’:但因此产生的一个问题是,如果默认编码并不是UTF-8,这会 ...

  2. iOS相机权限、相册权限、定位权限判断

    1.判断用户是否有权限访问相册 #import <AssetsLibrary/AssetsLibrary.h> ALAuthorizationStatus author = [ALAsse ...

  3. ThinkPHP3.2.3新特性之:数据库设置

    ThinkPHP3.2.3版本数据库驱动采用PDO完全重写,配置和使用上面也比之前版本更加灵活和强大,我们来了解下如何使用. 首先,3.2.3的数据库配置信息有所调整,完整的数据库设置包括: /* 数 ...

  4. Cocos2d-x 3.x 资料整理

     cocos2d-x-3.0rc0新project的分辨率设置和控制台输出信息 http://kome2000.blog.51cto.com/969562/1379704 Cocos2d-x 3. ...

  5. 在Image控件中绘制文字

    //Canvas 在Image控件中绘制文字 procedure TForm1.Button1Click(Sender: TObject);begin  image1.Canvas.Font.Size ...

  6. php实用函数整理

    1. 排序:array_multisort 可以对多位数组的多个字段进行排序 例子1如下: //自定义数组排序--按转发数从高到低排序 function sortSelfRc($oneLayer){ ...

  7. Mybatis案例

    MyBatis MyBatis 是支持普通 SQL 查询,存储过程和高级映射的优秀持久层框架. MyBatis 消除了几乎所有的 JDBC 代码和参数的手工设置以及对结果集的检索. MyBatis 可 ...

  8. ambassador docker container linking

    http://docs.docker.com/articles/ambassador_pattern_linking/

  9. 给Chrome和Firefox添加js脚本作为插件的方法

    为了防止无良网站的爬虫抓取文章,特此标识,转载请注明文章出处.LaplaceDemon/ShiJiaqi. http://www.cnblogs.com/shijiaqi1066/p/5973141. ...

  10. 嵌入式中 MMU的功能

    学习嵌入式才发现要看的书太多,外面的世界很精彩啊,现在来说说MMU吧,MMU是Memory Management Unit的缩写,是用来管理虚拟内存系统的器件. MMU通常是CPU的一部分,本身有少量 ...