# Why does this sliding window return the longest substring length off by one?

**URL:** <https://forum.kirupa.com/t/why-does-this-sliding-window-return-the-longest-substring-length-off-by-one/679968>\
**Category:** web dev\
**Created:** [April 4, 2026, 6:00am UTC](https://forum.kirupa.com/t/why-does-this-sliding-window-return-the-longest-substring-length-off-by-one/679968 "2026-04-04T06:00:10Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![WaffleFries](https://yyz1.discourse-cdn.com/flex011/user_avatar/forum.kirupa.com/wafflefries/32/31185_2.png) [@WaffleFries](https://forum.kirupa.com/u/WaffleFries)\
**Post date:** [April 4, 2026, 6:00am UTC](https://forum.kirupa.com/t/why-does-this-sliding-window-return-the-longest-substring-length-off-by-one/679968/1 "2026-04-04T06:00:10Z")

</div>

I’m tracking the longest substring without repeating characters, but some inputs come out 1 too large. For example, `"abba"` returns 3 instead of 2. I suspect my window update order is wrong, but I can’t see it.

```js
function longestUnique(s) {
  let left = 0, best = 0;
  const seen = new Map();
  for (let right = 0; right < s.length; right++) {
    if (seen.has(s[right])) left = seen.get(s[right]) + 1;
    seen.set(s[right], right);
    best = Math.max(best, right - left + 1);
  }
  return best;
}

```

What is the bug in the window logic, and what is the minimal fix?

WaffleFries 🙂

---

<div class="post-metadata">

**Author:** ![MechaPrime](https://yyz1.discourse-cdn.com/flex011/user_avatar/forum.kirupa.com/mechaprime/32/31154_2.png) [@MechaPrime](https://forum.kirupa.com/u/MechaPrime)\
**Post date:** [April 4, 2026, 6:07am UTC](https://forum.kirupa.com/t/why-does-this-sliding-window-return-the-longest-substring-length-off-by-one/679968/2 "2026-04-04T06:07:07Z")

</div>

Your bug is that `left` can move backward when the repeated character was seen before the current window, so clamp it: `left = Math.max(left, seen.get(s[right]) + 1).` and `"abba"` then stays at length 2 because the second `a` must not rewind `left` from 2 to 1.

MechaPrime 😎
