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) {
int length = s.length();
int index1 = 0;
int index2 = length-1;
while(index1 < index2){
bool isAlNum1 = isAlphanumeric(s[index1]);
bool isAlNum2 = isAlphanumeric(s[index2]);
if(isAlNum1 && isAlNum2){
if(s[index1] == s[index2] || s[index1]-'a' == s[index2]-'A' || s[index1]-'A' == s[index2]-'a'){
++index1;
--index2;
continue;
}else{
return false;
}
}
if(!isAlNum1){
++index1;
}
if(!isAlNum2){
--index2;
}
}
return true;
}
bool isAlphanumeric(char str){
if(str <= '9' && str >= '0' || str <= 'z' && str >= 'a'
|| str <= 'Z' && str >= 'A'){
return true;
}else{
return false;
}
}
};
2、Triangle
Given a triangle, find the minimum path sum from top to bottom. Each step you may move to adjacent numbers on the row below.
For example, given the following triangle
[ [2], [3,4], [6,5,7], [4,1,8,3] ]
The minimum path sum from top to bottom is 11
(i.e., 2 + 3 + 5 + 1 = 11).
Note:
Bonus point if you are able to do this using only O(n) extra space, where n is the total number of rows in the triangle.
分析:看到此题开始忽略了后面的note提示中的O(n)的空间复杂度,写了一个很简单的递归式,但是显示超时,复杂度很高,
代码如下:
Time Limit Exceeded
class Solution {
public:
int minimumTotal(vector<vector<int> > &triangle) {
minPath = INT_MAX;
int path = 0;
minimunCore(triangle,0,0,path);
return minPath;
}
void minimunCore(vector<vector<int> > &triangle,int rows, int cols,int path){
if(rows >= triangle.size() || cols >= triangle[rows].size()){
if(path < minPath){
minPath = path;
}
return;
}
path += triangle[rows][cols];
minimunCore(triangle,rows+1,cols,path);
minimunCore(triangle,rows+1,cols+1,path);
}
int minPath;
};
利用空间O(n)来提高效率,到每一层的每个点的最短路径只与上一层的两个点有关,minpath[i][j] = min(minpath[i-1][j],minpath[i-1][j-1])+i,j处的值。动归方法如下:
Accepted
class Solution {
public:
int minimumTotal(vector<vector<int> > &triangle) {
int rows = triangle.size();
if(rows == 0){
return 0;
}
int n = (rows+1)*rows/2;
int* minPath = new int[n];
minPath[0] = triangle[0][0];
int lastNum = 0;
int curNum = 1;
for(int i=1; i<rows; ++i){
for(int j=1; j<rows-1; ++j){
minPath[curNum+j] = min(minPath[lastNum+j],minPath[lastNum+j-1]) + triangle[i][j];
}
minPath[curNum] = minPath[lastNum] + triangle[i][0];
minPath[curNum+i] = minPath[lastNum+i-1] + triangle[i][i];
lastNum += i;
curNum += i+1;
}
curNum = (rows-1)*rows/2;
int minPathSum = minPath[curNum];
for(int i=1; i<rows; ++i){
if(minPath[curNum+i] < minPathSum){
minPathSum = minPath[curNum+i];
}
}
delete[] minPath;
return minPathSum;
}
};
3、Pascal's Triangle
Given numRows, generate the first numRows of Pascal's triangle.
For example, given numRows = 5,
Return
[ [1], [1,1], [1,2,1], [1,3,3,1], [1,4,6,4,1] ]
分析:Pascal 三角形,观察上图,每一行的第一个和最后一个元素都是1,中间的元素为上一行两个元素的和,那么代码就很好写了。
如下:
class Solution {
public:
vector<vector<int> > generate(int numRows) {
vector<vector<int> > triangle;
if(numRows <= 0){
return triangle;
}
vector<int> row;
row.push_back(1);
triangle.push_back(row);
for(int i=1; i<numRows; ++i){
row.clear();
row.push_back(1);
for(int j=1; j<=i-1; ++j){
row.push_back(triangle[i-1][j-1]+triangle[i-1][j]);
}
row.push_back(1);
triangle.push_back(row);
}
return triangle;
}
};
4、Pascal's Triangle II
Given an index k, return the kth row of the Pascal's triangle.
For example, given k = 3,
Return [1,3,3,1]
.
Note:
Could you optimize your algorithm to use only O(k) extra space?
分析:此题也很好想,利用一个O(k)的空间来实现,只保留上层的行即可,本层的行之和上层的行有关系。注意,此处要求O(k)的空间复杂度,不是说只要一个k的空间,2k同样可以。之前考虑只有一个k的空间时,这样计算复杂,空间中保存上层,并且每次更新为下层,这样row[i] = 前面的元素row[i-1] -row[i-2]+row[i-3]-row[i-4]..... ,计算复杂。还是采用了两个row,一个保存上层的,一个保存本层的。
如下:
class Solution {
public:
vector<int> getRow(int rowIndex) {
vector<int> row;
vector<int> preRow;
if(rowIndex < 0){
return row;
}
row.push_back(1);
preRow = row;
for(int i=1; i<rowIndex+1; ++i){
row.clear();
row.push_back(1);
for(int j=1; j<=i-1; ++j){
row.push_back(preRow[j]+preRow[j-1]);
}
row.push_back(1);
preRow = row;
}
return row;
}
};