You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C#滑动窗口实现中max变量无法正确更新的问题求助

C#滑动窗口实现中max变量无法正确更新的问题求助

我本来要用C#实现这个功能,采用滑动窗口技术来降低复杂度,但滑动窗口的时候max变量没法正确更新。我反复检查了逻辑,没发现哪里错了,实在搞不定来求助!

我的算法思路

Initialize currentMax = 0
Initialize max = 0
Initialize subArray as an empty HashSet

For each number in numbers (from index 0 to end):
    If number is NOT in subArray:
        Add number to subArray
        Add number to max (sum of the current subarray)
        
        If size of subArray equals subArrayMaxSize:
            Log currentMax, max, and subArray (before removal)
            currentMax = max if max > currentMax else currentMax
            Remove the oldest element from subArray (i - subArray.Count + 1)
            Subtract the removed element from max
            Log currentMax, max, and subArray (after removal)

Return currentMax

我写的C#代码

int[] numbers = { 1, 5, 4, 2, 9, 9, 9 };
int subArrayMaxSize = 3;

int currentMax = 0, max = 0;
HashSet<int> subArray = new HashSet<int>();

for (int i = 0; i < numbers.Length; i++)
{
    if (!subArray.Contains(numbers[i]))
    {
        subArray.Add(numbers[i]);
        max += numbers[i];

        if (subArray.Count == subArrayMaxSize)
        {
            LogValues(currentMax, max, subArray, true);

            currentMax = Math.Max(currentMax, max);
            subArray.Remove(numbers[i - subArray.Count + 1]);
            max -= numbers[i - subArray.Count + 1];

            LogValues(currentMax, max, subArray, false);
        }
    }
}
void LogValues(int currentMax, int max, HashSet<int> subArray, bool isStart)
{
    if (isStart) Console.WriteLine("======================================================");
    Console.WriteLine($"CurrentMax: {currentMax}, Max: {max}, SubArray: {string.Join(",", subArray)}");
    if (!isStart) Console.WriteLine("\n\n");
}

运行得到的输出

运行后输出如下:

======================================================
CurrentMax: 0, Max: 10, SubArray: 1,5,4
CurrentMax: 10, Max: 9, SubArray: 5,4


======================================================
CurrentMax: 10, Max: 11, SubArray: 5,4,2
CurrentMax: 11, Max: 6, SubArray: 4,2


======================================================
CurrentMax: 11, Max: 15, SubArray: 4,2,9
CurrentMax: 15, Max: 11, SubArray: 2,9

我逐行进行了调试,但还是没找到问题出在哪里,希望能得到大家的帮助!


问题分析与修正方案

你的代码和算法逻辑存在几个关键问题,导致max变量更新不符合预期,同时也无法覆盖所有场景:

1. HashSet无法维护元素插入顺序(潜在风险)

虽然你通过numbers[i - subArray.Count + 1]计算最早加入的元素索引在当前示例中暂时有效,但HashSet本身不保证元素的存储顺序。如果后续业务场景更复杂(比如元素重复出现在非窗口位置),这种方式可能会失效。正确的做法是用**队列(Queue)**来维护窗口内元素的插入顺序,结合HashSet快速判断元素是否存在。

2. 未处理窗口长度小于maxSize的最大和场景

你的算法只在窗口长度恰好等于subArrayMaxSize时才更新currentMax,但如果存在长度小于subArrayMaxSize的无重复子数组和更大(比如数组{10, 1, 1},maxSize=3),你的代码会返回0,显然不符合预期。

3. 遇到重复元素时窗口未正确滑动

当遇到重复元素时,你的代码直接跳过添加,但没有调整窗口(移除重复元素之前的所有元素),导致窗口内的元素和max无法正确反映当前有效无重复子数组的和。

修正后的代码

下面是修复后的代码,解决了上述问题,实现了长度不超过subArrayMaxSize的无重复子数组的最大和:

int[] numbers = { 1, 5, 4, 2, 9, 9, 9 };
int subArrayMaxSize = 3;

int currentMax = 0, currentSum = 0;
HashSet<int> elementSet = new HashSet<int>();
Queue<int> windowQueue = new Queue<int>();

for (int i = 0; i < numbers.Length; i++)
{
    int num = numbers[i];

    // 若当前元素已在窗口中,移除窗口中该元素及之前的所有元素,保证窗口内无重复
    while (elementSet.Contains(num))
    {
        int removed = windowQueue.Dequeue();
        elementSet.Remove(removed);
        currentSum -= removed;
    }

    // 将当前元素加入窗口
    windowQueue.Enqueue(num);
    elementSet.Add(num);
    currentSum += num;

    // 若窗口长度超过maxSize,滑动窗口移除最左侧元素
    while (windowQueue.Count > subArrayMaxSize)
    {
        int leftElement = windowQueue.Dequeue();
        elementSet.Remove(leftElement);
        currentSum -= leftElement;
    }

    // 更新最大和(覆盖所有长度<=maxSize的无重复子数组)
    currentMax = Math.Max(currentMax, currentSum);
}

Console.WriteLine($"最终最大和: {currentMax}"); // 输出:15

代码说明

  • Queue维护窗口顺序:确保我们能正确获取窗口最左侧的元素,滑动窗口时准确更新和。
  • 处理重复元素:遇到重复元素时,清空窗口中该元素之前的所有内容,保证窗口内始终是无重复的子数组。
  • 动态调整窗口大小:当窗口长度超过maxSize时自动滑动,同时每次迭代都更新最大和,覆盖所有有效子数组场景。

运行这段代码后,currentMax会正确更新为15,符合预期,同时也能处理更多复杂场景。

备注:内容来源于stack exchange,提问作者Zubair Jamil

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.15 11:00:29