动手刷LeetCode-字符串最长公前缀

字符串最长公共前缀

知识点

字符串或者串(string):是是由数字、字母、下划线组成的一串字符。一般记为 s = “a1a2…an”(n >= 0)。它是编程语言中表示文本的数据类型。
通常以串的整体作为操作对象,如:在串中查找某个子串在该串中首次出现的位置、在串的某个位置上插入一个子串以及删除一个子串等。两个字符串相等的充要条件是:长度相等,并且各个对应位置上的字符都相等。串通常以顺序的方式进行存储与实现。

解题思路

1、暴力法:取最短字符串长度,从头开始逐位比较;
判断字符串组的长度,找到最短字符串,逐一比较,新建字符串,并将相同字符赋值,返回新字符串;

class Solution {
public:
    string longestCommonPrefix(vector<string>& strs) {
        int len = strs.size();
        if(len < 2)
            return len ? strs[0] : "";
        int i = -1;
        bool flag = true;
        while(flag)
        {
            char cc = strs[0][++i];
            if(cc == '\0')  return strs[0].substr(0,i);
            for(int j = 1;j < len;j++)
                if(strs[j][i] != cc)
                    return strs[0].substr(0,i);
        }
        return "";
    }
};

2、两两比较法:先求出前两个字符串公共前缀 ans
再求 ans 和之后字符串的公共前缀
若公共字符串为 “” ,则直接 return “”
否则直至循环终止
时间复杂度: O(n),n为全部字符串长度和
所需空间: O(1)

class Solution {
public:
    string longestCommonPrefix(vector<string>& strs) {
        if(strs.size() == 1)     return strs[0];
        if(strs.size() == 0)     return "";
		string ans = CommonPrefix(strs[0], strs[1]);
        for(int i = 2; i < strs.size(); i++)
        {
        	ans = CommonPrefix(ans, strs[i]);
            if(ans == "")   break;
        }
        return ans;
    }
    // 两字符串最长公共前缀
    string CommonPrefix(string s1, string s2)
    {
        string ans = "";
        int len = s1.length() < s2.length() ? s1.length() : s2.length();
        for(int i = 0; i < len; i++)
        {
            if(s1[i] != s2[i])
            {
                break;
            }
            ans += s1[i];
        }
        return ans;
    }
};

3、分治算法
要求最长公共子序列
可将问题分为求 n 个相邻子序列的公共子序列
依次递归求出答案
时间复杂度:O(n)
所需空间:O(mlogn) 所需空间主要是递归开辟的栈空间;

class Solution {
public:
    string longestCommonPrefix(vector<string>& strs) {
        if(strs.size() == 1)     return strs[0];
        if(strs.size() == 0)     return "";
		return longestCommonPrefix(strs, 0 , strs.size() - 1);
    }
    string longestCommonPrefix(vector<string>& strs, int left, int right)
    {
        if(left == right)
        {
            return strs[left];
        }
        else
        {
            int mid = (left + right) / 2;
            string lcommon = longestCommonPrefix(strs, left, mid);
            string rcommon = longestCommonPrefix(strs, mid + 1, right);
            return CommonPrefix(lcommon, rcommon);
        }
    }
    // 两字符串最长公共前缀
    string CommonPrefix(string s1, string s2)
    {
        string ans = "";
        int len = s1.length() < s2.length() ? s1.length() : s2.length();
        for(int i = 0; i < len; i++)
        {
            if(s1[i] != s2[i])
            {
                break;
            }
            ans += s1[i];
        }
        return ans;
    }
};

4、双指针法:即就是两个for循环;

class Solution {
public:
    string longestCommonPrefix(vector<string>& strs) {
        //双指针法:指针i指向每串字符的同一个位置的字符,指针j用来遍历每个字符串
        if(strs.empty())return string();
        else if(strs.size()==1)return strs[0];
        string result="";
        //取第一个字符串为最长公共前缀,然后遍历每个字符串,来确定实际的最长公共前缀
        for(int i=0;i<strs[0].size();++i)//i表示指向每个字符串的同一个位置的字符
        {
            for(int j=1;j<strs.size();++j)//j遍历到每个字符串
                if(strs[0][i]!=strs[j][i])
                    return result;
            result+=strs[0][i];
        }
        return result;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值