String 문제 모음 (Level 1)

String 유형 Level 1 — Programmers

Programmers Level 1 String 문제들. 문자열 조작, 정렬, 변환 등의 기초 패턴을 다룬다.

Code Test
저자

Kwangmin Kim

공개

2026년 04월 04일

1 문제 1: 문자열 내림차순 정렬

항목 내용
출처 Programmers
난이도 Level 1
유형 String
풀이 시간 5분

1.1 문제 설명

문자열 s가 주어질 때, 모든 문자를 내림차순으로 정렬한 새 문자열을 반환한다.

입출력 예시

s return
"Zbcdefg" "gfedcbZ"

제한사항

  • 1 <= len(s) <= 10,000
  • 문자열은 한글자 이상의 모든 문자를 포함 가능

1.2 핵심 알고리즘/자료구조

핵심: sorted()와 reverse 옵션

sorted() 함수는 문자열을 정렬하여 리스트를 반환한다. - sorted(s) — 오름차순 정렬 (기본) - sorted(s, reverse=True) — 내림차순 정렬

정렬된 리스트를 문자열로 변환하려면 ''.join() 을 사용한다.

  • 시간 복잡도: O(n log n) — 정렬
  • 공간 복잡도: O(n) — 정렬 결과 저장

1.3 풀이 접근법

  1. 문자열을 문자 단위로 정렬sorted(s) 로 리스트 변환
  2. 내림차순으로 정렬reverse=True 옵션 추가
  3. 리스트를 문자열로 변환''.join() 사용

1.4 코드 풀이

def solution(s: str) -> str:
    """
    문자열을 내림차순으로 정렬하여 반환한다.
    Unicode 값 기준 내림차순: 대문자 > 소문자
    """
    return ''.join(sorted(s, reverse=True))

복잡도 분석

  • 시간 복잡도: O(n log n) — sorted() 정렬
  • 공간 복잡도: O(n) — 정렬된 리스트 저장

1.5 테스트 케이스 트레이싱

solution("Zbcdefg")
# sorted("Zbcdefg", reverse=True)
#   → ['g', 'f', 'e', 'd', 'c', 'b', 'Z']
#   (Unicode: 소문자 g~b > 대문자 Z)
# ''.join(...) → "gfedcbZ" ✓

solution("Za")
# sorted("Za", reverse=True) → ['a', 'Z']
# 결과 → "aZ" ✓

solution("abc")
# sorted("abc", reverse=True) → ['c', 'b', 'a']
# 결과 → "cba" ✓

1.6 다른 풀이

# 접근 1: list 변환 후 sort() 사용
def solution_v2(s: str) -> str:
    chars = list(s)
    chars.sort(reverse=True)
    return ''.join(chars)

# 접근 2: 슬라이싱을 이용한 문자 순회 (비효율)
def solution_v3(s: str) -> str:
    result = ""
    sorted_chars = sorted(s, reverse=True)
    for char in sorted_chars:
        result += char   # O(n²) — 문자열 concatenation
    return result
풀이 장점 단점
''.join(sorted(...)) 간결, Pythonic
list.sort() + join 명시적 한 줄 더 필요
문자열 concatenation 직관적 O(n²) 느림

1.7 핵심 패턴

이 문제에서 배운 것
  • sorted(s, reverse=True) — 내림차순 정렬
  • ''.join(list) — 리스트를 문자열로 합치기 (String 문제의 기본)
  • Unicode 정렬 순서 — ASCII: 대문자(65~90) < 소문자(97~122)
  • Pythonic 표현 — 여러 줄 루프보다 한 줄 함수 조합이 깔끔
면접 방어 포인트
  • sorted() 인가? — 단순성. 커스텀 정렬이 필요 없으면 내장 함수 활용
  • 시간복잡도? — O(n log n). 선형 정렬(Counting Sort)을 쓸 수도 있지만 필요 없음
  • sorted()vs list.sort()? — 새 리스트 반환 vs 제자리 정렬. 이 문제는 원본 유지 필요 없으므로 둘 다 가능
  • ''.join() 필수인 이유? — 반환 타입이 str이어야 하기 때문

2 문제 2: 가장 많이 나타나는 문자

항목 내용
출처 Programmers
난이도 Level 1
유형 String
풀이 시간 10분

2.1 문제 설명

