首页 > 试题广场 >

回文串

[编程题]回文串
  • 热度指数:17231 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 32M,其他语言64M
  • 算法知识视频讲解
给定一个字符串,问是否能通过添加一个字母将其变为回文串。

输入描述:
一行一个由小写字母构成的字符串,字符串长度小于等于10。


输出描述:
输出答案(YES\NO).
示例1

输入

coco

输出

YES
import java.util.*;


public class Main {
    public static void main(String[] args){
        Scanner sc = new Scanner(System.in);
        String s = sc.next();
        String s2 = sc.next();
        solution(s);
        solution(s2);

    }

    private static void solution(String s) {
        LinkedHashSet<Character> set = new LinkedHashSet<>();
        HashMap<String, String> map = new LinkedHashMap<>();
        for(int i=0;i<s.length();i++){
           set.add(s.charAt(i));
        }
        StringBuilder stringBuilder = new StringBuilder(s);
        Iterator<Character> iterator = set.iterator();
        while (iterator.hasNext()){
            Character c = iterator.next();
            for(int i=0;i<=s.length();i++){
                String s1 = stringBuilder.insert(i, c).toString();
                if(!map.containsKey(s1)){
                    String s2 = findroundString2(s1);
                    map.put(s1,s2);
                }
                stringBuilder.delete(0,stringBuilder.length());
                stringBuilder.append(s);
            }
        }
        String RESULT="NO";
        Set<Map.Entry<String, String>> entries = map.entrySet();
        Iterator<Map.Entry<String, String>> iterator1 = entries.iterator();
        while (iterator1.hasNext()){
            Map.Entry<String, String> next = iterator1.next();
            String value = next.getValue();
            if(value=="YES"){
                RESULT=value;
                break;
            }
        }

        System.out.println(RESULT);
    }

    private static String findroundString2(String s) {
        String flag = "";
            StringBuilder builder = new StringBuilder(s);
            builder.reverse();
            StringBuilder builder1 = new StringBuilder(s);
            if(builder.toString().equals(builder1.toString())){
                flag="YES";
            }


        return flag!=null?flag:"NO";
    }

}

发表于 2022-04-01 15:27:49 回复(0)
import java.util.*;

public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        Set<String> set = new HashSet<>();
        while (in.hasNext()){
            String s = in.next();
            for (int i = 0; i <s.length() ; i++) {
                set.add(String.valueOf(s.charAt(i)));
            }
            List<String> list = new ArrayList<>(set);
            if(just(list,s)){
                System.out.println("YES");
            }else {
                System.out.println("NO");
            }
        }
    }

    private static boolean just(List<String> list, String s) {
        for (int j = 0; j < list.size(); j++) {
            for (int k = 0; k <= s.length() ; k++) {
                StringBuffer ** = new StringBuffer(s);
                StringBuffer str = **.insert(k,list.get(j));
                StringBuffer str1 = new StringBuffer(str).reverse();
                if(str.toString().equals(str1.toString())){
                    return true;
                }
            }
        }
        return false;
    }
}


思路简单,但是是不是繁琐,希望大家批评指正
发表于 2020-07-15 11:54:23 回复(0)
import java.util.Scanner;

public class Main {
    public static void main(String args[]) {
        Scanner sc = new Scanner(System.in);
        while (sc.hasNextLine()) {
            String s = sc.nextLine();
            StringBuilder sb = new StringBuilder(s);
            for (int i = 0; i < sb.length() - 1; i++) {
                for (int j = 0; j <= 26; j++) {
                    sb.insert(i, (char) ('a' + j));
                    String sb2 = String.valueOf(sb);
                    sb.reverse();
                    if (sb2.equals(String.valueOf(sb))) {
                        System.out.println("YES");
                        return;
                    } else {
                        sb.deleteCharAt(sb.length() - 1 - i);
                        sb.reverse();
                    }
                }
            }
            System.out.println("NO");
        }
    }
}
//这个编译器有毒,idea上通过了这上面的测试用例,自测也通过了卡住的测试用例,可是这就是报空

