leetcode 无重复字符的最长子串 && 最大连续1的个数 III && 最少交换次数来组合所有的 1

355 阅读1分钟

3. 无重复字符的最长子串

leetcode-cn.com/problems/lo…

  • 滑动窗口 + 哈希表
    • 维护不含有重复字符的子串
    • 每次循环更新最大值
var lengthOfLongestSubstring = function (s) {
    let left = 0
    let counter = 0
    const map = new Map()
    for (let right = 0; right < s.length; right++) {
        if (map.has(s[right]) ) {
            left = Math.max(left,map.get(s[right])+ 1  ) 
        }
        map.set(s[right],right) 
        counter = Math.max(right - left + 1, counter)
    }
    return counter
};

1004. 最大连续1的个数 III

leetcode-cn.com/problems/ma…

  • 滑动窗口 + 队列
    • 维护一个全是1的数组
    • 队列中存已经从0换成1的对应元素的index
/**
 * @param {number[]} A
 * @param {number} K
 * @return {number}
 */
var longestOnes = function (A, K) {
    const queueK = []
    let left = 0
    let counter = 0
    for (let right = 0; right < A.length; right++) {
        if (A[right] === 0) {
            if (K === 0) {
                if (queueK.length) {
                    left = queueK.shift() + 1
                    queueK.push(right)
                } else {
                    left = right + 1
                }
            }else{
                queueK.push(right)
                K--
            }
        }
        counter = Math.max(counter, right - left + 1)
    }
    return counter
};

1151. 最少交换次数来组合所有的 1

leetcode-cn.com/problems/mi…

  • 滑动窗口
    • 首先统计1的个数,假设为K,那么最终所有的1聚集在一起的时候一定是一个长度为K的连续区间或者说窗口
    • 我们用一个大小为K的窗口从左到右扫面一遍数组,找到窗口内1的个数最多的窗口即是答案。
/**
 * @param {number[]} data
 * @return {number}
 */
var minSwaps = function (data) {
    let sum = 0 //代表有多少个1
    for (let i = 0; i < data.length; i++) {
        sum = sum + data[i]
        data[i] = sum
    }
    if (sum === 0 || sum === 1) {
        return 0
    }
    
    let oneCounter = data[sum - 1]
    for (let i = 1, j = sum; j < data.length; i++ , j++) {
        oneCounter = Math.max(oneCounter, data[j] - data[i - 1])
    }
    return sum - oneCounter
};