【C++算法】61.字符串_最长公共前缀

文章目录

    • 题目链接:
    • 题目描述:
    • 解法
    • C++ 算法代码:
    • 解释


题目链接:

14. 最长公共前缀


题目描述:

【C++算法】61.字符串_最长公共前缀_第1张图片


解法

解法一:两两比较

先算前两个字符串的最长公共前缀,然后拿这个最长公共前缀和后面一个来比较,得到最长公共前缀。直到比到最后一个字符串。

解法二:统一比较

先比较第一列,然后比较第2列,直到有字符串越界,或者有字符不一样,停止。


C++ 算法代码:

解法一(两两比较):

class Solution 
{
public:
    string longestCommonPrefix(vector<string>& strs) 
    {
        // 解法一:两两比较法
        // 基本思路:先用第一个字符串作为基准,然后依次与后面的每个字符串比较
        // 每次比较后更新公共前缀,最终得到整个数组的最长公共前缀
        
        // 初始化返回结果为第一个字符串
        // 如果数组为空,此处可能会出错,但题目通常保证输入非空
        string ret = strs[0];
        
        // 从第二个字符串开始,依次与当前的公共前缀比较
        for(int i = 1; i < strs.size(); i++)
            // 调用辅助函数findCommon计算当前公共前缀与下一个字符串的公共前缀
            // 并更新公共前缀结果
            ret = findCommon(ret, strs[i]);
            
        // 返回最终的最长公共前缀
        return ret;
    }
    
    // 辅助函数:计算两个字符串的最长公共前缀
    string findCommon(string& s1, string& s2)
    {
        // 用索引i遍历两个字符串
        int i = 0;
        
        // 条件一:确保不越界,只比较到较短字符串的长度
        // 条件二:当前位置字符必须相同才继续
        while(i < min(s1.size(), s2.size()) && s1[i] == s2[i]) 
            i++; // 字符相同,继续比较下一个字符
        
        // 截取s1的前i个字符作为公共前缀返回
        // 此时i表示公共前缀的长度,可能为0(无公共前缀)
        // substr(pos,len)返回一个新的字符串,包含原字符串从pos位置开始的len个字符
        return s1.substr(0, i);
    }
};

解法二(统一比较):

class Solution 
{
public:
    string longestCommonPrefix(vector<string>& strs) 
    {
        // 解法二:统一比较(逐列比较)
        // 基本思路:逐个字符位置比较所有字符串,只要发现不一致就立即返回结果
        
        // 从第一个字符串的第一个字符开始,逐位置向后比较
        // strs[0]:访问字符串数组的第一个元素(即第一个字符串)
        // strs[0].size():获取第一个字符串的长度
        // i < strs[0].size():判断索引i是否小于第一个字符串的长度
        for(int i = 0; i < strs[0].size(); i++)
        {
            // 获取第一个字符串在当前位置的字符作为比较基准
            char tmp = strs[0][i];
            
            // 遍历剩余的所有字符串,检查它们在相同位置的字符是否与基准相同
            // strs:输入的字符串数组(vector类型)
            // strs.size():获取字符串数组中的字符串数量
            // j < strs.size():判断索引j是否小于数组的大小
            for(int j = 1; j < strs.size(); j++)
                // 两种情况需要立即返回当前已找到的公共前缀:
                // 1. 当前字符串长度不够(i已经超出范围)
                // 2. 当前字符串在位置i的字符与基准不同
                // i == strs[j].size():检查当前检查的字符位置i是否等于当前字符串strs[j]的长度。就是"当前字符串是否已经到达末尾?"
				// tmp != strs[j][i]:检查基准字符tmp(即第一个字符串在位置i的字符)是否与当前字符串strs[j]在同一位置的字符不同。
                if(i == strs[j].size() || tmp != strs[j][i])
                    // 返回第一个字符串的前i个字符作为最长公共前缀
                    return strs[0].substr(0, i);
        }
        
        // 如果循环正常结束(没有提前返回),说明第一个字符串是所有字符串的前缀
        // 返回第一个字符串作为最长公共前缀
        return strs[0];
    }
};

解释

例如:["flower", "flow", "flight"]

执行过程:

  1. i=0: 比较所有字符串的第0个字符
    • strs[0][0] = 'f'
    • strs[1][0] = 'f'
    • strs[2][0] = 'f'
    • 全部匹配,继续
  2. i=1: 比较所有字符串的第1个字符
    • strs[0][1] = 'l'
    • strs[1][1] = 'l'
    • strs[2][1] = 'l'
    • 全部匹配,继续
  3. i=2: 比较所有字符串的第2个字符
    • strs[0][2] = 'o'
    • strs[1][2] = 'o'
    • strs[2][2] = 'i' ≠ 'o'
    • 发现不匹配,返回strs[0].substr(0, 2) = “fl”

你可能感兴趣的:(优选算法C++,算法,c++)