版权声明:希望各位多提意见多多互相交流哦~ 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;
}
};
小结
今天的思路有点受阻,今天亲戚来了状态也不是很好,明天养精蓄锐再战!!!主要对树的层次遍历、分治以及二分查找又进行了复习。
知识点
- 树的层次遍历带分隔符
- 分治
- 二分查找