本专栏目录
蓝桥杯算法竞赛大纲数论相关(Java)
枚举相关(Java)
对象排序(Java)
字符串相关(Java)
排序相关算法(Java)
记忆化搜索(Java)
树论相关(Java)
图论相关(Java)
堆(Java)
贪心(Java)
文章目录
- 内置方法
- 最长对称字符串
- 最长回文子串
- KMP
- 马拉车算法
内置方法
package 字符串;
public class _内置方法 {
public static void main(String[] args) {
String s = "abcdefghijklmnopq...";
int ind = s.indexOf("gh");
ind = s.lastIndexOf("gh");
boolean flag = s.contains("def");
int f = s.compareTo("abcde");
String newS = s.substring(3);
String s2 = s.replace("d","");
flag = s.startsWith("abc");
flag = s.endsWith("...");
String[] split = s.split(" ");
ind = s.charAt('i');
s.toCharArray();
s.equals("....");
s.concat("123");
s.strip();
s.trim();
s.toLowerCase();
s.toUpperCase();
}
}
最长对称字符串
package 字符串;
import java.util.Scanner;
public class _最长对称字符串 {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
String line = scan.nextLine();
// 可能的长度
for (int k = line.length(); k >= 2; k--) {
// 对称字符串开始的位置
for (int st = 0; st + k - 1 <= line.length() - 1; st++) {
int i=st,j = st+k-1; // 一个从头向后,一个从后向前。
for (; i <= j; i++,j--) { // 对称检测
if (line.charAt(i)!=line.charAt(j)){
break;
}
}
if (i>=j){ // 如果在k长度字符串存在对称,则输出。
System.out.println(k);
return;
}
}
}
System.out.println(1);
}
}
最长回文子串
package 字符串;
import java.util.Scanner;
public class _最长回文子串 {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
String s = scan.nextLine();
s = longestPalindrome(s);
System.out.println(s);
}
public static String longestPalindrome(String s) {
int len = s.length();
if (len==1){
return s;
}
char[] dest = insertChar(s, '#');
int slen = dest.length;
int[] p = new int[slen];
int maxRight = 0;
int center = 0;
// 这里的maxlen在s中是总的回文字符串的长度,在dest里面是右半径的长度
int maxlen = 1;
//原字符串中回文起始的位置
int begin = 0;
for (int i = 0; i < slen; i++) {
// 更新p[i] 状态转移方程
if (i<maxRight){
int mirror = 2 * center - i;
p[i] = Math.min(p[mirror], maxRight - i);
}
// 中心扩散
int left = i - p[i] - 1;
int right = i + p[i] + 1;
while (left>=0 && right<=slen-1 && dest[left]== dest[right]){
left--;
right++;
p[i]++;
}
// 更新maxRight
if (i + p[i] > maxRight){
maxRight = i + p[i];
center = i;
}
// 更新begin和maxlen
if (p[i] > maxlen){
maxlen = p[i];
begin = (i - maxlen) / 2;
}
}
return s.substring(begin, begin + maxlen);
}
public static char[] insertChar(String s, char c){
char[] src = s.toCharArray();
char[] dest = new char[src.length * 2 + 1];
for (int i = 0; i < dest.length; i++) {
if ((i&1)==0){
dest[i] = c;
}else {
dest[i] = src[i/2];
}
}
return dest;
}
}
KMP
package 字符串;
public class _KMP {
public static void main(String[] args) {
String s1 = "abadcdacdba";
String s2 = "dacd";
// 获取s2的next数组
int[] next = getNextArr(s2);
// s2在s1中的位置
int index = kmp(s1,s2,next);
}
// kmp
public static int kmp(String s1, String s2, int[] next){
char[] c1 = s1.toCharArray();
char[] c2 = s2.toCharArray();
int j = 0;
for (int i = 0; i < c1.length; i++) {
while (j>0 && c1[i]!=c2[j]){
j = next[j-1];
}
if (c1[i]==c2[j]){
j++;
}
if (j==c2.length){
return i-j+1;
}
}
return -1;
}
// 获取next数组
public static int[] getNextArr(String s) {
char[] chs = s.toCharArray();
int[] next = new int[s.length()];
next[0] = 0;
int j = 0;
for (int i = 1; i < next.length; i++) {
while (j>0 && chs[i]!=chs[j]){
j = next[j-1];
}
if (chs[i]==chs[j]){
j++;
next[i] = j;
}
}
return next;
}
}
马拉车算法
package 字符串;
// https://leetcode-cn.com/problems/longest-palindromic-substring/solution/zui-chang-hui-wen-zi-chuan-by-leetcode-solution/
public class _马拉车算法 {
public static void main(String[] args) {
String s = "abba";
longestPailndrome(s);
}
public static String longestPailndrome(String s){
int len = s.length();
if (len<2){
return s;
}
String str = addDividers(s, '#');
int slen = str.length();
// p[i]: 以预处理字符串下标i为中心的回文半径(奇数长度时不包括中心)
int[] p = new int[slen];
// 通过中心扩散的方式能够扩散的最右边的下标
int maxRight = 0;
// 与maxRight对应的中心字符的下标
int center = 0;
int maxLen = 1;
int begin = 0;
char[] charArray = str.toCharArray();
for (int i = 0; i < slen; i++) {
if (i<maxRight){
int mirror = 2 * center - i;
p[i] = Math.min(maxRight-i, p[mirror]);
}
// 尝试使用中心扩散法,更新p[i]的值
int left = i - (1 + p[i]);
int right = i + (1 + p[i]);
while (left >= 0 && right < slen && charArray[left]==charArray[right]){
p[i]++;
left--;
right++;
}
// 更新maxRight,它是遍历过的 i 的 i+p[i] 的最大者
if (i + p[i] > maxRight){
maxRight = i + p[i];
center = i;
}
// 更新begin 和 maxLen
if (p[i] > maxLen){
maxLen = p[i];
begin = (i - maxLen) / 2;
}
}
return s.substring(begin, begin + maxLen);
}
private static String addDividers(String s, char c) {
char[] src = s.toCharArray();
char[] dest = new char[src.length*2+1];
for (int i = 0; i < dest.length; i++) {
if ((i&1)==0){
dest[i] = c;
}else {
dest[i] = src[i/2];
}
}
return new String(dest);
}
}