LeetCode: Longest Common Prefix, Valid Parentheses

来源:互联网 发布:身份证拍照扫描软件 编辑:程序博客网 时间:2024/06/03 19:58

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

直观的想法是弄个while(true)循环,然后遍历array,每遍历一次取出来一个字符,直到取出来的字符不是共有的为止(后面会看到这种其实是最好的,避免了很多重复计算)。也可以不要每次只取出来一个字符,而采用二分法去搜索分割点(引入了很多重复计算)。

"""1. LCP(S1,S2,...,Sn)=LCP(LCP(LCP(S1,S2),S3),...,Sn)6 ms, beats 24.06%时间复杂度:O(S),S是vector中字符总数空间复杂度:O(1)"""#include <iostream>#include <vector>#include <string>using namespace std;// A Utility Function to find the common prefix between// strings- str1 and str2string lcp2(string str1, string str2){    string result;    int n1 = str1.length(), n2 = str2.length();    // Compare str1 and str2    for (int i = 0, j = 0; i <= n1 - 1 && j <= n2 - 1; i++, j++)    {        if (str1[i] != str2[j])            break;        result.push_back(str1[i]);    }    return (result);}string longestCommonPrefix(vector<string>& strs) {    if (strs.size() == 0) //careful        return "";    string result = *(strs.begin());    for (vector<string>::iterator it = strs.begin(); it != strs.end(); ++it){        result = lcp2(result, *it);    }    return result;}int main(){    cout << lcp2("", "abc") << endl;    cout << lcp2("ab", "abc") << endl;    cout << lcp2(lcp2("", "abc"), "abc") << endl;    vector<string> strs = { "abc", "ab" ,"a"};    string result = longestCommonPrefix(strs);    cout << result << endl;    vector<string> strs2 = { "", "ab", "a" };    string result2 = longestCommonPrefix(strs2);    cout << result2 << endl;    vector<string> strs3 = {};    string result3 = longestCommonPrefix(strs3);    cout << result3 << endl;    system("pause");    return 0;}
"""2. Vertical scanning就是一开始我们说的那个直观的想法,弄个while(true)循环,然后遍历array,每遍历一次取出来一个字符,直到取出来的字符不是共有的为止。时空复杂度与1相同,但是in the best case there are at most n*minLenn comparisons where minLen is the length of the shortest string in the array.下面是一个比较紧凑的写法,6 ms,和前面的代码一样。"""
string longestCommonPrefix(vector<string>& strs) {    string prefix = "";    for(int idx=0; strs.size()>0; prefix+=strs[0][idx], idx++)        for(int i=0; i<strs.size(); i++)            if(idx >= strs[i].size() ||(i > 0 && strs[i][idx] != strs[i-1][idx]))                return prefix;    return prefix;}
"""3, Binary search参见一开始的直观想法。时间复杂度是O(S∗log(m)),比前面两种都要大。log(m)是二分查找的次数,最坏情况时每个字符串的长度都是m。每次二分查找要做的比较是S次。时间复杂度增大了,原因是每次二分查找做的比较有很多重复(如看前k个是不是cp,然后又要看前k+k'个是不是cp,这里面有k个字符都是重复的),所以还不如不用二分查找,直接一个位置一个位置逐个查找。空间复杂度O(1)。"""
"""4, Divide and conquer在这个问题中并不是最好的,2中简单的方案是最好的。但是我们趁机复习一下分而治之。T(n)=2T(n/2)+O(m), T(2)=O(m)T(4)=2T(2)+O(m)=O(3m)T(8)=O(7m)通过简单的递推解得T(n)=O(nm)=O(S)空间复杂度O(m*log(n)),原因是在log(n)次递归调用中,每次要用O(m)来保存计算结果以便返回来整合。"""

Valid Parentheses
Given a string containing just the characters ‘(‘, ‘)’, ‘{‘, ‘}’, ‘[’ and ‘]’, determine if the input string is valid.

The brackets must close in the correct order, “()” and “()[]{}” are all valid but “(]” and “([)]” are not.

先自己思考一下。
([)]
[(]
可以弄个链表,存三种节点代表三种括号。然后遍历字符串,每遇到一个左括号就增加一个相应节点,每遇到一个右括号就看最后一个位置是不是该括号,如是则删除该节点,否则return false。最后遍历完了节点刚好全被删除,return true。
时间复杂度O(n),n是字符串长度
空间复杂度O(n)

"""1. 看一下discussion,有个用栈(stack)实现的,思路和上面一致。3 ms, beats 6.94%"""    bool isValid(string s) {        stack<char> paren;        for (char& c : s) {            switch (c) {                case '(':                 case '{':                 case '[': paren.push(c); break;                case ')': if (paren.empty() || paren.top()!='(') return false; else paren.pop(); break;                case '}': if (paren.empty() || paren.top()!='{') return false; else paren.pop(); break;                case ']': if (paren.empty() || paren.top()!='[') return false; else paren.pop(); break;                default: ; // pass            }        }        return paren.empty() ;    }