【简单】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.

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/longest-common-prefix

解法

方法一:逐位扫描

解题思路

从第一位字符开始,判断是否每一个字符串的第n位都是相同的,如果第n位出现不同的字符,那么前n-1位就是最长前缀,可以直接对比,也可以使用find函数

代码

代码一:直接对比
class Solution {
public:

    inline bool test(int pos, string s, char curr){
        if(s.length() <= pos){
            return false;
        }
        if(s[pos] == curr){
            return true;
        }
        return false;
    }
    string longestCommonPrefix(vector<string>& strs) {
        if(strs.size() == 0){
            return "";
        }
        if(strs.size() == 1){
            return strs[0];
        }
        int pos = 0;
        for(char currchar = strs[0][pos]; pos < strs[0].length(); pos++, currchar = strs[0][pos]){
            for(int i = 1; i < strs.size(); ++i){
                if(!test(pos, strs[i], currchar)){
                    return strs[0].substr(0, pos);
                }
            }
        }
        return strs[0].substr(0, pos+1);
    }
};
代码二:find函数
class Solution {
public:

    string longestCommonPrefix(vector<string>& strs) {
        if(strs.size() == 0){
            return "";
        }
        string result = strs[0];
        for(int i = 1; i < strs.size(); ++i){
            while(strs[i].find(result) != 0){
                result = result.substr(0, result.length()-1);
            }
            if(result == ""){
                return "";
            }
        }
        return result;
    }
};

方法二:逐一扫描

解题思路

先找到前两个字符串的最长前缀,再用这个前缀和下一个字符串比较得到新的前缀,重复这个过程直到没有新的字符串或者前缀为空字符串。

代码

class Solution {
public:
    string findPre(string l1, string l2){
        int size1 = l1.size(), size2 = l2.size();
        for(int i = 0; i < size1; ++i){
            if(i >= size2 or l2[i] != l1[i]){
                return l1.substr(0,i);
            }
        }
        return l1;
    }
    string longestCommonPrefix(vector<string>& strs) {
        int size = strs.size();
        if(size == 0) return "";
        string pre = strs[0];
        for(int i = 1; i < size; ++i){
            pre = findPre(pre, strs[i]);
            if(pre == "") return pre;
        }
        return pre;
    }
};

方法三:二分法

解题思路

对于长度为n的字符串数组,将其分成两组求出组中的最长前缀,那两个前缀的最长前缀就是最终的前缀,同理,这两组也可以分成新的两组,一直划分下去就是二分法的思想

代码

class Solution {
public:
    string findPre(string l1, string l2){
        int size1 = l1.size(), size2 = l2.size();
        for(int i = 0; i < size1; ++i){
            if(i >= size2 or l2[i] != l1[i]){
                return l1.substr(0,i);
            }
        }
        return l1;
    }
    string longestPre(vector<string> strs, int start, int end){
        if(start == end) return strs[start];
        int mid = (start+end)/2;
        string a = longestPre(strs, start, mid);
        string b = longestPre(strs, mid+1, end);
        if(a=="" || b=="") return "";
        return findPre(a,b);
    }
    string longestCommonPrefix(vector<string>& strs) {
        int size = strs.size();
        if(size == 0) return "";
        return longestPre(strs, 0, size-1);
    }
};

总结

二分法的代价有点高

posted @ 2020-04-22 11:43  陌良  阅读(246)  评论(0编辑  收藏  举报