编程题 回文串难题
来源:互联网 发布:淘宝服装平铺拍照技巧 编辑:程序博客网 时间:2024/06/12 07:15
1、寻找字符串的最长回文子串 Longest Palindrome
(1)动态规划的方法
状态转移:dp[i][j]与dp[i+1][j-1]有关,如果dp[i+1][j-1]==true,并且A[i]==A[j],则dp[i][j]==true,单字符是true,双字符直接比较A[i]==A[j]。同时,需要注意的是初始化的dp[n][n]不能保证是初始化为false,需要在循环时确保false的情况。
class Solution {public: string longestPalindrome(string A) { int n=A.size(); if(n<=1) return A; int sum=1; bool dp[n][n];//这里并没有让他全部初始化为false for (int i = 0; i < n; ++i) { dp[i][i] = true; } int left=0,right=0; for(int i=n-1;i>=0;i--) for(int j=i+1;j<n;j++) { if(A[i]==A[j]&&(i+1==j||dp[i+1][j-1])) { dp[i][j]=true; if(sum<j-i+1){ sum=j-i+1; left=i; right=j; } } else dp[i][j]=false; } return A.substr(left,right-left+1); }};(2)中心拓展方法
class Solution {public: string longestPalindrome(string s) { //使用第四个方法,自中心扩展 int start=0,end=0;//保存当前最长回文串的起始和终结位置 for(int i=0;i<s.size();i++) { int len1=expandFromCenter(s,i,i);//以当前字符为中心的回文串(奇数) int len2=expandFromCenter(s,i,i+1);//以当前和下一个字符的中间为中心的回文串(偶数) int len=max(len1,len2); if(len>end-start+1)//如果求得的新字符串长度是比之前保存的要长的话 { start=i-(len-1)/2; end=i+len/2; } } return s.substr(start,end-start+1); } int expandFromCenter(string& s,int left,int right){ while(left>=0&&right<=s.size()&&s[left]==s[right]){//这种书写方式考虑到奇数和偶数的情况 --left; ++right; } return right-left-1;//返回长度,因为right和left都是移到了回文串的外围位置 } };
2、回文字符串划分 131. Palindrome Partitioning
题目描述:
将一个字符串划分成回文字串,返回所有的划分结果
分析:
从左到右,当找到一个回文字串时,递归下去,直到字符串的末尾,把得到的串加到结果上。递归后置pop操作。是通常的回溯结构
class Palindrome{public: /*131. 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"]]*/ public: vector<vector<string>> partition(string s) { vector<vector<string>> res; vector<string> curStr; doPartition(s,0,s.size(),curStr,res); return res; } void doPartition(string& s,int left,int length,vector<string>& curStr,vector<vector<string>>& res){ if(left==length) { res.push_back(curStr); return ; } for(int i=left;i<length;i++) { if(isPalindrome(s,left,i)) { curStr.push_back(s.substr(left,i-left+1));//注意substr的写法 doPartition(s,i+1,length,curStr,res); curStr.pop_back(); } } } bool isPalindrome(string& s,int left,int right){ if(left==right) return true; while(left<=right) { if(s[left++]!=s[right--]) return false; } return true; }};
3、回文字符串划分 Palindrome Partitioning II 程序员代码面试 回文最少分割数
题目:
将一个字符串划分成回文子串,要求返回最少的划分次数
思路:
参考程序员代码面试指南
用dp[i]表示str[i----length-1]的最少划分数,而dp[i]取决于从i开始的第一个 这个题目与第一个题目类似
int minCut(string s) { int n=s.size(); vector<int> dp(n+1,numeric_limits<int>::max());//从i到n-1的最少分割数,结果返回dp[0] dp[n]=-1;//这个很巧妙 vector<vector<int>> p(n,vector<int>(n,0));//p[i][j]表示从i-j是否是回文串 for(int i=n-1;i>=0;i--) { for(int j=i;j<n;j++) { if(s[i]==s[j]&&(j-i<2||p[i+1][j-1]==1)) { p[i][j]=1; dp[i]=min(dp[i],1+dp[j+1]);//注意时j+1很巧妙 } } } return dp[0]; }
4、最长回文子序列 516. Longest Palindromic Subsequence
if i == j, then longest[i][j] = 1, naturally
if i+1 == j, then longest[i][j] = 2 if s[i] == s[j]
longest[i][j] = 1 otherwise
Transition rule:
- s[i] == s[j]
dp[i][j] = max(dp[i+1][j], dp[i][j-1], dp[i+1][j-1] + 2) - s[i] != s[j]
dp[i][j] = max(dp[i+1][j], dp[i][j-1], dp[i+1][j-1])
class Solution { public: int longestPalindromeSubseq(string s) { int n=s.size(); vector<vector<int>> dp(n,vector<int>(n,0)); for(int i=n-1;i>=0;i--) { dp[i][i]=1; for(int j=i+1;j<n;j++) { if(s[i]==s[j]) dp[i][j]=dp[i+1][j-1]+2; dp[i][j]=max(dp[i][j],max(dp[i+1][j],dp[i][j-1])); } } return dp[0][n-1]; } };
5、回文子串的个数 647. Palindromic Substrings
这道题与1一样,也是设置dp[][] 布尔矩阵,只是,在循环过程中统计true出现的次数
class Solution {public: int countSubstrings(string A) { int n=A.size(); if(n<=1) return n; int sum=0; bool dp[n][n];//这里并没有让他全部初始化为false for (int i = 0; i < n; ++i) { dp[i][i] = true; sum++; } int left=0,right=0; for(int i=n-1;i>=0;i--) for(int j=i+1;j<n;j++) { if(A[i]==A[j]&&(i+1==j||dp[i+1][j-1])) { dp[i][j]=true; sum++; } else dp[i][j]=false; } return sum; }};
阅读全文
0 0
- 编程题 回文串难题
- 《蘑菇街编程题》回文串
- 常见编程题——回文串
- 回文串编程
- 回文字符串编程题
- [编程题]回文序列
- [编程题] 回文序列
- [编程题] 构造回文
- [编程题] 制造回文
- [编程题] 制造回文
- [编程题] 统计回文
- [编程题] 回文序列
- [编程题] 回文序列
- [编程题]回文序列
- [编程题]回文解码
- [编程题]构造回文
- 挑战面试编程:回文串、回文数字
- 腾讯编程题:构造回文
- 用post或者get实现文件下载
- 三种测试用例方法规则
- 多因子模型之因子(信号)测试平台----alphalens(二)
- (配置Hadoop2.x 环境搭建)完全分布式集群
- 自动化运维管理工具ansible的配置与使用
- 编程题 回文串难题
- Vue.js的组件分发 之 作用域槽
- JSON解析、JAVA常用的工具类、JAVA集合框架、JAVA泛型、枚举
- C++常规指针类(浅复制),智能指针类(计数类),值行类(深复制) 区别
- 九度OJ —— 1000
- MySQL 关于插入insert 相关的操作
- 读Zepto源码之Ajax模块
- PAT1109——Group Photo
- 设计模式的应用场景(16)--策略模式