Valid Palindrome

Given a string, determine if it is a palindrome, considering only alphanumeric characters and ignoring cases.

For example,
"A man, a plan, a canal: Panama" is a palindrome.
"race a car" is not a palindrome.

Note:
Have you consider that the string might be empty? This is a good question to ask during an interview.

For the purpose of this problem, we define empty string as valid palindrome.

处理好大小写转换、非法字符忽略就可以。

 class Solution {
public: bool isPalindrome(string s) {
if (s.empty()) return true;
int l = , r = s.length() - ;
char c1, c2;
while (r > l) {
while (true) {
if (l >= r) break;
if (s[l] >= 'a' && s[l] <= 'z') break;
if (s[l] >= 'A' && s[l] <= 'Z') { s[l] += ; break; }
if (s[l] >= '' && s[l] <= '') break;
l++;
} while (true) {
if (l >= r) break;
if (s[r] >= 'a' && s[r] <= 'z') break;
if (s[r] >= 'A' && s[r] <= 'Z') { s[r] += ; break; }
if (s[r] >= '' && s[r] <= '') break;
r--;
} if (s[l] != s[r]) return false;
l++; r--;
} return true;
}
};

这样写好一点。

 class Solution {
public:
bool isDigit(char c) {
return (c >= '' && c <= '');
} bool isUppercase(char c) {
return (c >= 'A' && c <= 'Z');
} bool isLowercase(char c) {
return (c >= 'a' && c <= 'z');
} bool isValid(char c) {
return (isLowercase(c) || isDigit(c) || isUppercase(c));
} bool isPalindrome(string s) {
if (s.empty()) return true;
int n = s.length();
for (int i = , j = n - ; i < j; ) {
for (; i < j && !isValid(s[i]); i++);
for (; i < j && !isValid(s[j]); j--);
if (isUppercase(s[i])) s[i] += ;
if (isUppercase(s[j])) s[j] += ;
if (s[i] != s[j]) return false;
i++, j--;
}
return true;
}
};

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"]
]

回溯法就可以了。

 class Solution {
public: bool isPalindrome(string &s) {
int n = s.length();
if (n <= ) return true;
int l = , r = n - ;
while (r > l) {
if (s[l] != s[r]) return false;
r--; l++;
}
return true;
} vector<vector<string>> partition(string s) {
vector<vector<string>> rets; vector<string> ret;
bt(s, , ret, rets); return rets;
} void bt(string &s, int index, vector<string> &ret, vector<vector<string>> &rets) {
if (index >= s.length()) {
rets.push_back(ret);
return;
} for (int i = index; i < s.length(); ++i) {
string tmp(s.substr(index, i - index + ));
if (isPalindrome(tmp)) {
ret.push_back(tmp);
bt(s, i + , ret, rets);
ret.pop_back();
}
}
}
};

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",
Return 1 since the palindrome partitioning ["aa","b"] could be produced using 1 cut.

这里主要有两层需要dp的。

1. 令p[i][j]为i到j之间需要的最小cut个数。我们要求的是p[0][n - 1]。第一个dp很简单,p[i][n - 1] = min{p[j+1][n-1]} + 1, 其中i<=j<n,s(i, j)是回文。

2. 判断回文其实也是一个dp的过程,不过每次都用循环。如果s(i, j)是回文,则p[i][j]=0。p[i][j] = 0 当且仅当str[i]== str[j] && p[i + 1][j - 1]=0。没有这一部分dp就会TLE了。这一步骤用递归就可以,注意的是,比较后要设置p[i][j],无论是否等于0.

 class Solution {
public:
bool isPalindrome(string &s, int l, int r, vector<vector<int> > &p) {
if (l > r) return true;
if (p[l][r] == ) return true;
if (p[l][r] != -) return false;
if (s[l] != s[r]) return false; bool isPalin = isPalindrome(s, l + , r - , p);
if (isPalin) {
p[l][r] = ;
} else {
p[l][r] = r - l;
}
return isPalin;
} int minCut(string s) {
int n = s.length();
if (n <= ) return ;
vector<vector<int> > p(n, vector<int>(n, -));
for (int i = ; i < n; ++i) {
p[i][i] = ;
}
for (int i = n - ; i >= ; --i) {
p[i][n - ] = n - i - ;
for (int j = i; j < n; ++j) {
if (s[j] == s[i] && isPalindrome(s, i + , j - , p)) {
p[i][j] = ; if (j < n - && p[j + ][n - ] + < p[i][n - ]) {
p[i][n - ] = p[j + ][n - ] + ;
}
}
}
} return p[][n - ];
}
};

