3. Longest Substring Without Repeating Characters

2025. 10. 19. 22:28·Coding Test/LeetCode

난이도: 중간 (Medium)

링크: LeetCode 3

풀이 날짜: 2025/10/19

 

1. 문제 이해

문자열 s에서 중복 문자가 없는 가장 긴 부분 문자열(substring)의 길이를 구하는 문제이다.

즉, 문자열을 순회하면서 반복되는 문자가 생기기 전까지의 최대 길이를 구해야 한다.

 

2. 접근 방식 — Sliding Window (슬라이딩 윈도우)

슬라이딩 윈도우(Sliding Window)를 사용하면, 중복 문자가 나올 때마다 윈도우를 한 칸씩 이동시키며 O(n) 시간 내에 해결할 수 있다. 현재 “중복이 없는 문자열 구간”을 윈도우로 유지하면서, 새로운 문자를 오른쪽에 추가할 때 중복이 생기면 왼쪽 첫번째를 중복이 없을 때까지 제거한다. 이 과정을 반복하며 매 순간 가장 긴 윈도우의 길이를 갱신하면 된다.

 

 

3. 풀이 코드

풀이 1 — 나의 풀이 (Array + includes + shift 방식)

/**
 * @param {string} s
 * @return {number}
 */
var lengthOfLongestSubstring = function(s) {  
  let maxLength = 0;  
  let words = [];
  
  for (let i = 0; i < s.length; i++) {
    const char = s[i];
    let hasChar = words.includes(char);
    
    while (hasChar) {      
      words.shift();
      hasChar = words.includes(char);
    }
    words.push(char);
    maxLength = Math.max(words.length, maxLength);
  }

  return maxLength;
};

 

단계 문자 현재 words 중복 발견 조치 maxLength
1 a [a] ❌ 추가 1
2 b [a, b] ❌ 추가 2
3 c [a, b, c] ❌ 추가 3
4 a [a, b, c] ✅ shift → [b, c] → 추가 → [b, c, a] 3
5 b [b, c, a] ✅ shift → [c, a] → 추가 → [c, a, b] 3

결국 "abc"의 길이 3이 최대값이 된다.

 

직관적인 이해

  • words는 현재 중복 없는 문자 리스트이다.
  • 중복이 생기면 shift()로 앞에서부터 제거하여 윈도우를 줄인다.
  • 매 순간 words.length가 “현재 유효한 substring의 길이”이다.

복잡도

  • 시간 복잡도: O(n²) (includes()와 shift()가 각각 O(n)). 문자열 전체를 이중 반복문으로 탐색하면 O(n²)이 되어 비효율적이다.
  • 공간 복잡도: O(k) (현재 substring 길이에 비례)

풀이 2 — Set + 포인터 방식 (최적화된 방법)

var lengthOfLongestSubstring = function(s) {
  let left = 0;
  let maxLength = 0;
  let substring = new Set();

  for (let right = 0; right < s.length; right++) {
    while (substring.has(s[right])) {
      substring.delete(s[left]);
      left++;
    }
    substring.add(s[right]);
    maxLength = Math.max(maxLength, substring.size);
  }

  return maxLength;
};

핵심 아이디어

  • right: 윈도우의 끝을 확장
  • left: 중복이 발생하면 왼쪽 포인터를 한 칸씩 이동
  • Set: 중복 체크를 O(1)에 처리

복잡도

  • 시간 복잡도: O(n)
  • 공간 복잡도: O(k)

두 풀이 비교

항목 나의 풀이(Array 방식) Set + 포인터 방식
접근 방식 배열 + includes + shift Set + Sliding Window
중복 탐색 O(n) (includes) O(1) (Set)
시간 복잡도 O(n²) O(n)
공간 복잡도 O(k) O(k)
특징 직관적, 이해하기 쉬움 효율적, 최적해에 가까움

 

4. 핵심 정리

개념 설명
문제 유형 문자열, 슬라이딩 윈도우
핵심 변수 left, right, substring(Set)
핵심 아이디어 중복 발생 시 윈도우 시작(left)을 이동시키며 유효 구간 유지
복잡도 시간 O(n), 공간 O(k)
포인트 “중복을 만나면 왼쪽을 줄이고, 아닐 때 오른쪽을 확장한다.”

 

이 문제는 나의 풀이처럼 배열로 접근해도 되지만, 성능 최적화를 위해서는 Set 기반의 투 포인터 방식으로 전환하는 것이 좋다.

'Coding Test > LeetCode' 카테고리의 다른 글

57. Insert Interval  (0) 2025.10.20
56. Merge Intervals  (0) 2025.10.20
209. Minimum Size Subarray Sum  (0) 2025.10.19
45. Jump Game II  (0) 2025.10.15
55. Jump Game  (0) 2025.10.15
'Coding Test/LeetCode' 카테고리의 다른 글
  • 57. Insert Interval
  • 56. Merge Intervals
  • 209. Minimum Size Subarray Sum
  • 45. Jump Game II
JTB
JTB
웹/앱 개발 정보를 공유하고 있습니다.
  • JTB
    JTechBlog
    JTB
  • 전체
    오늘
    어제
    • All About Programming;)
      • Computer Science
        • Terminology and Concepts
        • Network
        • Operating System
        • Database
        • Data Structure
        • Web Development
      • Frontend
        • Javascript Essentials
        • Perfomance Optimization
        • JS Patterns
        • React
        • Next.js
        • Flutter
        • Testing
      • Backend
        • Node.js
      • DevOps
        • Docker & Kubernetes
      • Coding Test
        • LeetCode
        • Programmers
      • Tech Books & Lectures
        • Javascript_Modern JS Deep d..
        • Network_IT 엔지니어를 위한 네트워크 입문
      • Projects
        • PolyLingo_2025
        • Build Your Body_2024
        • JStargram_2021
        • Covid19 Tracker_2021
        • JPortfolio_2021
      • BootCamp_Codestates
        • TIL
        • TILookCloser
        • Pre Tech Blog
        • IM Tech Blog
        • Daily Issues and DeBugging
        • First Project
        • Final Project
        • Sprint Review
        • Good to Know
        • Socrative Review
        • HTML &amp; CSS
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

    • 글쓰기
    • 관리
  • 공지사항

  • 인기 글

  • 태그

    Threads and Multithreading
    Network
    polylingo
    Data Structure
    How memory manage data
    Javascript Essentials
    database
    leetcode
    딥다이브
    Binary Tree BFS
    js pattern
    testing
    프론트엔드 성능 최적화 가이드
    Time complexity and Space complexity
    커리어
    모던 자바스크립트 Deep Dive
    스코프
    이벤트
    VoiceJournal
    CPU scheduling algorithm
    structure of os
    DOM
    자바스크립트 딥다이브
    Operating System
    자바스크립트
    Shared resources
    TCP/IP
    mobile app
    indie hacker
    need a database
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.5
JTB
3. Longest Substring Without Repeating Characters
상단으로

티스토리툴바