(1)找字符串最长回文子串
- 指定一个字符串str,找到字符串中长度 >=2 的最长回文子串,不存在则返回null
举例
const str1 = 'abcdeed';
const str2 = 'abcbaefabc';
const str3 = 'abcdefg';
实现
const testPDString = (str) => typeof str === 'string' ? !str.split('').some((ele, i) => ele !== str.at(-1 - i)) : alert('请入参字符串');
const arrangeStrIntermittent = (str) => {
const strComList = [];
let strArr;
if (typeof str === 'string') {
strArr = str.split('');
} else if (Array.isArray(str)) {
strArr = [...str];
} else {
throw 'The arrangeStrIntermittent input parameter can only be a string or array';
}
for (let i = 0; i < strArr.length; i++) {
strComList.push(strArr[i]);
loopStr(strArr, i, [strArr[i]]);
}
function loopStr(arr, i, prev) {
i++;
if (i < arr.length) {
for (let j = i; j < arr.length; j++) {
const list = prev.concat(arr[j]);
strComList.push(list.join());
loopStr(arr, j, list)
}
}
}
return strComList;
};
const arrangeStrContinuity = (str) => {
const strComList = [];
let strArr;
if (typeof str === 'string') {
strArr = str.split('');
} else if (Array.isArray(str)) {
strArr = [...str];
} else {
throw 'The arrangeStrContinuity input parameter can only be a string or array';
}
for (let i = 0; i < strArr.length; i++) {
strComList.push(strArr[i]);
let prev = [strArr[i]];
for (let j = i + 1; j < strArr.length; j++) {
prev = prev.concat(strArr[j]);
strComList.push(prev.join());
}
}
return strComList;
};
const findMaxLenStrPD = (str, strType = true) => {
const list = strType ? arrangeStrContinuity(str) : arrangeStrIntermittent(str);
const result = list.filter(ele => testPDString(ele) && ele.length > 1);
return result.length === 0 ? null : result.reduce((ret, ele) => ret.length > ele.length ? ret : ele, '').replace(/,/g, '');
};
console.log(findMaxLenStrPD('abcdeed'));
console.log(findMaxLenStrPD('abcbaefabc'));
console.log(findMaxLenStrPD('abcdefg'));
console.log(findMaxLenStrPD('abcbaefghgfe'));
(2)找字符串数组中的最长公共前缀
举例
const list1 = ['apple', 'app', 'angel'];
const list2 = ['abcd', 'efg', 'hijk'];
实现
const findLongStrPrefix = (arr) => {
if (!Array.isArray(arr)) {
throw 'The findLongStrPrefix input parameter must be an array';
}
const strArr = arr[0].split('');
let str = '';
for (let i = 0; i < strArr.length; i++) {
for (let j = 1; j < arr.length; j++) {
if (arr[j][i] !== strArr[i]) {
return str;
}
}
str += strArr[i];
}
return str;
}
console.log(findLongStrPrefix(['apple', 'app', 'angel']));
console.log(findLongStrPrefix(['abcd', 'efg', 'hijk']));
(3)找字符串中无重复字符的最长子串
- 给定一个字符串 str ,找出其中不含有重复字符的【最长子串】的长度。
举例
const str1 = 'abcdefghaccba';
const str2 = 'appopqrstaubvcwxyzppa';
const str3 = 'eeqwrdf';
实现
const findLongSubStringLen = (str) => {
if (typeof str !== 'string') {
throw 'The findLongSubStringLen input parameter must be a string';
}
const newArr = str.split(''), strList = [], len = newArr.length;
for (let i = 0; i < len; i++) {
let prev = [newArr[i]];
strList.push(prev);
for (let j = i + 1; j < len; j++) {
if (strList[i].includes(newArr[j])) {
break;
} else {
strList[i].push(newArr[j]);
}
}
}
return strList.reduce((res, ele) => res.length > ele.length ? res : ele, []).length;
let endIndex = 0, startIndex = 0, step = 0; maxStr = '', maxLen = 0;
const subStrDict = {};
while (endIndex < str.length) {
const endStr = str[endIndex];
endIndex++;
if (subStrDict[endStr]) {
step++;
subStrDict[endStr]++;
} else {
subStrDict[endStr] = 1;
}
while (step || endIndex === str.length) {
if (maxLen < endIndex - startIndex) {
maxLen = endIndex - startIndex;
maxStr = str.slice(startIndex, step ? endIndex - 1 : endIndex);
}
const startStr = str[startIndex];
startIndex++;
subStrDict[startStr]--;
if (startStr === endStr) step--;
if (endIndex === str.length) endIndex++;
}
}
return maxStr.length;
};
console.log(findLongSubStringLen('abcdefghaccba'));
console.log(findLongSubStringLen('appopqrstaubvcwxyzppa'));
console.log(findLongSubStringLen('eeqwrdf'));
(4)找A、B字符串中A对B的最小覆盖子串
- 有A、B两个字符串,从A字符串中寻找涵盖B字符串全部字符的【最小子串】;如果不存在该子串,返回""
- 对于【B】中重复字符,我们在【A】寻找的子字符串中该字符数量不得少于【B】中该字符数量。
举例
const strA = 'appopqrsctaubvctwxyzppa', strB = 'atv';
const strA = 'bcbc', strB = 'bb';
const strA = 'bc', strB = 'cc';
实现(利用滑动窗口实现)
const findMinSubString = (parent, sub) => {
const subDict = {}, parentDict = {};
for (const ele of sub) subDict[ele] ? subDict[ele]++ : subDict[ele] = 1;
const subDictLen = Object.keys(subDict).length;
let LIndex = RIndex = step = 0, minStrLen = parent.length + 1, minSubStr = '';
while (RIndex < parent.length) {
const p = parent[RIndex];
RIndex++;
parentDict[p] ? parentDict[p]++ : parentDict[p] = 1
if (subDict[p] && subDict[p] === parentDict[p]) step++;
while (step === subDictLen) {
if (minStrLen > RIndex - LIndex) {
minStrLen = RIndex - LIndex;
minSubStr = parent.slice(LIndex, RIndex);
}
const s = parent[LIndex];
parentDict[s]--;
LIndex++;
if (subDict[s] && subDict[s] > parentDict[s]) step--;
}
}
return minSubStr;
};
console.log(findMinSubString('appopqrsctaubvctwxyzppa', 'atv'));
console.log(findMinSubString('bcbc', 'bb'));
console.log(findMinSubString('bc', 'cc'));