首页 > 代码库 > leetcode -day13 Valid Palindrome & Triangle & Pascal's Triangle I II
leetcode -day13 Valid Palindrome & Triangle & Pascal's Triangle I II
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; } };