算法题-双指针(最长的指定瑕疵度的元音子串(答案、解析))

目录

题目

最长的指定瑕疵度的元音子串

题目描述

解答要求

答案

解析

核心思想


题目

注意要选好先判断左指针还是右指针可以节省不必要的操作。

最长的指定瑕疵度的元音子串

hash算法、双指针

题目描述

定义:开头和结尾都是元音字母(aeiouAEIOU)的字符串为元音字符串,其中混杂的非元音字母数量为瑕疵度。比如:

“a”、“aa”是元音字符串,其瑕疵度都为0

“aiur”不是元音字符串(结尾不是元音字符)

“abira”是元音字符串,其瑕疵度为2

给定一个字符串,请找出指定瑕疵度的最长元音字符子串,并输出其长度,如果找不到满足条件的元音字符子串,输出0.

子串:字符串中任意个连续的字符组成的子序列称为该字符串的子串

解答要求

时间限制:1000ms,内存限制:256MB

输入

首行输入是一个整数,表示预期的瑕疵度flaw,取值范围[0,65535]。

接下来一行是一个仅由字符a-z和A-Z组成的字符串,字符串长度(0,65535]。

输出

输出为一个整数,代表满足条件的元音字符子串的长度。

样例

输入样例1

0

asdbuiodevauufgh

输出样例1

3

提示样例1

满足条件的最长元音字符子串有两个,分别为uio和auu,长度为3。

输入样例2

2

aeueo

输出样例2

0

提示样例2

没有满足条件的元音字符子串,输出0.

输入样例3

1

aabeebuu

输出样例3

5

提示样例3

满足条件的最长元音字符子串有两个,分别为aabee和eebuu,长度为5

答案

const getLongestFlawedVowelSubstrLen = (flaw, input) => {
    input = input.toLowerCase()
    //利用hash算法确定是否为元音
    let au = {
        a: 1,
        e: 1,
        i: 1,
        o: 1,
        u: 1
    }
    let left = 0
    let right = 0
    let arr = []
    let count = 0
    //每次循环右指针向右进一格,直到遍历完数组
    for (right = 0; right < input.length; right++) {
        //利用哈希算法判断右指针是否为元音,即子串结尾要求时元音
        let isRightYuan = au[input[right]] === 1 ? true : false
        if (isRightYuan === false) {
            count++
        }
        //要求足够的瑕疵度
        if (isRightYuan === false || count < flaw) {
            continue
        }
        //足够的瑕疵度,且左边的也是元音,则记录该子串
        if (count === flaw && au[input[left]] === 1) {
            let temp = input.substring(left, right + 1)
            arr.push(temp)
            continue
        }
        //当瑕疵度大于要求的瑕疵度或子串左边非元音时,需要移动左指针
        while (count > flaw || au[input[left]] !== 1) {
            left++
            if (au[input[left - 1]] !== 1) {
                count--
            }
            if (left > right) {
                left = right
                break
            }
        }
        //记录跳出循环时是否符合要求
        if (count == flaw && au[input[left]] === 1) {
            let temp = input.substring(left, right + 1)
            arr.push(temp)
        }
    }
    if (arr.length > 1) {
        //按长度大小给子串排序
        arr.sort((a, b) => b.length - a.length)
        if (arr.length > 0) {
            return arr[0].length
        }
    } else if (arr.length === 1) {
        return arr[0].length
    } else {
        return 0
    }
}
console.log(getLongestFlawedVowelSubstrLen(0, 'asdbuiodevauufgh'))

解析

注意每次如果先判断左指针则每次都要将右指针从头判断到尾,而先判断右指针,左指针只用在原先的基础上移动到下一个符合条件的位置,这样可以节省很多多余的判断。

核心思想

先确定右指针是否为元音,否就右移,是就判断瑕疵度是否够且左指针也为元音,都满足才记录,不满足,瑕疵度不够就继续右移右指针,瑕疵度超过就右移左指针,直到瑕疵度小于或等于指定瑕疵度,并进行判断是否记录,最后右移右指针进行下次循环。

你可能感兴趣的:(算法,最长的指定瑕疵度的元音子串,双指针算法题,hash算法应用算法题,双指针算法题注意点,js解双指针算法题)