发表于 2020-03-11 00:17:20 回复(0)
import java.util.*;
public class Main{
    public static void main(String[] args){
        Scanner sc = new Scanner(System.in);
        while(sc.hasNext()){
            String s = sc.next();
            char[] data = s.toCharArray();
            if(s.length() <= 1){
                System.out.println("YES");
                break;
            }
            for(int i = 0; i < s.length(); i++){
                if(data[s.length() - 2] == data[0]) {
                    if (s.length() - 2 - i <= i) {
                        System.out.println("YES");
                        break;
                    } else if (data[s.length() - 2 - i] != data[i]) {
                        System.out.println("NO");
                        break;
                    }
                }else{
                    if (s.length() - 1 - i <= i + 1) {
                        System.out.println("YES");
                        break;
                    } else if (data[s.length() - 1 - i] != data[i + 1]) {
                        System.out.println("NO");
                        break;
                    }
                }
            }
        }
    }
}

发表于 2019-07-28 18:24:07 回复(0)
 import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        while(in.hasNext()){
            String str = in.next();
            System.out.println(Helper(str));
        }
    }
    public static String Helper(String str){
        int len = str.length();
        int i = len/2;
        if(len%2 == 0){
            if((str.substring(0,i).contains(new StringBuffer(str.substring(i+1)).reverse().toString())) ||
                    str.substring(i).contains(new StringBuffer(str.substring(0,i-1)).reverse().toString())){
                return "YES";
            }
            return "NO";
        }else{
            if((str.substring(0,i+1).contains(new StringBuffer(str.substring(i+1)).reverse().toString())) ||
                    str.substring(i).contains(new StringBuffer(str.substring(0,i)).reverse().toString())){
                return "YES";
            }
            return "NO";
        }
    }
}
发表于 2019-07-16 22:04:46 回复(0)
使用dp求解
public static void main(String[] args) {
        Scanner scanner=new Scanner(System.in);
        while (scanner.hasNext()){
            String s=scanner.next();
            boolean[][] dp=new boolean[s.length()][s.length()];
            for(int i=s.length()-1;i>=0;i--){
                for(int j=i;j<s.length();j++){
                    dp[i][j]=s.charAt(i)==s.charAt(j)&&(i>j-2||dp[i+1][j-1]);
                }
            }
            int j=s.length()-1;
            int i=0;
            while (i<j){
                if(s.charAt(i)!=s.charAt(j))break;
                i++;
                j--;
            }
            if(i==j||dp[i+1][j]||dp[i][j-1]) System.out.println("YES");
            else System.out.println("NO");
        }
    }
发表于 2018-08-26 16:38:37 回复(0)
import java.util.Scanner;

public class Main {

    public static void main(String[] args) {

        Scanner sc = new Scanner(System.in);

        while (sc.hasNext()) {
            String str = sc.nextLine();
            Main.addLeastChar(str);
        }

    }

    /*
     * 核心思想是:组装出str与其翻转的字符strMirror的最长公共子序列,举例:
     * str="abceba",strMirror="abecba",最长公共子序列为
     * "abcba"为5,str的长度为6,只要满足str的长度-最长公共子序列<=1(添加一个字符,满足题意),即可输出YES,反之则输出NO
     */
    /*
     * 其他位置为三种情况:1.可能是dp[i - 1][j],i.e:str1:"A1BC2",str2:"AB34C" str1[0..3](A1BC
     * )与str2[0...4](AB34C)的最长公共子序列为"ABC",即dp[3][4]=3而dp[4][4
     * ]也是3,具体可同dp[3][4]一样分析
     * //2.也可能是可能是dp[i][j-1],i.e:str1:"A1BC2",str2:"AB3C4",str1[0..4](A1BC2 // *
     * )与str2[0...3](AB3C)的最长公共子序列为"ABC",dp[4][3],而dp[4][4]也是3
     * 3.str1[i]==str2[j] 还可能是dp[i-1][j-1]+1,i.e:str1:"ABCD",str2:"ABCD"
     */
    public static void addLeastChar(String str) {
        String str1 = str;
        String str2 = new StringBuilder(str).reverse().toString();
        int[][] dp = getdp(str1, str2);
        int len = str1.length();
        int lisLen = dp[str1.length() - 1][str2.length() - 1];
        boolean res = len - lisLen <= 1;
        if (res)
            System.out.println("YES");
        else
            System.out.println("NO");

    }

