[日常刷题]leetcode D22

版权声明:希望各位多提意见多多互相交流哦~ https://blog.csdn.net/wait_for_taht_day5/article/details/82920633

14. Longest Common Prefix

Write a function to find the longest common prefix string amongst an array of strings.

If there is no common prefix, return an empty string "".
Example 1:

Input: ["flower","flow","flight"]
Output: "fl"

Example 2:

Input: ["dog","racecar","car"]
Output: ""
Explanation: There is no common prefix among the input strings.

Note:

All given inputs are in lowercase letters a-z.

Solution in C++:

关键点:

  • 从下标0开始 每个字符串

思路:

  • 对每个字符串进行对比扫描,扫描长度为其中最短的字符串长度。
  • 看到解析有好多种方法哇,我的这个方法算是解析种的vertical scanning带点优化。然后说下我觉得很棒或者比较有训练价值的方法。
  • 分治方法,左边的最大前缀和后边的最后前缀的最大前缀即为所求。
  • 二分查找,第一个字符串的前半部分如果和其他字符串都有公共前缀,那么求后半部分的最大前缀即可,如果不是,缩短前半部分求前面即可。

方法一:vertical scanning 变种

string longestCommonPrefix(vector<string>& strs) {
        
        string result = "";
        size_t size = strs.size();
        int minLen = INT_MAX;
        
        if(size == 0)
            return result;
        
        for(auto str : strs)
            if (str.size() < minLen)
                minLen = str.size();
        
        for(int i = 0; i < minLen; ++i)
        {
            bool flag = true;
            char tmp = strs[0][i];
            
            for(int j = 1; j < size; ++j)
            {
                if (tmp != strs[j][i])
                {
                    flag = false;
                    break;
                }
            }
            
            if (flag)
                result += tmp;
            else 
                break;
        }
        
        return result;
    }

方法二:分治

public:  
    string longestCommonPrefix(vector<string>& strs) {
        if(strs.size() == 0)
            return "";
        return longestCommonPrefix(strs, 0, strs.size() - 1);
    }
    
private:
      string longestCommonPrefix(vector<string>& strs, int l, int r) {
        if (l == r)
            return strs[l];
        else{
            
            int mid = (l + r) / 2;
            string left = longestCommonPrefix(strs, l, mid);
            string right = longestCommonPrefix(strs, mid + 1, r);
            return commonPrefix(left, right);
        }
    }
    
    string commonPrefix(string left, string right){
        int min = (left.size() < right.size() )? left.size():right.size();
        for ( int i = 0; i < min; ++i)
        {
            if (left[i] != right[i])
                return left.substr(0, i);
        }
        return left.substr(0, min);
    }

方法三:二分查找

public:
    string longestCommonPrefix(vector<string>& strs) {
        if (strs.size() == 0)
            return "";
        int minLen = INT_MAX;
        for(auto str : strs)
            if (str.size() < minLen)
                minLen = str.size();
        int low = 1;
        int high = minLen;
        while (low <= high){
            int mid = (low + high) / 2;
            if ( isCommonPrefix(strs, mid))
                low = mid + 1;
            else
                high = mid - 1;
        }
        return strs[0].substr(0, (low+high) / 2);
    }
    
private:
    bool isCommonPrefix(vector<string>& strs, int len){
        string str1 = strs[0].substr(0, len);
        for( int i = 0; i < strs.size(); ++i)
            if(strs[i].substr(0,len) != str1)
                return false;
        return true;
    }

107. Binary Tree Level Order Traversal II

Given a binary tree, return the bottom-up level order traversal of its nodes’ values. (ie, from left to right, level by level from leaf to root).

For example:
Given binary tree[3,9,20,null,null,15,7],

    3
   / \
  9  20
    /  \
   15   7

return its bottom-up level order traversal as:

[
  [15,7],
  [9,20],
  [3]
]

Solution in C++:

关键点:

  • 层次遍历 && from bottom to top

思路:

  • 用队列记录每层元素,采用nullptr作为层与层之间的分隔符,然后就是vector采用每次在头部插入的方式获取bottom to top
/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    vector<vector<int>> levelOrderBottom(TreeNode* root) {
        vector<vector<int>> result;
        
        if(root == nullptr)
            return result;
        
        queue<TreeNode*> que;
        que.push(root);
        que.push(nullptr);
        vector<int> tmp;
        
        while(!que.empty())
        {
            TreeNode* top = que.front();
            que.pop();
            
            // the num of the current level
            if (top != nullptr)
                tmp.push_back(top->val);
            
            // at the end of a level
            if (top == nullptr)
            {
                
                vector<vector<int>>::iterator it = result.begin();
                result.insert(it, tmp);
                tmp.clear();
                if(que.empty())
                    break;
                que.push(nullptr);
                continue;
            }
            
            // add num to the que
            if (top->left != nullptr)
                que.push(top->left);
            if (top->right != nullptr)
                que.push(top->right);  
        }
        
        return result;
        
    }
};

小结

今天的思路有点受阻,今天亲戚来了状态也不是很好,明天养精蓄锐再战!!!主要对树的层次遍历、分治以及二分查找又进行了复习。

知识点

  • 树的层次遍历带分隔符
  • 分治
  • 二分查找

猜你喜欢

转载自blog.csdn.net/wait_for_taht_day5/article/details/82920633
今日推荐