本文共 4140 字,大约阅读时间需要 13 分钟。
// 自己想出来的算法,纵向扫描class Solution{ public: string longestCommonPrefix(vector&strs) { string res = ""; if(!strs.size()) return res; for (int i = 0; i < strs[0].length(); i++) { // 取出第一个字符串中的字符 char ch = strs[0][i]; // 与其他字符串对应位置的字符比较 for (int j = 1; j < strs.size(); j++) { if (strs[j][i] != ch) return res; } res.push_back(ch); } return res; }};
// JS实现var longestCommonPrefix = function (strs) { var res = ""; if (strs.length === 0) return res; for (var i = 0; i < strs[0].length; i++) { var ch = strs[0][i]; for (var j = 1; j < strs.length; j++) { if (strs[j][i] != ch) return res; } res += ch; } return res;};
/* LCP计算满足结合律:LCP(S1...Sn)=LCP(LCP(S1...Sk),LCP(Sk+1...Sn))分治法得到字符串数组中的最长公共前缀,对于问题可以分解为两个子问题,其中k=i+j/2。然后将两个子结果求公共前缀 */class Solution{ public: string longestCommonPrefix(vector&strs) { if (!strs.size()) return ""; else return longestCommonPrefix(strs, 0, strs.size() - 1); } string longestCommonPrefix(const vector &strs, int start, int end) { if (start == end) return strs[start]; else { int mid = (start + end) / 2; string lcpLeft = longestCommonPrefix(strs, start, mid); string lcpRight = longestCommonPrefix(strs, mid + 1, end); return commonPrefix(lcpLeft, lcpRight); } } string commonPrefix(const string &lcpLeft, const string &lcpRight) { int minLength = min(lcpLeft.size(), lcpRight.size()); for (int i = 0; i < minLength; ++i) { if (lcpLeft[i] != lcpRight[i]) return lcpLeft.substr(0, i); } return lcpLeft.substr(0, minLength); }};/* 时间复杂度:O(mn),其中m是字符串数组中的字符串的平均长度,n是字符串的数量。时间复杂度的递推式是 T(n)=2*T(n/2)+O(m),通过计算可得 T(n)=O(mn)。空间复杂度:O(mlogn),其中 m 是字符串数组中的字符串的平均长度,n 是字符串的数量。空间复杂度主要取决于递归调用的层数,层数最大为logn,每层需要 m 的空间存储返回结果。作者:LeetCode-Solution链接:https://leetcode-cn.com/problems/longest-common-prefix/solution/zui-chang-gong-gong-qian-zhui-by-leetcode-solution/来源:力扣(LeetCode)著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。 */
/* 显然,最长公共前缀的长度不会超过字符串数组中的最短字符串的长度。用minLength 表示字符串数组中的最短字符串的长度,则可以在][0,minLength] 的范围内通过二分查找得到最长公共前缀的长度。每次取查找范围的中间值 mid,判断每个字符串的长度为mid 的前缀是否相同,如果相同则最长公共前缀的长度一定大于或等于mid,如果不相同则最长公共前缀的长度一定小于mid,通过上述方式将查找范围缩小一半,直到得到最长公共前缀的长度。作者:LeetCode-Solution链接:https://leetcode-cn.com/problems/longest-common-prefix/solution/zui-chang-gong-gong-qian-zhui-by-leetcode-solution/来源:力扣(LeetCode)著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。 */#include#include #include using namespace std;class Solution{ public: string longestCommonPrefix(vector &strs) { if (!strs.size()) { return ""; } int minLength = min_element(strs.begin(), strs.end(), [](const string &s, const string &t) { return s.size() < t.size(); })->size(); int low = 0, high = minLength; while (low < high) { int mid = (high - low + 1) / 2 + low; if (isCommonPrefix(strs, mid)) { low = mid; } else { high = mid - 1; } } return strs[0].substr(0, low); } bool isCommonPrefix(const vector &strs, int length) { string str0 = strs[0].substr(0, length); int count = strs.size(); for (int i = 1; i < count; ++i) { string str = strs[i]; for (int j = 0; j < length; ++j) { if (str0[j] != str[j]) { return false; } } } return true; }};/* 时间复杂度:O(mnlogm),其中 m 是字符串数组中的字符串的最小长度,n 是字符串的数量。二分查找的迭代执行次数是 O(logm),每次迭代最多需要比较 mn 个字符,因此总时间复杂度是O(mnlogm)。空间复杂度:O(1)。使用的额外空间复杂度为常数。 */