    // dp[i][j]是str1[0...i]和str2[0...j]的最长公共子序列的长度
    public static int[][] getdp(String str1, String str2) {
        char[] chas1 = str1.toCharArray();
        char[] chas2 = str2.toCharArray();

        int[][] dp = new int[chas1.length][chas2.length];
        dp[0][0] = chas1[0] == chas2[0] ? 1 : 0;
        for (int i = 1; i < chas1.length; i++) {// 组装第一列
            dp[i][0] = Math.max(dp[i - 1][0], chas1[i] == chas2[0] ? 1 : 0);
        }

        for (int j = 1; j < chas2.length; j++) {// 组装第一行
            dp[0][j] = Math.max(dp[0][j - 1], chas1[0] == chas2[j] ? 1 : 0);
        }
        for (int i = 1; i < chas1.length; i++) {// 组装其他元素
            for (int j = 1; j < chas2.length; j++) {
                dp[i][j] = Math.max(dp[i - 1][j], dp[i][j - 1]);
                if (chas1[i] == chas2[j]) {
                    dp[i][j] = Math.max(dp[i][j], dp[i - 1][j - 1] + 1);
                }

            }
        }

        return dp;
    }

}

编辑于 2018-03-12 21:14:48 回复(0)

发现点赞较多的居然是n平方的复杂度,不能忍。
O(n)就行啦,双指针,一前一后。遍历一次就可以了。

import java.util.Scanner;
/**
 * Created by lzq on 17-7-2.
 */
public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        while (in.hasNext()) {
            String str = in.next();
            int flag = 0;
            int i = 0, j = str.length() - 1;
            while (i <= j) {
                if (str.charAt(i) != str.charAt(j)) {
                    if (i + 1 <= j && str.charAt(i + 1) == str.charAt(j)) {
                        i++;
                        flag++;
                    } else if (j - 1 >= i && str.charAt(i) == str.charAt(j - 1)) {
                        j--;
                        flag++;
                    } else {
                        flag+=2;
                        break;
                    }
                } else {
                    i++;
                    j--;
                }
            }
            if (flag < 2) {
                System.out.println("YES");
            } else {
                System.out.println("NO");
            }
        }
    }
}
编辑于 2017-07-04 10:43:02 回复(1)
/*思路:增加一个变成回文即删除一个变成回文
             求原字符串和反转字符串的最长公共子序列(不懂百度)
             如果公共子序列字符个数等于原字符串长度减一则为YES否则为NO
*/

import java.util.*;

public class test {
public static void main(String arg[]) {
Scanner scanner=new Scanner(System.in);
         String str1=scanner.next();
         String str2="";
         for(int i=str1.length()-1;i>=0;i--) 
         str2+=str1.charAt(i);  
         int [][]n=new int[str1.length()][str2.length()];
         for(int i=0;i<str1.length();i++){
         if(str1.charAt(i)==str2.charAt(0)) n[i][0]=1;
         }
         for(int i=0;i<str2.length();i++){
         if(str2.charAt(i)==str1.charAt(0)) n[0][i]=1;
         }
         for(int i=1;i<str1.length();i++){
         for(int j=1;j<str2.length();j++){
         if(str1.charAt(i-1)==str2.charAt(j-1)){
         n[i][j]=n[i-1][j-1]+1;
         }else{
         n[i][j]=Math.max(n[i-1][j], n[i][j-1]);
         }
         }
         }
         if(str1.length()-1==n[str1.length()-1][str2.length()-1]){
        System.out.println("YES");
         }
         else  System.out.println("NO");
}
}
发表于 2017-03-20 22:26:13 回复(0)
/**
有个case: "jnwbbwnjb"本地可以通过,线上却通不过,也没有提示,
我使用暴力求解(逃。。。),各位大虾知道是怎么回事吗?
*/
public static boolean  addedStrIsPalindrome(String str) {
        for (int i = 0; i < str.length(); i++) {
            for (char ch = 'a'; ch <= 'z'; ch++) {
                StringBuilder sb = new StringBuilder(str);
                sb.insert(i, ch);
                if (isPalindrome(sb.toString())) {
                    return true;
                }
            }
        }
        return false;
    }

