[LeetCode] 3. Longest Substring Without Repeating Characters (Python)

2022. 10. 30. 19:05·Algorithm
LeetCode 3. Longest Substring Without Repeating Characters
String

https://leetcode.com/problems/longest-substring-without-repeating-characters/

 

Longest Substring Without Repeating Characters - LeetCode

Level up your coding skills and quickly land a job. This is the best place to expand your knowledge and get prepared for your next interview.

leetcode.com

1. 문제 설명

Longest Substring Without Repeating Characters은 이름 그대로 가장 긴 문자열을 의미한다.

이때, 같은 문자를 중복해서 사용하면 안된다.

 

LCS처럼 dp를 이용하여 풀 수도 있겠지만 (사실 고민해보지 않았다. 아마 가능하지 않을까..)

2차원 배열을 쓰지 않고, 그냥 문자열을 처음부터 끝까지 한 번만 돌면서 문자열이 중복되는지만 확인해주면 된다.

 

아래와 같은 문자열이 주어진다고 가정하자.

s = "abcabcbb"

이때 연속되는 문자열은 abc, bca, cab 등 최장 길이는 3이다.

따라서 3을 리턴해주면 된다.


2. 문제 접근

Naive approach

이 문제는 사실 Dynamic Programming, Greedy 등 여러 기법보다는 그냥 Naive하게 루프 한 번에 끝냈다.

중복된 문자가 나온다면 최장 문자열의 길이를 업데이트 하고, 새로운 substring을 만들면 된다.

 

다만, 이 루프를 돌면서 새로운 문자열을 제대로 만들어 주어야 한다.

예제처럼 string이 "abcabcbb"으로 주어졌다면 substring을 공백으로 초기화해도 큰 상관이 없을 것이다.

 

그러나 공백으로 초기화하면 반례가 존재한다.

예를 들어 아래와 같은 문자열이 주어진다고 가정하자.

s = "dvdf"

'dvdf'같은 문자열의 경우 세 번째 인덱스인 'd'가 들어와서 공백으로 초기화하면 substring을 'd'로 잡을 것이다.

하지만, 'd' 앞에 있는 'v'도 함께 포함하는 것이 제일 긴 substring이다.

따라서 substring에서 해당 문자의 다음 인덱스부터 마지막 문자열 + 중복되는 문자로 구성된 새로운 substring을 만들어 주어야 한다.


3. 참고 사항

① 리턴 값에 최대값이 정해진 경우는 루프의 탈출 조건을 걸어두는 것이 좋다.

해당 문제에서 문자열의 최장 길이는 5 * 104이므로 상당히 길다.

따라서 중간에 문자열의 길이가 알파벳의 최대 개수(= 26)인 경우 즉시 리턴하는 것이다.

 

② 루프가 끝나는 시점에도 최대값을 업데이트 해야 한다.

중복된 문자가 들어오는 경우만 최대값을 업데이트하면 루프 종료시점의 substring의 길이를 반영할 수 없다.

따라서 리턴하는 시점에 마지막으로 최대값을 업데이트 해야 한다. 

 

 


4. 구현 코드

class Solution:
    def lengthOfLongestSubstring(self, s: str) -> int:
        string = []
        res = 0
        for i in s:
            if i not in string:
                string.append(i)
            else:
                res = max(res, len(string))
                idx = string.index(i)
                string = string[idx + 1:]  # 중복되는 문자열의 다음 인덱스부터 잡는다!
                string.append(i)

            if res == 26:  # 알파벳 최대 개수인 경우 즉시 리턴
                break

        return max(res, len(string))

 

제출 결과 상위 8.27%의 런타임으로 코드가 통과했음을 알 수 있다.

리스트에 in을 사용하는 것이 O(n)이라 런타임이 조금 걱정되긴 했으나, 만족스러운 결과를 받았다.

 

'Algorithm' 카테고리의 다른 글
  • [LeetCode] 433. Minimum Genetic Mutation (Python)
  • [LeetCode] 1706. Where Will the Ball Fall (Python)
  • [BOJ] 1012번: 유기농 배추 (Python)
  • [BOJ] 9252번: LCS 2 (Python)
Bookish
Bookish
Waking Up Early :P / Ajou Univ
  • Bookish
    토끼의 발자취
    Bookish
  • 전체
    오늘
    어제
    • 분류 전체보기 (64)
      • GDSC Ajou (9)
      • Algorithm (15)
      • Lab (2)
      • Challenge (11)
      • Event (3)
      • Tips (4)
      • Daily (12)
      • 병원 (8)
  • 블로그 메뉴

    • Solved.ac
    • LeetCode
    • Kaggle
    • Manage
    • 홈
    • 태그
    • 미디어로그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    Python
    leetcode
    리트코드
    GDSC
    Google Solution Challenge 2023
    빅데이터분석기사
    백준
    라식
    삼성안과
    라섹후기
    Daily LeetCoding Challenge
    라섹
    아주대학교 프로그래밍 경시대회
    파이썬
    ㅅㅅ안과
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
Bookish
[LeetCode] 3. Longest Substring Without Repeating Characters (Python)
상단으로

티스토리툴바