回文:把相同的词汇或句子,在下文中调换位置或颠倒过来,产生首尾回环的情趣,叫做回文,也叫回环。
1.题目:
给定一个字符串,问是否能通过添加一个字母将其变为回文串。
输入描述:
一行一个由小写字母构成的字符串,字符串长度小于等于10。
输出描述:
输出答案(YES\NO).
输入例子:
coco
输出例子:
YES
思路:
1.既然增加一个字符就是回文,那么同样减去一个字符也是回文。
2.普通思路:遍历字符串每个字符,删掉该字符并传入判断回文的函数。时间复杂度为O(N^2).
3.进阶思路:利用递归方法,从两边直接开始判断回文,传递一个变量来记录值能跳过一次两边不相等。时间复杂度O(n);
代码:
using System;
namespace 增加一个字符是否能成为回文串
{
class Program
{
static void Main(string[] args)
{
string line;
string[] p;
while ((line = Console.ReadLine()) != null)
{
char[] str = line.Trim().ToCharArray();
Console.WriteLine(helper(str,0,str.Length-1,false));
Console.ReadLine();
}
}
static bool helper(char[] str, int start, int end, bool flag)
{
if (start >= end)
return true;
if (str[start] == str[end])
{
return helper(str, start + 1, end - 1, flag);
}
else
{
if (flag)
{
return false;
}
else
{
return helper(str, start + 1, end, true) || helper(str, start, end - 1, true);
}
}
}
}
}
2.题目:palindrome-partitioning
Given a string s, partition s such that every substring of the partition is a palindrome.
Return all possible palindrome partitioning of s.
For example, given s ="aab",
Return
[ ["aa","b"], ["a","a","b"]思路:
1.用递归+动态规划方法实现
2.递归条件:当前字符串s分成两部分,一部分是回文,另一部分进行递归
3.递归返回后,删除上次添加的回文
代码:
import java.util.*;
public class Solution {
public ArrayList<ArrayList<String>> partition(String s) {
ArrayList<ArrayList<String>> ret = new ArrayList<ArrayList<String>>();
ArrayList<String> list = new ArrayList<String>();
dfs(ret, list, s);
return ret;
}
public void dfs(ArrayList<ArrayList<String>> ret, ArrayList<String> list, String s)
{
if(s.length() == 0)
{
ret.add(new ArrayList<String>(list));
}
for(int i=1; i<=s.length(); i++)
{
String subStr = s.substring(0,i);
if(isPalindrome(subStr))
{
list.add(subStr);
dfs(ret, list, s.substring(i));
list.remove(list.size()-1);
}
}
}
public boolean isPalindrome(String s)
{
int i = 0;
int j = s.length()-1;
while(i < j)
{
if(s.charAt(i++) != s.charAt(j--))
return false;
}
return true;
}
}
3.题目: palindrome-partitioning-ii
Given a string s, partition s such that every substring of the partition is a palindrome.
Return the minimum cuts needed for a palindrome partitioning of s.
For example, given s ="aab",
Return1since the palindrome partitioning["aa","b"]could be produced using 1 cut.
思路:
1.动态规划:
dp[i] - 表示子串(
0
,i)的最小回文切割,则最优解在dp[s.length-
1
]中。
2.初始化:当字串s.substring(
0
,i+
1
)(包括i位置的字符)是回文时,dp[i] =
0
(表示不需要分割);否则,dp[i] = i(表示至多分割i次);
代码:
public class Solution {
public int minCut(String s) {
int[] dp = new int[s.length()];
for(int i=0; i<s.length(); i++)
{
dp[i] = isPalindrome(s.substring(0, i+1))?0:i;
if(dp[i]==0)
continue;
for(int j=1; j<=i; j++)
{
if( isPalindrome(s.substring(j, i+1)))
dp[i] = Math.min(dp[i], dp[j-1] +1);
else
dp[i] = Math.min(dp[i], dp[j-1]+i-j+1);
}
}
return dp[s.length()-1];
}
public boolean isPalindrome(String s)
{
int i = 0;
int j = s.length()-1;
while(i < j)
{
if(s.charAt(i++) != s.charAt(j--))
return false;
}
return true;
}
}