文章目录
- 题目链接:
- 题目描述:
- 解法
- C++ 算法代码:
- 解释
题目链接:
14. 最长公共前缀
题目描述:
解法
解法一:两两比较
先算前两个字符串的最长公共前缀,然后拿这个最长公共前缀和后面一个来比较,得到最长公共前缀。直到比到最后一个字符串。
解法二:统一比较
先比较第一列,然后比较第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<string>类型)// 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"]
执行过程:
- i=0: 比较所有字符串的第0个字符
strs[0][0] = 'f'
strs[1][0] = 'f'
strs[2][0] = 'f'
- 全部匹配,继续
- i=1: 比较所有字符串的第1个字符
strs[0][1] = 'l'
strs[1][1] = 'l'
strs[2][1] = 'l'
- 全部匹配,继续
- i=2: 比较所有字符串的第2个字符
strs[0][2] = 'o'
strs[1][2] = 'o'
strs[2][2] = 'i' ≠ 'o'
- 发现不匹配,返回strs[0].substr(0, 2) = “fl”