第三次写,用了两个数组。不过思路也算简单了。

 class Solution {
public:
int minCut(string s) {
if (s.empty()) return ;
int n = s.length();
vector<vector<bool> > dp(n, vector<bool>(n, false));
vector<int> min(n, );
for (int i = ; i < n; ++i) {
dp[i][i] = true;
min[i] = min[i - ] + ;
for (int j = i - ; j >= ; --j) {
if ((j > i - || dp[j + ][i - ]) && s[i] == s[j]) {
dp[j][i] = true;
if (j == ) min[i] = ;
else if (min[j - ] + < min[i]) min[i] = min[j - ] + ;
}
}
}
return min[n - ];
}
};

空间上比起用vector<vector<int> >还是省了。因为用bool的话,最终用了O(n^2+n),用int虽然看起来只用了一个变量,但是却是O(4n^2)。

Leetcode | Palindrome的更多相关文章

  1. LeetCode:Palindrome Partitioning,Palindrome Partitioning II

    LeetCode:Palindrome Partitioning 题目如下:(把一个字符串划分成几个回文子串,枚举所有可能的划分) Given a string s, partition s such ...

  2. LeetCode: Palindrome Partition

    LeetCode: Palindrome Partition Given a string s, partition s such that every substring of the partit ...

  3. [LeetCode] Palindrome Partitioning II 解题笔记

    Given a string s, partition s such that every substring of the partition is a palindrome. Return the ...

  4. LeetCode: Palindrome 回文相关题目

    LeetCode: Palindrome 回文相关题目汇总 LeetCode: Palindrome Partitioning 解题报告 LeetCode: Palindrome Partitioni ...

  5. [LeetCode] Palindrome Pairs 回文对

    Given a list of unique words. Find all pairs of distinct indices (i, j) in the given list, so that t ...

  6. [LeetCode] Palindrome Permutation II 回文全排列之二

    Given a string s, return all the palindromic permutations (without duplicates) of it. Return an empt ...

  7. [LeetCode] Palindrome Permutation 回文全排列

    Given a string, determine if a permutation of the string could form a palindrome. For example," ...

  8. [LeetCode] Palindrome Linked List 回文链表

    Given a singly linked list, determine if it is a palindrome. Follow up: Could you do it in O(n) time ...

  9. [LeetCode] Palindrome Partitioning II 拆分回文串之二

    Given a string s, partition s such that every substring of the partition is a palindrome. Return the ...

  10. [LeetCode] Palindrome Partitioning 拆分回文串

    Given a string s, partition s such that every substring of the partition is a palindrome. Return all ...

随机推荐

  1. DP:Coins(POJ 1742)

      用硬币换钱 题目大意:就是有面值为A1,A2,A3....的硬币,各有C1,C2,C3...的数量,问在钱数为m的范围内,能换多少钱?(不找零) 这题看名字就知道是完全背包,但是这题又有点不一样, ...

  2. 多源最短路(codevs 1077)

    题目描述 Description 已知n个点(n<=100),给你n*n的方阵,a[i,j]表示从第i个点到第j个点的直接距离. 现在有Q个询问,每个询问两个正整数,a和b,让你求a到b之间的最 ...

  3. Txx考试(codevs 2894)

    2894 Txx考试  时间限制: 1 s  空间限制: 32000 KB  题目等级 : 黄金 Gold 题解  查看运行结果     题目描述 Description Txx是一个成绩很差的人,考 ...

  4. Java之IO操作总结

    所谓IO,也就是Input与Output的缩写.在java中,IO涉及的范围比较大,这里主要讨论针对文件内容的读写 其他知识点将放置后续章节 对于文件内容的操作主要分为两大类 分别是: 字符流 字节流 ...

  5. 比较两个目录中的文件 diff -rq

    [root@bass test]# mkdir A B [root@bass test]# tree A A └── lin 0 directories, 1 file [root@bass test ...

  6. HTTP协议缓存机制的应用

    缓存的目 的是减少相应延迟 和 减少网络带宽消耗, 比如 css. js.图片这类静态资源应该进行缓存.实际项目 一般使用反向代理服务器(如 nginx. apache 等) 进行缓存. 关键字:ca ...

  7. SQL Server 2012 OFFSET/FETCH NEXT分页示例(转载)

    原文:http://beyondrelational.com/modules/29/presentations/483/scripts/12983/sql-server-2012-server-sid ...

  8. javascript中window.open()与window.location.href的区别

    window.open("www.baidu.com"); 只是表示打开这个页面,并不是打开并刷新baidu.com window.location.href="www. ...

  9. poj 2245 水题

    求组合数,dfs即可 #include<cstdio> #include<iostream> #include<algorithm> #include<cst ...

  10. Sqlite实现默认时间为当前时间列的方法(转)

    原文地址: http://blog.csdn.net/derryzhang/article/details/5033209 在SQL Server中,创建表格的时候,对于时间列有时候我们可以根据需要指 ...