문자열 s가 주어질 때, 가장 많이 나타나는 문자를 반환한다. 만약 여러 문자가 같은 빈도로 가장 많이 나타나면, 사전순으로 앞선 문자를 반환한다.

입출력 예시

s return
"abracadabra" "a"
"hello" "l"
"aabbcc" "a"

제한사항

  • 1 <= len(s) <= 10,000
  • 문자열은 소문자 영문자만 포함

2.2 핵심 알고리즘/자료구조

핵심: Counter와 동일 빈도 처리

Counter(s) 는 각 문자의 빈도를 dict로 반환한다.

주의: Counter.most_common(1) 은 최대 빈도인 첫 번째 항목만 반환하므로, 동일 빈도인 경우 어느 것을 반환할지 보장하지 않는다. 사전순 처리가 필요하다.

  • 시간 복잡도: O(n) — Counter 생성 + 최대값 계산
  • 공간 복잡도: O(k) — k는 고유 문자 수 (≤ 26)

2.3 풀이 접근법

  1. 문자 빈도 계산Counter(s) 로 각 문자의 등장 횟수 파악
  2. 최대 빈도 찾기max(count.values())
  3. 최대 빈도인 모든 문자 필터링 — 조건부 리스트컴프리헨션
  4. 사전순 최소 선택min() 함수

2.4 코드 풀이

from collections import Counter

def solution(s: str) -> str:
    """
    가장 많이 나타나는 문자를 반환.
    동일 빈도면 사전순 첫 번째.
    """
    count = Counter(s)
    max_freq = max(count.values())

    # 최대 빈도인 모든 문자 중 사전순 최소
    return min(c for c, f in count.items() if f == max_freq)

복잡도 분석

  • 시간 복잡도: O(n) — Counter 생성, 최대값 찾기, 최소값 찾기 모두 O(n) 또는 O(k)
  • 공간 복잡도: O(k) — Counter 저장 (k = 고유 문자 수)

2.5 테스트 케이스 트레이싱

solution("abracadabra")
# count = Counter({'a': 5, 'b': 2, 'r': 2, 'c': 1, 'd': 1})
# max_freq = 5
# 최대 빈도인 문자: ['a']
# min(['a']) = "a" ✓

solution("aabbcc")
# count = Counter({'a': 2, 'b': 2, 'c': 2})
# max_freq = 2
# 최대 빈도인 문자: ['a', 'b', 'c']
# min(['a', 'b', 'c']) = "a" ✓

solution("hello")
# count = Counter({'l': 2, 'h': 1, 'e': 1, 'o': 1})
# max_freq = 2
# 최대 빈도인 문자: ['l']
# min(['l']) = "l" ✓

2.6 다른 풀이

# 접근 1: most_common() 직접 사용 (동일 빈도 미처리 — 위험)
def solution_wrong(s: str) -> str:
    count = Counter(s)
    return count.most_common(1)[0][0]  # 어느 것을 반환할지 보장 안 함

# 접근 2: sorted 조합 (명시적)
def solution_v2(s: str) -> str:
    count = Counter(s)
    # (빈도, 문자)로 정렬: 빈도 내림차순, 문자 오름차순
    sorted_items = sorted(count.items(), key=lambda x: (-x[1], x[0]))
    return sorted_items[0][0]
풀이 장점 단점
min(c for ... if f == max_freq) 직관적, 안전 코드 3줄
sorted(..., key=...) 조합 한 줄 가능 정렬 비용 O(k log k)
most_common(1) 간단 동일 빈도 미처리

2.7 핵심 패턴

이 문제에서 배운 것
  • Counter(s) — 빈도 카운팅 자동화
  • max(dict.values()) — dict의 값 최댓값 찾기
  • min() with 조건 — 조건을 만족하는 최솟값 찾기 (사전순)
  • 동일 값 처리most_common(1) 은 보장 안 함 → 필터 + min/max 조합 필수
면접 방어 포인트
  • Counter 인가? — 빈도 카운팅이 명확하고 간단
  • most_common(1) 왜 안 쓰나? — 동일 빈도일 때 순서 미보장 → 직접 필터링이 안전
  • 시간복잡도? — O(n). 소문자 26개로 제한되면 O(1)로도 봐줄 수 있음
  • 공간복잡도? — O(k). 소문자만이면 O(26) = O(1)

3 관련 문제

Subscribe

Enjoy this blog? Get notified of new posts by email: