自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

十五周算法訓(xùn)練營(yíng)——滑動(dòng)窗口

開發(fā) 前端
今天是十五周算法訓(xùn)練營(yíng)的第七周,主要講滑動(dòng)窗口專題。

// 滑動(dòng)窗口算法解題思路
1. 使用雙指針技巧,初始化left=right=0,把索引左閉右開區(qū)間[left, right)稱為一個(gè)窗口
2. 先不斷增加right指針,擴(kuò)大窗口
3. 當(dāng)結(jié)果不符合要求,進(jìn)行窗口收縮
4. 重復(fù)2、3步,直到終止條件

和為s的連續(xù)正數(shù)序列

輸入一個(gè)正整數(shù) target ,輸出所有和為 target 的連續(xù)正整數(shù)序列(至少含有兩個(gè)數(shù))。

序列內(nèi)的數(shù)字由小到大排列,不同序列按照首個(gè)數(shù)字從小到大排列。

示例 1:

輸入:target = 9 輸出:[[2,3,4],[4,5]]

// 該問題是一個(gè)滑動(dòng)窗口問題
// 滑動(dòng)窗口算法解題思路
// 1. 使用雙指針技巧,初始化left=right=0,把索引左閉右開區(qū)間[left, right)稱為一個(gè)窗口
// 2. 先不斷增加right指針,擴(kuò)大窗口
// 3. 當(dāng)結(jié)果不符合要求,進(jìn)行窗口收縮
// 4. 重復(fù)2、3步,直到終止條件
function findContinuousSequence(target) {
    const result = [];
    // 滑動(dòng)窗口
    const window = [];
    let sum = 0;
    const middle = (target + 1) << 1;
    let left = 1;
    let right = 1;

    for (let i = 1; i <= middle; i++) {
        // 擴(kuò)充窗口
        window.push(i);
        sum += i;
        right++;

        // 判斷是否收縮窗口
        while (sum > target) {
            // 進(jìn)行窗口收縮
            const temp = window.shift();
            left++;
            sum -= temp;
        }

        if (sum === target && window.length > 1) {
            result.push([...window]);
        }
    }

    return result;
}

console.log(findContinuousSequence(9));

最長(zhǎng)不含重復(fù)字符的子字符串

請(qǐng)從字符串中找出一個(gè)最長(zhǎng)的不包含重復(fù)字符的子字符串,計(jì)算該最長(zhǎng)子字符串的長(zhǎng)度。

示例 1:

輸入: "abcabcbb" 輸出: 3 解釋: 因?yàn)闊o(wú)重復(fù)字符的最長(zhǎng)子串是 "abc",所以其長(zhǎng)度為 3。

/**
 * 最長(zhǎng)不含重復(fù)字符的子字符串
 */
// 可以通過滑動(dòng)窗口解決
function lengthOfLongestSubstring(s) {
    // 滑動(dòng)窗口
    const window = {};

    // 左右指針
    let left = 0;
    let right = 0;

    let result = 0;

    for (let i = 0; i < s.length; i++) {
        const c = s.charAt(i);

        // 擴(kuò)充窗口
        window[c] = window[c] ? window[c] + 1 : 1;
        right++;

        // 判斷是否收縮窗口
        while (window[c] > 1) {
            // 進(jìn)行窗口收縮
            const leftC = s.charAt(left);
            window[leftC]--;
            left++;
        }

        result = Math.max(result, right - left);
    }

    return result;
}

const s = 'abcabcbb';
console.log(lengthOfLongestSubstring(s));

長(zhǎng)度最小的子數(shù)組

給定一個(gè)含有 n 個(gè)正整數(shù)的數(shù)組和一個(gè)正整數(shù) target 。

找出該數(shù)組中滿足其和 ≥ target 的長(zhǎng)度最小的 連續(xù)子數(shù)組 [numsl, numsl+1, ..., numsr-1, numsr] ,并返回其長(zhǎng)度。如果不存在符合條件的子數(shù)組,返回 0 。

示例 1:

輸入:target = 7, nums = [2,3,1,2,4,3]
輸出:2
解釋:子數(shù)組 [4,3] 是該條件下的長(zhǎng)度最小的子數(shù)組。
// 滑動(dòng)窗口
function minSubArrayLen(target, nums) {
    let left = 0;
    let right = 0;
    let sum = 0;
    let result = Infinity;

    while (right < nums.length) {
        // 更新狀態(tài)
        sum += nums[right];
        right++;

        // 收縮窗口
        while (sum >= target) {
            result = Math.min(result, right - left);
            const presentVal = nums[left];
            // 更新狀態(tài)
            sum -= presentVal;
            left++;
        }
    }

    return result === Infinity ? 0 : result;
}

無(wú)重復(fù)字符的最長(zhǎng)子串

一、題目

給定一個(gè)字符串 s ,請(qǐng)你找出其中不含有重復(fù)字符的 最長(zhǎng)子串 的長(zhǎng)度。

示例 1:

輸入: s = "abcabcbb" 輸出: 3 解釋: 因?yàn)闊o(wú)重復(fù)字符的最長(zhǎng)子串是 "abc",所以其長(zhǎng)度為 3。

二、題解

function lengthOfLongestSubstring(s) {
    // 滑動(dòng)窗口
    const window = {};

    // 滑動(dòng)窗口的兩個(gè)指針
    let left = 0;
    let right = 0;

    // 結(jié)果
    let result = 0;

    // 循環(huán)終止條件
    while (right < s.length) {
        const c = s[right];

        // 進(jìn)行窗口內(nèi)數(shù)據(jù)的一系列更新
        window[c] = window[c] ? window[c] + 1 : 1;

        // 移動(dòng)窗口右側(cè)
        right++;

        // 判斷左側(cè)窗口是否要收縮
        while (window[c] > 1) {
            const d = s[left];

            // 左側(cè)窗口收縮
            left++;

            // 進(jìn)行窗口內(nèi)的一系列更新
            window[d]--;
        }

        // 更新答案
        result = Math.max(result, right - left);
    }

    return result;
}

const s = 'abcabcbb';

console.log(lengthOfLongestSubstring(s));

字符串排列

一、題目

給你兩個(gè)字符串 s1 和 s2 ,寫一個(gè)函數(shù)來(lái)判斷 s2 是否包含 s1 的排列。如果是,返回 true ;否則,返回 false 。

換句話說(shuō),s1 的排列之一是 s2 的 子串 。

示例 1:

輸入:s1 = "ab" s2 = "eidbaooo" 輸出:true 解釋:s2 包含 s1 的排列之一 ("ba").

二、題解

/**
 * 算法思路:
 * 滑動(dòng)窗口
 * s2包含s1的最小子串,然后最小子串長(zhǎng)度跟s1長(zhǎng)度相等
 */

function checkInclusion(s1, s2) {
    // 需要湊齊的字符
    const need = {};
    for (let i = 0; i < s1.length; i++) {
        need[s1[i]] = need[s1[i]] ? need[s1[i]] + 1 : 1;
    }

    // 滑動(dòng)窗口
    const window = {};

    // 滑動(dòng)窗口的兩端
    let left = 0;
    let right = 0;

    // 表示窗口中滿足need部分的字符數(shù)
    let valid = 0;

    while (right < s2.length) {
        const c = s2[right];

        // 進(jìn)行窗口內(nèi)數(shù)據(jù)的一系列更新
        if (need[c]) {
            window[c] = window[c] ? window[c] + 1 : 1;
            if (window[c] === need[c]) {
                valid++;
            }
        }

        // 移動(dòng)窗口右側(cè)
        right++;

        // 判斷左側(cè)窗口是否要收縮(當(dāng)s1字符和滑動(dòng)窗口字符大小相等,此時(shí)就要收縮敞口)
        while (right - left >= s1.length) {
            // 在這里判斷是否找到了合法的子串
            if (valid === Object.keys(need).length) {
                return true;
            }

            const d = s2[left];
            left++;

            // 進(jìn)行窗口內(nèi)數(shù)據(jù)的一系列更新
            if (need[d] !== undefined) {
                if (window[d] === need[d]) {
                    valid--;
                }

                window[d]--;
            }
        }
    }

    return false;
}

const s1 = 'ab';
const s2 = 'eidbaooo';

console.log(checkInclusion(s1, s2));

滑動(dòng)窗口的最大值

給你一個(gè)整數(shù)數(shù)組 nums,有一個(gè)大小為 k 的滑動(dòng)窗口從數(shù)組的最左側(cè)移動(dòng)到數(shù)組的最右側(cè)。你只可以看到在滑動(dòng)窗口內(nèi)的 k 個(gè)數(shù)字?;瑒?dòng)窗口每次只向右移動(dòng)一位。

返回 滑動(dòng)窗口中的最大值 。

示例 1:

輸入:nums = [1,3,-1,-3,5,3,6,7], k = 3 輸出:[3,3,5,5,6,7] 解釋: 滑動(dòng)窗口的位置最大值

[1  3  -1] -3  5  3  6  7       3 1 [3  -1  -3] 5  3  6  7       3 1  3 [-1  -3  5] 3  6  7       5 1  3  -1 [-3  5  3] 6  7       5 1  3  -1  -3 [5  3  6] 7       6 1  3  -1  -3  5 [3  6  7]      7

該問題用單調(diào)隊(duì)列解決(單調(diào)隊(duì)列可以解決滑動(dòng)窗口問題)。

// 首先建立一個(gè)單調(diào)隊(duì)列的類
class MonotonicQueue {
    constructor() {
        this.queue = [];
    }

    // 在隊(duì)尾添加元素n
    // 該函數(shù)在加入元素時(shí),會(huì)將其前面比自己小的元素全部刪除掉
    push(n) {
        // 將前面小于自己的元素全部刪除掉
        while (this.queue.length && n > this.queue[this.queue.length - 1]) {
            this.queue.pop();
        }

        this.queue.push(n);
    }

    // 對(duì)頭元素如果是n,則刪除它
    pop(n) {
        if (this.queue.length > 0 && n === this.queue[0]) {
            this.queue.shift();
        }
    }

    // 返回當(dāng)前隊(duì)列中的最大值
    // 因?yàn)閜ush元素時(shí)都會(huì)將比自己小的刪除掉,最終結(jié)果就是一個(gè)遞減的順序,則最大值就是隊(duì)列首部?jī)?nèi)容
    max() {
        return this.queue[0];
    }
}
function maxSlidingWindow(nums, k) {
    // 實(shí)例化一個(gè)單調(diào)隊(duì)列
    const monotonicQueue = new MonotonicQueue();
    const result = [];

    for (let i = 0; i < nums.length; i++) {
        // 先填滿整個(gè)滑動(dòng)窗口的k-1個(gè)元素
        if (i < k - 1) {
            monotonicQueue.push(nums[i]);
        } else {
            // 窗口向前滑動(dòng),添加新元素
            monotonicQueue.push(nums[i]);
            // 記錄當(dāng)前窗口的最大值
            result.push(monotonicQueue.max());
            // 移除隊(duì)列首部元素
            monotonicQueue.pop(nums[i - k + 1]);
        }
    }

    return result;
}
責(zé)任編輯:姜華 來(lái)源: 前端點(diǎn)線面
相關(guān)推薦

2023-06-05 07:30:51

2023-07-10 08:01:13

島嶼問題算法

2023-04-03 07:33:05

數(shù)組排序快速排序法

2023-07-03 08:01:54

2023-04-17 07:33:11

反轉(zhuǎn)鏈表移除鏈表

2023-05-22 07:31:32

Nums快慢指針

2023-05-29 07:31:35

單調(diào)棧數(shù)組循環(huán)

2023-06-26 07:31:44

屬性物品背包

2023-06-13 06:51:15

斐波那契數(shù)算法

2023-06-19 07:31:34

普通動(dòng)態(tài)規(guī)劃字符串

2021-09-23 10:53:43

數(shù)據(jù)中心

2016-08-05 20:21:51

CTO導(dǎo)師技術(shù)

2016-08-05 18:53:25

CTO導(dǎo)師技術(shù)

2021-07-08 20:22:05

AI

2013-04-22 12:58:14

TechExcel敏捷研發(fā)

2016-10-17 13:50:31

2009-04-29 18:12:41

GAUPS培訓(xùn)

2013-07-13 22:38:14

微軟社區(qū)微軟MVPMWW

2015-01-04 14:54:28

IT訓(xùn)練營(yíng)

2016-08-04 13:41:27

CTO訓(xùn)練營(yíng),技術(shù)管理
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)