以下是 LeetCode 2488 的 TypeScript 实现,使用哈希表统计左右两侧的平衡值:

function countSubarrays(nums: number[], k: number): number {
    const n = nums.length;
    let pos = -1;
    
    // 找到 k 的位置
    for (let i = 0; i < n; i++) {
        if (nums[i] === k) {
            pos = i;
            break;
        }
    }
    
    // 哈希表存储左边出现的平衡值及次数
    const leftMap = new Map<number, number>();
    leftMap.set(0, 1); // 空子数组(只包含 k 自身)
    
    let balance = 0;
    // 向左遍历,统计平衡值
    for (let i = pos - 1; i >= 0; i--) {
        if (nums[i] > k) {
            balance++;
        } else if (nums[i] < k) {
            balance--;
        }
        leftMap.set(balance, (leftMap.get(balance) || 0) + 1);
    }
    
    let result = 0;
    balance = 0;
    // 向右遍历并统计
    for (let i = pos; i < n; i++) {
        if (i > pos) { // 避免重复处理 pos 位置
            if (nums[i] > k) {
                balance++;
            } else if (nums[i] < k) {
                balance--;
            }
        }
        
        // 奇数长度子数组:leftBalance + rightBalance = 0
        // 偶数长度子数组(k在左中位):leftBalance + rightBalance = 1
        result += (leftMap.get(-balance) || 0);
        result += (leftMap.get(1 - balance) || 0);
    }
    
    return result;
}

优化版本(使用数组代替 Map,适合数值范围较小的情况)

function countSubarrays(nums: number[], k: number): number {
    const n = nums.length;
    let pos = -1;
    
    for (let i = 0; i < n; i++) {
        if (nums[i] === k) {
            pos = i;
            break;
        }
    }
    
    // 使用对象存储(更简洁)
    const leftCount: Record<number, number> = { 0: 1 };
    let balance = 0;
    
    for (let i = pos - 1; i >= 0; i--) {
        balance += nums[i] > k ? 1 : (nums[i] < k ? -1 : 0);
        leftCount[balance] = (leftCount[balance] || 0) + 1;
    }
    
    let result = 0;
    balance = 0;
    
    for (let i = pos; i < n; i++) {
        if (i > pos) {
            balance += nums[i] > k ? 1 : (nums[i] < k ? -1 : 0);
        }
        
        // 两种情况
        result += (leftCount[-balance] || 0);
        result += (leftCount[1 - balance] || 0);
    }
    
    return result;
}

测试用例

// 示例 1
console.log(countSubarrays([3,2,1,4,5], 4)); // 输出: 3

// 示例 2
console.log(countSubarrays([2,3,1], 3)); // 输出: 1

// 示例 3
console.log(countSubarrays([1,2,3,4,5], 3)); // 输出: 2

关键点说明

  1. 平衡值的定义balance = (大于k的数量) - (小于k的数量)
  2. 中位数条件
    • 奇数长度子数组:左边平衡 + 右边平衡 = 0
    • 偶数长度子数组:左边平衡 + 右边平衡 = 1(k 在左中位)
  3. 哈希表存储:记录从 k 向左的所有平衡值的出现次数
  4. 向右遍历:对每个右边界,查找满足条件的左边界数量

时间复杂度:O(n),空间复杂度:O(n)

Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