点击这里查看原文

假设一个数组仅仅由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. Android进阶之大话设计模式

    一般来说,常用的设计模式有以下八种:单例.工厂.观察者.代理.命令.适配器.合成.访问者 单例模式:目的是为了让系统中只有一个调用对象,缺点是单例使其他程序过分依赖它,而且不同单例运行在不同进程中,使 ...

  2. Codeforces Round #320 (Div. 1) [Bayan Thanks-Round] C. Weakness and Poorness 三分 dp

    C. Weakness and Poorness Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/contest/5 ...

  3. NYOJ109 数列转换 【守恒法】

    数列转换 时间限制:3000 ms  |  内存限制:65535 KB 难度:3 描写叙述 有一个数列a1,a2,a3...an,每次能够从中随意选三个相邻的数ai-1 ,ai , ai+1 ,进行例 ...

  4. Webx学习(一)

    什么是webx Webx3_Guide_Book中是这样介绍的: Webx是一套基于Java Servlet API的通用Web框架. Webx致力于提供一套极具扩展性的机制.来满足Web应用不断变化 ...

  5. "无法启动程序,因为计算机中丢失*.dll” 运行exe错误解决方法

    笔者把编译生成的win32 Release exe文件复制到另外一台电脑上,却发现程序不能运行,报错如下: 报错提示缺失动态链接库pcl_common_release.dll,那为什么在编译生成的电脑 ...

  6. iOS开发——新特性OC篇&IOS9 系统新特性

    IOS9 系统新特性 2015年6月89号凌晨召开的WWDC 2015苹果开发者大会发布了全新的iOS 9系统,PC6小编今天给大家整理了这次iOS9的系统更新带来了哪些新的功能与升级,本次新功能一览 ...

  7. ajax调用webService中的方法

    页面代码 <%@ Page Language="C#" AutoEventWireup="true" CodeFile="Index.aspx. ...

  8. eclipse+ADT 进行android应用签名详解

    http://jojol-zhou.iteye.com/blog/719428 1.Eclipse工程中右键工程,弹出选项中选择 android工具-生成签名应用包: 2.选择需要打包的android ...

  9. Mini2440 DM9000 驱动分析(一)

    Mini2440 DM9000 驱动分析(一) 硬件特性 Mini2440开发板上DM9000的电气连接和Mach-mini2440.c文件的关系: PW_RST 连接到复位按键,复位按键按下,低电平 ...

  10. HTML实现跳转到页面指定位置

    <a href="#page1">跳转到页面1</a> <a href="#page2">跳转到页面2</a> ...