問題一:(最長回文子串)給定乙個字串 s,找到 s 中最長的回文子串。
第一眼的想法是暴力法,由於其時間複雜度高達o(n^3),當s過長時效率會特別低。
方法一:中心擴充套件演算法
其思想就是遍歷一遍字串,其中在每乙個點都進行以其為中心而均勻展開(分奇偶),然後找到每個點能夠展開到的最大值,最後也就不難得到最長回文串了。
具體**如下:
public string longestpalindrome1(string s)
}return s.substring(start, end + 1);
}private int expandaroundcenter(string s, int left, int right)
return r - l - 1;
}
方法二:manacher 演算法
其思想就是將原字串用同一的符號擴充套件兩倍+1,這樣可以巧妙的迴避了奇偶回文串的問題。然後再定義乙個類似計數排序的乙個計數陣列,用它在擴充套件後的字串上進行型別中心擴充套件的操作。最終的manacher 演算法還有乙個對計數陣列的乙個演算法優化。
具體**如下:
public string longestpalindrome2(string s)
ah[2 * s.length()] = '#';
int arr = manacher1(ah);
return s.substring((arr[1] - arr[0]) / 2, (arr[1] + arr[0]) / 2);
}private int manacher1(char t)
for (int i = 0; i < len.length; i++)
ans = math.max(ans, len[i]);
}arr[0] = ans - 1;
int i = 0;
while (len[i] != ans)
arr[1] = i;
return arr;
}private int manacher2(char t) else
while ((i - len[i] >= 0) && (i + len[i] < len.length) && t[i - len[i]] == t[i + len[i]])
if (len[i] + i > mx)
ans = math.max(ans, len[i]);
}arr[0] = ans - 1;
int i = 0;
while (len[i] != ans)
arr[1] = i;
return arr;
}
問題二:(最短回文串)給定乙個字串 s,你可以通過在字串前面新增字元將其轉換為回文串。找到並返回可以用這種方式轉換的最短回文串。
思路:由於只能在字串的前面新增字元,所以不由的想出要先找到原字串的最長字首回文串,下面給出兩種方法。
方法一:直接尋找
這裡需要倒序遍歷字串,定義一頭一尾兩個指標,再用乙個while的內迴圈來取得其最長的字首回文串。
具體**如下:
public string shortestpalindrome1(string s)
int x = getfronts(s);
return new stringbuilder(s.substring(x + 1)).reverse().tostring() + s;
}//獲得原字串的最長字首回文字串長度
private int getfronts(string s)
else
}if (a >= b)
a = 0;}}
return 0;
}
方法二:kmp演算法的next陣列
這個next陣列也很類似計數排序的那個計數陣列,只不過這個陣列記錄的是當前位置的最大字首數,有了這個陣列,最長字首回文串也就手到擒來了。
具體**如下:
public string shortestpalindrome2(string s)
string temp = s + "#" + new stringbuilder(s).reverse().tostring() + "#";
//中間那個#是為了把兩段字串分隔開,避免產生干擾
int next = getnext1(temp);
int index = next[temp.length()-1]; //取得最長字首回文字串的下標
return new stringbuilder(s.substring(index)).reverse().tostring() + s;
}private int getnext1(string p)
}return next;
}
特別是後面的manacher 演算法和kmp演算法都很巧妙也很有回味價值。 動態規劃的兩個經典問題
weight 原始物品陣列,values 為其所對應的價值,n 表示物品的個數,w 表示揹包所能承受的最大重量 public void knapsack3 int weight,int values,int n,int w states 0 0 0 if weight 0 w for int i 1...
字串處理的兩個問題
處理字元是c語言中的常見操作,有兩個問題需要討論 一是判斷字元處理結束的標誌是空字元還是換行符,二是迴圈處理字元時,迴圈次數是字元陣列的容量大小還是實際輸入字元的個數。舉例 鍵盤輸入一行字元,統計大寫字元的個數。本例可用兩種方法程式設計,第一種方法的 如下 include int main 下面是第...
動態規劃的兩個經典問題 01揹包
學動態規劃要從經典問題開始 by lrj 答應了小q要寫這個的.哎.先說那個什麼01揹包.為什麼叫揹包呢?因為這些問題的原型是說有很多東西,每個東西都有體積,也有價值,你要去春遊,要選一些東西放到揹包裡.問題是要怎麼選才能在總體積不超過揹包的體積的前提下,讓總價值最大.為什麼是0 1呢?因為每種東西...