题目描述
给定一个字符串,问是否能通过添加一个字母将其变为回文串。
输入描述:
一行一个由小写字母构成的字符串,字符串长度小于等于10。
输出描述:
输出答案(YESNO).
输入例子:
coco
输出例子:
YES
解题
暴力,在所有位置添加一个字母:a - z ,判断是否可以是回文串,时间复杂度是不是太长了。
下面一个半暴力
1.原字符串str 和其逆序字符串revstr进行比较
2.去除两侧相等的元素,次数两个指针为low high
3.low high 对于两个不相同的元素
4.low = str.length() 说明原始字符串已经是回文串 返回true
5.high - low == 1 说明这两个字符串不一样,并且他们中间也没有了字符串,可以通过插入其中一个字符串形成回文串
6.下面就比较复杂了
7.对str 和revstr 的low -- high进行比较,主要分成下面两个部分比较
8.str 的low --high-1 部分和 revstr 的low+1 -- high 部分,判断是否是回文串,是回文串,就可以添加一个字符low 或者 high形成回文串
9.str 的low+1 --high 部分和 revstr 的low -- high-1部分 ,同样判断是否是回文串
import java.util.Scanner; public class Main{ public static void main(String [] args){ Main m = new Main(); m.run(); } public void run(){ Scanner in = new Scanner(System.in); String str; String revStr; while(in.hasNext()){ str = in.nextLine(); revStr = reverse(str); if(isInsertPalindromic(str,revStr)){ System.out.println("YES"); }else{ System.out.println("NO"); } } } public boolean isInsertPalindromic(String str,String revStr){ int low = 0; int high = str.length() - 1; if(low < high){ while(low<= high && str.charAt(low) == revStr.charAt(low)) low++; if(low==high + 1)// 本来就是回文串 添加一个字母也可以形成回文串 return true; while(low<=high && str.charAt(high) == revStr.charAt(high)) high--; if(high - low == 1) // 中间没有字母,只需增加一个就可以形成回文串 return true; // 这里说明两个字符串比较出现不相等的情况, // str low - high - 1 和 revStr low+1 - high 部分是回文串则整体就是回文串 String strTmp = str.substring(low,high); String revTmp = revStr.substring(low+1,high+1); if(isPalindromic(strTmp,revTmp)) return true; // str low+1 - high 和 revStr low - high -1 部分是回文串则整体就是回文串 strTmp = str.substring(low+1,high+1); revTmp = revStr.substring(low,high); if(isPalindromic(strTmp,revTmp)) return true; } return false; } public boolean isPalindromic(String s1,String s2){ if(s1.length() != s2.length()) return false; int low = 0; int high = s1.length() - 1; while(low <= high && s1.charAt(low) == s2.charAt(low)) low++; if(low == high+1) return true; return false; } public String reverse(String str){ String revStr=""; for(int i = str.length() -1;i>=0;i--){ revStr+= str.charAt(i); } return revStr; } }
讨论中看到可以通过、判断原字符串和翻转字符串的最长公共子序列长度是否比原字符串长度小1或相等
参考讨论
插入一个字符串是回文,那么,删除一个字符串也一定是回文
时间复杂度O(n^2)
import java.util.*; public class Main{ public static void main(String[] args){ Scanner in = new Scanner(System.in); boolean flag = true; while(in.hasNext()){ char[] A = in.nextLine().toCharArray(); flag = true; if(A==null||A.length<=1){ System.out.println("YES"); continue; } for(int i=0;i<A.length;i++){ if(isPalindromic(A,0,A.length-1,i)){ flag = false; break; } } if(flag) System.out.println("NO"); else System.out.println("YES"); } } // 数组A中,去除 第 k 位置后判断是否回文 public static boolean isPalindromic(char[] A,int left,int right,int k){ if(left==right || left - right==-1) return true; while(left<right){ if(left==k) left++; if(right==k) right--; if(left<right && A[left] == A[right]){ left++; right--; }else return false; } return true; } }