编辑于 2017-03-16 15:36:39 回复(1)
/*
1.做完后,发现有人说既然增加一个能成为回文,那么删除一个也能成为回文,思路不错
2.本例联系了StringBuilder,一定要注意,只要没有new StringBuilder,修改的就还是原对象
3.易错点:利用StringBuilder的插入,都是插在i元素之前。而本题最后一个元素是要插在
第一个元素的左边,而第一个是要插在最后一个元素的右边的。
*/
import java.util.*;
public class Main {
    public static void main(String[] args){
        Scanner sc =new Scanner(System.in);
        while(sc.hasNext()){
            String s = sc.nextLine();            
            String res = "NO";
            if(isHuiWen(new StringBuilder(s))){
                res="NO";
            }else{                
                for(int i=0;i<=s.length()/2;i++){
                    if(s.charAt(i)!=s.charAt(s.length()-1-i)){
						StringBuilder B = new StringBuilder(s).insert(i,s.charAt(s.length()-1-i));                    
                        StringBuilder C = new StringBuilder(s).insert(s.length()-i,s.charAt(i));
                        if(isHuiWen(B) | isHuiWen(C)){
                            res = "YES";
                            break;
                        }
                	}
                }                
            }
            System.out.println(res);
        }
    }
    public static boolean isHuiWen(StringBuilder sb){
        StringBuilder sb1 = new StringBuilder(sb);
        if(sb1.reverse().toString().equals(sb.toString())){
            return true;
        }
        return false;
    }
}

编辑于 2017-03-04 15:54:53 回复(0)
问题分析:首先缺了一个字符的回文串是怎样的
1、在头部、尾部缺 如 abcb(在尾部缺) bdffdbe(在头部缺)
------这种类型只要把首部、或者尾部的一个字符串去掉,那天还是一个回文字符串
2、在中间部分缺 如: abcdrfcrdcbae这种情况,只要把首尾相同的字符去掉,就又会出现 1 的这种情况 abcdrfcrdcba————————>fc 
abcdrfcrbae-------> cdrfcr
3、还有一种情况就是在最中间缺,这种情况,就算他缺了一个字符,它还是一个回文字符串 如: aba abba

public static void  main(String args[]) {
Scanner sc=new Scanner(System.in);
while(sc.hasNext()){
String input=sc.next();
doIt( input);
}
}
 
public static void doIt(String input){
int i=0,j=input.length()-1;
 
while(i<j&&input.charAt(i)==input.charAt(j)){
i++;j--;
}; //把首尾相同的元素去掉
 

if(i>=j) {  //这就是最中间缺的情况
System.out.println("YES");
return;
}
else{
if(input.charAt(i+1)==input.charAt(j)){    
i++;
while(i<j&&input.charAt(i)==input.charAt(j)){
i++;j--;
}; //把首尾相同的元素去掉
if(i>=j) {  //这就是中间缺的情况
System.out.println("YES");return;
} 
}
 
if(input.charAt(i)==input.charAt(j-1)){    
j--;
while(i<j&&input.charAt(i)==input.charAt(j)){
i++;j--;
}; //把首尾相同的元素去掉
if(i>=j) {  //这就是中间缺的情况
System.out.println("YES");return;
} 
}
 
 
}
 
System.out.println("NO");
 
 
 
	 }



发表于 2016-09-24 17:07:06 回复(0)
import java.util.Scanner;


public class Main{
    public static void main(String[] args){
        Scanner sc = new Scanner(System.in);
        while(sc.hasNext()){
            String line = sc.nextLine();
            int n = line.length();
            boolean flag = false;
            for(int i = 0; i < n; i++){
                StringBuilder sb = new StringBuilder(line);
                String left = "";
                String right = "";
                if(i != 0){
                left = sb.substring(0, i).toString();
                }
                if(i != n -1){
                right = sb.substring(i+1, n).toString();
                }
                StringBuilder sb1 = new StringBuilder(left+right);
                
                if(isPa(sb1.toString()))
                flag  =true;
            }
            if(flag)
                System.out.println("YES");
            else 
                System.out.println("NO");
            
        }
    }
    
    public static boolean isPa(String s){
        return new StringBuilder(s).reverse().toString().equals(s);
    }
}
发表于 2016-09-06 17:19:48 回复(0)
import java.util.Scanner;
public class Main {
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		while (sc.hasNext()) {
			String s = sc.next();
			boolean flag = false;
			for (int i = 0; i < s.length(); i ++ ) {
				String str = s.substring(0, i) + s.substring(i + 1);
				StringBuilder sb = new StringBuilder();
				sb.append("#");
				for (int j = 0; j < str.length(); j ++ )
					sb.append(str.charAt(j) + "#");
				int start = sb.length() / 2;
				int end = sb.length() / 2;
				String temp = sb.toString();
				while (start >= 0 && end <= sb.length() - 1 && temp.charAt(start) == temp.charAt(end)) {
					if(start == 0 && end == temp.length() - 1) flag = true;
					start -- ;
					end ++ ;
				}
			}
			if(flag)
				System.out.println("YES");
			else
				System.out.println("NO");
		}
	}
}
编辑于 2016-08-30 23:30:39 回复(0)
import java.util.*;

