日常刷题0x9之德玛蹲草丛

91 阅读1分钟

此阶段给自己定的目标是:做过的这些题每天坚持继续刷二遍,每道题做过之后开始尝试多解法尝试解题。上一阶段是感知都有什么题目,此阶段主要系统化常规题解套路知识,牢记牢记此阶段目的。

题号:28
//暴力遍历
var strStr = function (haystack, needle) {

    if (needle.length == 0) {
        return 0
    }

    for (let i = 0; i < haystack.length; i++) {
        for (let j = 0; j < needle.length; j++) {
            let char1 = haystack[i + j]
            let char2 = needle[j]
            if (char1 == char2) {
                if (j == needle.length - 1) {
                    return i
                }
                continue
            }
            break
        }
    }
    return -1
};

//KMP算法
var strStr = function (haystack, needle) {

    if (needle.length == 0) {
        return 0
    }
    //构建next数组
    //next数组是针对匹配串的而不是针对主串的
    const nextArr = new Array(needle.length).fill(0)

    let maxK = 0
    for (let i = 1, j = 0; i < needle.length; i++) {

        while (maxK > 0 && needle[maxK] != needle[i]) {
            maxK = nextArr[maxK - 1]
        }
        if (needle[maxK] == needle[i]) {
            maxK++;
        }
        nextArr[i] = maxK;
    }

    let i = 0
    while (i < haystack.length) {
        let j = 0
        while (j < needle.length) {
            if (haystack[i] == needle[j]) {
                if (j == needle.length - 1) {
                    //找到位置符合题意
                    //此时的i是比较的和needle相等的字符的最后一个位置要做计算才是首坐标i - needle.length + 1
                    return i - needle.length + 1
                } else {
                    i++
                    j++
                    continue
                }
            } else {
                //当前位置字符串不相等
                if (j == 0) {
                    //开始比较的第一个就不相等
                    i++
                } else {
                    //这里才是和暴力求解的不同之处
                    //暴力求解是一次移动一个这里是一次移动好几个
                    i -= nextArr[j - 1]
                }
                break
            }
        }
    }
    return -1;
};
题号:125
var isPalindrome = function (s) {

    let left = 0, right = s.length - 1
    while (left < right) {

        if (check(s[left]) && check(s[right])) {
            if (s[left].toLowerCase() != s[right].toLowerCase()) {
                return false
            }
            left++
            right--
        }
        if (!check(s[left])) {
            left++
        }
        if (!check(s[right])) {
            right--
        }
    }
    return true
};
function check(aChar) {
    if (aChar >= 'a' && aChar <= 'z' || aChar >= 'A' && aChar <= 'Z' || aChar >= '0' && aChar <= '9') {
        return true
    }
    return false
}
题号:680
var validPalindrome = function (s) {
    //count可以删除字母的次数
    let left = 0, right = s.length - 1, count = 1
    while (left < right) {
        if (s[left] != s[right]) {
            //如果发现leftright指向的字母不相等就默认使用count的次数调过继续下个迭代比较
            //跳过此时的left还是right都可以我这边先跳过当前的left下一个while循环跳过right
            if (count > 0) {
                left++
                count--
            } else {
                count--
                break
            }
        } else {
            left++
            right--
        }
    }
    if (count < 0) {
        count = 1, left = 0, right = s.length - 1
        while (left < right) {
            if (s[left] != s[right]) {
                if (count > 0) {
                    right--
                    count--
                } else {
                    return false
                }
            } else {
                left++
                right--
            }
        }
    }
    return true
};