I am trying to solve the Leet Code challenge 14. Longest Common Prefix:
Write a function to find the longest common prefix string amongst an array of strings.
If there is no common prefix, return an empty string
"".Example 1:
Input: strs = ["flower","flow","flight"] Output: "fl"Example 2:
Input: strs = ["dog","racecar","car"] Output: ""Explanation: There is no common prefix among the input strings.
Constraints:
1 <= strs.length <= 2000 <= strs[i].length <= 200strs[i]consists of only lower-case English letters.
let strs = ["flower", "flow", "flight"];
var longestCommonPrefix = function (strs) {
for (let i = 0; i < strs.length; i++) {
for (let j = 0; j < strs[i].length; j++) {
// console.log(strs[i+2][j]);
if (strs[i][j] == strs[i + 1][j] && strs[i + 1][j] ==strs[i + 2][j]) {
return (strs[i][j]);
} else {
return "0";
}
}
}
};
console.log(longestCommonPrefix(strs));
Output: f
How can I iterate over every character and check if it is same and then go for next and if it fails then the longest common prefix will be returned?
As the longest common prefix must occur in every string of the array you can jus iterate over the length and check if all words have the same char at that index until you find a difference
function prefix(words){
// check border cases size 1 array and empty first word)
if (!words[0] || words.length == 1) return words[0] || "";
let i = 0;
// while all words have the same character at position i, increment i
while(words[0][i] && words.every(w => w[i] === words[0][i]))
i++;
// prefix is the substring from the beginning to the last successfully checked i
return words[0].substr(0, i);
}
console.log(1, prefix([]));
console.log(2, prefix([""]));
console.log(3, prefix(["abc"]));
console.log(4, prefix(["abcdefgh", "abcde", "abe"]));
console.log(5, prefix(["abc", "abc", "abc"]));
console.log(6, prefix(["abc", "abcde", "xyz"]));
Some of the issues:
Your inner loop will encounter a return on its first iteration. This means your loops will never repeat, and the return value will always be one character.
It is wrong to address strs[i+1] and strs[i+2] in your loop, as those indexes will go out of bounds (>= strs.length)
Instead of performing character by character comparison, you could use substring (prefix) comparison (in one operation): this may seem a waste, but as such comparison happens "below" JavaScript code, it is very fast (and as string size limit is 200 characters, this is fine).
The algorithm could start by selecting an existing string as prefix and then shorten it every time there is a string in the input that doesn't have it as prefix. At the end you will be left with the common prefix.
It is good to start with the shortest string as the initial prefix candidate, as the common prefix can certainly not be longer than that.
var longestCommonPrefix = function(strs) {
let prefix = strs.reduce((acc, str) => str.length < acc.length ? str : acc);
for (let str of strs) {
while (str.slice(0, prefix.length) != prefix) {
prefix = prefix.slice(0, -1);
}
}
return prefix;
};
let res = longestCommonPrefix(["flower","flow","flight"]);
console.log(res);
An approach based on sorting by word length, and for the shortest word, for exiting early, an entirely Array.every-based prefix-validation and -aggregation ...
function longestCommonPrefix(arr) {
const charList = [];
const [shortestWord, ...wordList] =
// sort shallow copy by item `length` first.
[...arr].sort((a, b) => a.length - b.length);
shortestWord
.split('')
.every((char, idx) => {
const isValidChar = wordList.every(word =>
word.charAt(idx) === char
);
if (isValidChar) {
charList.push(char);
}
return isValidChar;
});
return charList.join('');
}
console.log(
longestCommonPrefix(["flower","flow","flight"])
);
.as-console-wrapper { min-height: 100%!important; top: 0; }