题目:
例子:
分析题目:
主要目的:求出各个字符串的公共前缀
思路(本人解法):
用所给实例来看,不难看出我们可以直接以竖着对应来查看是否是公共前缀 ,
这样就有了一定的思路 , 然后接着想如何让他找到最长的公共前缀后就 停止下来呢
这样就能想到,从最短的字符串下手(因为公共前缀最长就只能是最短的字符串或者是最长字符串的前几个)
这样就有了大概的轮廓:
- 找到最短字符串(记录其长度)
- 通过比较的方法依次竖向比较,然后遍历(每个字符串和每个对应的前缀),找到公共前缀的最后(也就是不同/len的时候就能退出了)竖向比较:
Cyy:
char * longestCommonPrefix(char ** strs, int strsSize){
int i = 0;
int j = 0;
//找到最短的字符串以及记录其最短的长度
int len = strlen(strs[0]);
for(int i = 1 ; i < strsSize ; i++)
{
if(strlen(strs[i]) < len)
{
len = strlen(strs[i]);
}
}
//竖向比较
//从下标为0处开始,到最短字符串的最后一个字符(len-1)
for(i = 0; i < len ;i++)
{
for(j = 1; j < strsSize;j++)//比较每个字符串的下标i处的字符是否相等(此时进行竖向比较)
{
if(strs[j][i] != strs[j-1][i])//当有不同的时候就退出
break;
}
if(j != strsSize)//到此处有两种可能,一是有不同中途退出的,二是全部相同后自然退出的
break;//当不是自然退出的时候 j != strSize 、 此时就表示已经找到公共前缀的最后一个那就退出循环
}
strs[0][i] = '\0';//直接把下标i处换成\0,这里利用了字符串以\0结尾的特性
return strs[0];
}
通过查看官方给的答案后进一步优化:
此时我们还能不再判断最短的字符串
而是直接在内部来查看,当竖向查找到了其中一个字符串的最后一个元素时就退出循环
char * longestCommonPrefix(char ** strs, int strsSize){
int i = 0;
int j = 0;
int len = strlen(strs[0]);
for(i = 0; i < len ;i++)
{
for(j = 1; j < strsSize;j++)
{
if(strs[j][i] != strs[j-1][i] || strlen(strs[j]) == i)//此处进行了优化
break;
}
if(j != strsSize)
break;
}
strs[0][i] = '\0';
return strs[0];
}
C++:
class Solution {
public:
string longestCommonPrefix(vector<string>& strs) {
int number = strs.size();
int len = strs[0].size();
for(int i = 0; i < len;i++)
{int j;
for(j = 1 ; j < number;j++)
{
if(strs[j][i] != strs[0][i] || strs[j].size() == i)
break;
}
if(j != number)
return strs[0].substr(0,i);
}
return strs[0];
}
};
总结学到什么:
- 模拟法(模拟题目所给步骤来解决问题)
- 用些地方可以进行优化
- 优化后不用再查找最小字符串(因为后面有需要遍历的字符串所以可以再后面再进行 与i的进行判断看是否到某些字符串的结尾了)
- 字符串以\0结尾可以把一个字符串的某个位置改成\0这样就修改了结尾