LeetCode: Longest Common Prefix, Valid Parentheses

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 str2
string 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() ;
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值