トピック:
例:
分析トピック:
主な目的: 各文字列の共通プレフィックスを見つける
アイデア (私の解決策):
与えられた例を見ると、それがパブリック プレフィックスであるかどうかを垂直対応によって直接確認できることがわかります。
このようにして、あるアイデアがあり、最長の共通プレフィックスを見つけた後、どうすれば停止させるかを考えます。
このようにして、最も短い文字列から開始することを考えることができます (最も長い共通プレフィックスは、最も短い文字列か、最も長い文字列の最初の数文字のみであるため)
これにより、大まかな概要が得られます。
- 最も短い文字列を検索します (その長さを記録します)
- 比較メソッドを使用して垂直方向に順番に比較し、(各文字列と対応する各プレフィックスを) 横断して、共通のプレフィックスの最後のものを見つけます (つまり、異なる/len の場合に終了できます)。垂直比較:
サイ:
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];
}
公式の回答を見てさらに最適化します。
この時点では、最短の文字列を判断できなくなります。
代わりに、内部を直接チェックし、文字列の 1 つの最後の要素が垂直方向に見つかったときにループを終了します。
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 に変更すると、末尾が変更されます。