每日一道算法 Day3

105 阅读1分钟

题目描述如下:

截屏2021-07-29 下午10.03.47.png

大致思路: 将目标数组转化为由每一项的每个对应序号字符串拼接起来的数组...好像有点绕, 实现效果为:

 test('generateArr', () => {
    expect(generateArr(['abc', 'dfg'])).toEqual(['ad', 'bf', 'cg']);
    expect(generateArr(['abc', 'cd'])).toEqual(['ac', 'bd', 'c ']);
    expect(generateArr(['aaa', 'aa', 'aaa'])).toEqual(['aaa', 'aaa', 'a a']);
  });

实现代码如下:

 const tmpArr: string[] = [];

  strs.forEach((str) => {
    //有问题的版本  ['aaa', 'aa', 'aaa'] 会转化为 ['aaa', 'aaa', 'aa'], 导致最后结果为 'aaa'
    // Array.from(str).forEach((s, index) => {
    //   tmpArr[index] = (tmpArr[index] ? tmpArr[index] : '') + s;
    // }); 
    //正确版本   ['aaa', 'aa', 'aaa'] 会转化为 ['aaa', 'aaa', 'a a'], 最后结果为正确答案 'aa'
    for (let i = 0; i < strs[0].length; ++i) {
      tmpArr[i] = (tmpArr[i] ? tmpArr[i] : '') + (str[i] ?? ' ');
    }
  });

判断转化后的数组的每一项是否由相同字符组成, 使用正则判断:

for (let i = 0; i < tmpArr.length; ++i) {
    const tmp = tmpArr[i];
    if (/^(\w)\1{1,}$/.test(tmp)) {
    //都为同项的情况且长度大于1
      res += tmp[0];
    } else {
    //有不相同项, 直接跳出循环
      break;
    }
  }

考虑一些特殊情况:

  if (strs.includes('') || !strs.length) return '';
  if (strs.length === 1) return strs[0];

最终代码:

 function longestCommonPrefix(strs: string[]): string {
  let res = '';
  
  if (strs.includes('') || !strs.length) return res;
  if (strs.length === 1) return strs[0];

  const tmpArr: string[] = [];

  strs.forEach((str) => {
    // Array.from(str).forEach((s, index) => {
    //   tmpArr[index] = (tmpArr[index] ? tmpArr[index] : '') + s;
    // });
    for (let i = 0; i < strs[0].length; ++i) {
      tmpArr[i] = (tmpArr[i] ? tmpArr[i] : '') + (str[i] ?? ' ');
    }
  });

  for (let i = 0; i < tmpArr.length; ++i) {
    const tmp = tmpArr[i];
    if (/^(\w)\1{1,}$/.test(tmp)) {
      res += tmp[0];
    } else {
      break;
    }
  }

  return res;
}

提交时失败了几次, 一次是少判断长度为1的情况, 另一次是 ['aaa', 'aa', 'aaa']的情况, 还是漏考虑了几种边界情况, 希望以后的我能少出现这种错误。