public class Main {
    
    public static void main(String[] args) {
        Scanner scan = new Scanner(System.in);
        while (scan.hasNextLine()) {
            String line = scan.nextLine();
            char[] cs = line.toCharArray();
            char[] rs = new char[cs.length];
            for (int i = 0, j = cs.length - 1; i < cs.length; ++i, --j) {
                rs[i] = cs[j];
            }
            int[][] dp = new int[cs.length + 1][cs.length + 1];
            for (int i = 1; i <= cs.length; ++i) {
                for (int j = 1; j <= rs.length; ++j) {
                    if (cs[i - 1] == rs[j - 1]) {
                        dp[i][j] = dp[i - 1][j - 1] + 1;
                    } else {
                        dp[i][j] = Math.max(dp[i - 1][j], dp[i][j - 1]);
                    }
                }
            }
            int len = dp[cs.length][cs.length];
            if (cs.length - len <= 1) {
                System.out.println("YES");
            } else {
                System.out.println("NO");
            }
        }
        scan.close();
    }
    
}
字符串的和它的反向字符串的公共子序列长度为原字符串的长度或短1,则为yes
编辑于 2016-08-25 11:34:31 回复(0)
通过递归来判断:
import java.util.Scanner;

public class Main {

	public static boolean isHuiWen(char[] a, int start, int end,
			boolean isHuiWen) {
		if (end - start < 2) {
			return true;
		}

		if (a[start] == a[end]) {
			return isHuiWen(a, start + 1, end - 1, isHuiWen);
		} else {
			if (isHuiWen) {
				return isHuiWen(a, start, end - 1, false)
						|| isHuiWen(a, start + 1, end, false);
			} else {
				return false;
			}
		}
	}

	public static void main(String[] args) {
		Scanner scanner = new Scanner(System.in);
		while (scanner.hasNext()) {
			String s = scanner.nextLine();
			boolean rs = isHuiWen(s.toCharArray(), 0, s.length() - 1, true);
			if (rs) {
				System.out.println("YES");

			} else {
				System.out.println("NO");
			}
		}
		scanner.close();
	}
}

发表于 2016-08-19 14:13:20 回复(0)
import  java.util.Scanner;

public class Main{
    public static void main(String args[]){
        Scanner input=new Scanner(System.in);
        while(input.hasNext()){
            String A=input.next();
            String B="";
            for(int i=A.length()-1;i>=0;i--){
                B+=A.charAt(i);
            }
            A+=A.charAt(0);
            B+=B.charAt(0);
            if(IsHuiwen(A)||IsHuiwen(B)){
                System.out.println("YES");
            }else{
            System.out.println("NO");
            }
        }
    }
    public static boolean IsHuiwen(String A){
        boolean count=false;
        for(int i=0;i<A.length();i++){
            if(A.charAt(i)==A.charAt(A.length()-1-i)){
                count=true;
            }else{
                count=false;
                break;
            }
        }
        return count;
    }
}
//用自己的思想证明是可以的

编辑于 2016-06-30 21:43:16 回复(0)
/*利用传统思路,掐头去尾
字符串头部添加一个尾部字符,判断是否为回文
字符串尾部添加一个头部字符,判断是否为回文
2者有1个是,返回true
否则判断头尾字符是否一样(插入的字符确定不在两边了,头尾就一定可以形成对应)
如果否 返回false
如果是 新字符串=原字符串去掉头尾 进行递归
下面附上代码

*/


import java.util.Scanner;

public class Main {

/**
* @param args
*/
public static boolean isHui(String a){
//System.out.println(a);
for(int i=0;i<(a.length()/2+1);i++){
if(a.charAt(i)!=a.charAt(a.length()-1-i)){
return false;
}
}
return true;
}
public static boolean dealString(String a){
char temp1 = a.charAt(a.length()-1);
if(isHui(temp1+a)){
return true;
}
char temp2 = a.charAt(0);
if(isHui(a+temp2)){
return true;
}
if(temp1!=temp2){
return false;
}
return dealString(a.substring(1, a.length()-1));
}
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner sc = new Scanner(System.in);
String a ="";
while(sc.hasNext()){
a = sc.next();
if(dealString(a)){
System.out.println("YES");
}
else{
System.out.println("NO");
}
}

}

}



发表于 2016-06-15 22:23:28 回复(0)