프라이D
프라이Develog(❁´◡`❁)
프라이D
전체 방문자
오늘
어제
  • ALL (378)
    • TDD, Cleancode with JavaScr.. (5)
    • 프로젝트 (32)
      • work (3)
      • 직접 만드는 기술 블로그 (2)
      • 데일리 옥션 (19)
      • 모락모락 (8)
    • Computer Science (1)
    • Algorithm & 자료구조 (94)
      • 알고리즘 w.JavaScript (53)
      • 자료구조 (5)
      • (인프런) 자바스크립트 알고리즘 문제풀이 (34)
    • JavaScript (45)
      • JavaScript (41)
      • 모던 자바스크립트 Deep Dive (4)
    • WEB (13)
    • 회고 (12)
    • TIL (109)
    • WIL (7)
    • Stacks (20)
      • React.js (6)
      • Next.js (1)
      • Redux (3)
      • Node.js (2)
      • GIT (2)
      • SAP (1)
    • 15일 메이킹 프로젝트 (15)
    • 이전 기록 (14)
    • ETC. (5)
    • ---------------2021 (6)
      • 내일배움단-웹개발 5주 (2)
      • 정보처리기사 (4)

블로그 메뉴

  • 홈
  • 태그
  • 미디어로그
  • 위치로그
  • 방명록

공지사항

인기 글

태그

  • MySQL
  • vanilaJS
  • Til
  • 투포인터알고리즘
  • 자바스크립트
  • 자바스크립트비트마스크
  • 내일배움단
  • nomadcoders
  • 국비지원
  • 스파르타코딩클럽
  • JavaScript
  • 코드스테이츠
  • 내일배움카드
  • 코딩프로젝트
  • 알고리즘
  • nomadcoder
  • 비트마스크
  • 2023 인프콘 후기
  • 모던자바스크립트딥다이브
  • 자바스크립트알고리즘

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
프라이D

프라이Develog(❁´◡`❁)

Algorithm & 자료구조/알고리즘 w.JavaScript

[알고리즘 JS] Sliding window - 중복이 없는 가장 긴 문자열의 길이 찾기

2023. 3. 24. 15:15

주어진 문자열에서 중복이 없는 가장 긴 길이를 구하는 문제이다. 

처음에는 부분 문자열을 매번 구하고 해당 부분 문자열에 현재 문자열이 존재하는지를 찾는 방법이 떠올랐다.

이 경우 시간 복잡도가 O(n^2) 이므로 상당히 비효율적이다.

이 때 슬라이딩 윈도우 기법을 사용하면 문자열 길이만큼 반복하여 O(n) 의 선형 시간 복잡도로 문제를 해결할 수 있다. 

[findLongestSubstring]

Write a function called findLongestSubstring, which accepts a string and returns the length of the longest substring with all distinct characters.

ex)
  findLongestSubstring(''), // 0 
findLongestSubstring('rithmschool'), // 7 
findLongestSubstring('thisisawesome'), // 6 
findLongestSubstring('thecatinthehat'), // 7 
findLongestSubstring('bbbbbb'), // 1 
findLongestSubstring('longestsubstring'), // 8 
findLongestSubstring('thisishowwedoit'), // 6

출처 : Udemy JavaScript 알고리즘 & 자료구조 마스터클래스

솔루션을 보지 않은 나의 첫 풀이는 아래와 같다. 

0부터 시작해서 각 문자열을 key 값으로 갯수를 계속 카운트했다.

카운트하는 도중 갯수가 2 이상이 되면 중복 문자열이기 때문에, 현재까지의 길이를 Max 값으로 저장하고,

윈도우 범위를 좁혀가며 길이를 구했다.

function findLongestSubstring(str) {
  let map = {};

  let start = 0;
  let end = 0;
  let maxLen = 0;

  while (start < str.length && end < str.length) {
    const key = str[end];

    // key 값이 없는 경우 추가하고 end 증가
    if (!map[key]) {
      map[key] = 1;
      end++;
      maxLen = Math.max(maxLen, end - start);
    }
    // key 값이 있는 경우 start 빼고 map 에서도 제거
    else if (map[key]) {
      map[str[start]]--;
      start++;
    } else {
      break;
    }
  }

  return maxLen;
}

솔루션의 풀이는 아래와 같다. 내 풀이와 다른 점은 seen 이라는 객체에 해당 문자열이 등장한 인덱스 값을 저장한다는 것이다. seen 객체를 통해 이전에 등장했던 문자열인지 확인하고, 등장했던 문자열이라면 중복이기 때문에 중복이 없는 문자열의 최대 길이를 구하기 위해 start 값을 seen[char]의 값과 비교해서 옮긴다.

function findLongestSubstring(str) {
  let longest = 0;
  let seen = {};
  let start = 0;

  for (let i = 0; i < str.length; i++) {
    let char = str[i];
    // seen 객체에 현재 char 가 존재한다면 중복이 발생
    if (seen[char]) {
      start = Math.max(start, seen[char]);
    }
    // 현재 위치 - start가 문자열의 길이
    longest = Math.max(longest, i - start + 1);
    seen[char] = i + 1;
  }
  return longest;
}

이 풀이가 직관적으로 이해가 되지 않아서 간단한 예시를 준비했다.

만약 str이 abcdabd 라고 할 때 중복이 없는 가장 긴 부분 문자열의 길이는 abcd => 4가 된다.

seen 객체를 이용해 이 문자열의 각 인덱스를 저장하고, 길이를 구해보도록 하자.

seen 객체와 start 값의 변화는 아래와 같이 확인할 수 있다. 

seen: { a: 1 } start: 0 current: 1
seen: { a: 1, b: 2 } start: 0 current: 2
seen: { a: 1, b: 2, c: 3 } start: 0 current: 3
seen: { a: 1, b: 2, c: 3, d: 4 } start: 0 current: 4
seen: { a: 5, b: 2, c: 3, d: 4 } start: 1 current: 5
seen: { a: 5, b: 6, c: 3, d: 4 } start: 2 current: 6
seen: { a: 5, b: 6, c: 3, d: 7 } start: 4 current: 7
저작자표시 (새창열림)

'Algorithm & 자료구조 > 알고리즘 w.JavaScript' 카테고리의 다른 글

[Leetcode] 1071. Greatest Common Divisor of Strings  (0) 2023.12.28
[Leetcode] 1768.Merge Strings Alternately  (2) 2023.12.18
[알고리즘JS] 피로도 (프로그래머스 lv.2)  (0) 2023.02.04
[알고리즘JS] 연속 부분 수열 합의 개수 (프로그래머스 lv.2)  (0) 2023.02.04
[알고리즘 JS] 귤 고르기(프로그래머스 Lv.2)  (0) 2023.01.31
    'Algorithm & 자료구조/알고리즘 w.JavaScript' 카테고리의 다른 글
    • [Leetcode] 1071. Greatest Common Divisor of Strings
    • [Leetcode] 1768.Merge Strings Alternately
    • [알고리즘JS] 피로도 (프로그래머스 lv.2)
    • [알고리즘JS] 연속 부분 수열 합의 개수 (프로그래머스 lv.2)
    프라이D
    프라이D
    틀린내용 정정 및 개선사항은 언제든지 댓글 달아주세요 :D

    티스토리툴바