首页 > 代码库 > leetcode -day13 Valid Palindrome & Triangle & Pascal's Triangle I II

leetcode -day13 Valid Palindrome & Triangle & Pascal's Triangle I II

1、


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;
    }
};