這類問題都是求乙個滿足某種條件的連續的段,相對於子串行。字串和陣列的主要區別是,前者因為由字元而不是數值組成,一般不會有最大值,最小值,求和這種問題。對於字串的子串問題,一般條件是子串符合某種pattern(回文、有序)或者滿足某種統計特徵(子串內無重複字元,最多重複2次,包含了給定字符集的所有字元,字元個數均等)
子陣列問題包含了子串問題,但是可以用子陣列的一些數值計算特徵值(比如sum, max)作為條件,最大子陣列和, 最短的和為target的子陣列
最基本的暴力列舉框架是o(n^3)的,列舉所有子陣列需要o(n^2),然後判斷子陣列是否滿足條件(計算特徵值,check pattern),一般要check子陣列內所有元素,是o(n)的,整體就是o(n^3)。
暴力列舉的框架就是由 列舉+計算子陣列特徵值兩部分組成,都有可能優化,計算特徵值的優化是累加利用之前的結果,比如 a[i...j]上的sum或 max 可以由a[i...j-1]上的結果o(1)累加而來,不用遍歷子陣列。列舉的可能的優化是滑動視窗法,(即內層迴圈不回退的雙重迴圈)。
計算特徵值的的優化還可以通過預處理,先求字首和陣列,然後就可以o(1)得到任意子陣列a[i...j]的和,或者做一棵區間樹,之後都可以o(logn)查詢。
關於子陣列的條件,滿足某種pattern的(回文,有序)沒辦法,就得o(n)的去check,關於統計特徵,有些可以轉換為特徵值,比如:
1)01串找最長的01出現次數相等的子串,通過把『0』當成-1,『1』當成1,可以轉化為最長的sum為0的子陣列問題
2)最長的可整合子陣列(排序後連續,e.g. [3, 2,1]),可以轉化為,max - min == j - i
import sys
def longestconsecutivesubarray(a):
ans = 0
for i in xrange(len(a)):
lo, hi, s = sys.maxint, -sys.maxint - 1, set()
for j in xrange(i, len(a)):
if a[j] in s: continue
s.add(a[j])
lo, hi = min(lo, a[j]), max(hi, a[j])
if hi - lo == j - i:
ans = max(ans, j - i + 1)
return ans
子串行 子串
def foo num list 求陣列中最大子串行的和,子串行必須連續 length len num list max value 10000000000 tmp 0 for i in range length tmp max tmp num list i num list i max value...
子串行 子串
1 第一種思路模板是乙個一維的 dp 陣列 int n array.length int dp newint n for int i 1 i n i 例如 最長遞增子串行 在這個思路中 dp 陣列的定義是 在子陣列 array 0 i 中,我們要求的子串行 最長遞增子串行 的長度是 dp i 2 第...
LIS 和 LCS 子串行子串問題
abcdefg 子串行是可以不連續的 eg acg 子串是必須連續的eg abc 1 lc子串行 子串行是看某點 可不選 之前能組成的所有 public int longestcommonsubsequence string a,string b else return dp m n 2 lc子串 ...