← 알고리즘 강의 목록으로
🧱
기본 자료구조
슬라이싱·문자열 메서드·아스키 활용

04. 배열과 문자열 (Arrays & Strings)

투 포인터·회문 판별·애너그램 등 배열·문자열 응용 패턴의 토대를 만듭니다.

배열문자열투 포인터
소요 시간
약 1시간
난이도
📊 초급
선수 조건
🎯 기초 트랙
결과물
투 포인터·회문 판별·애너그램 등 배열·문자열 응용 패턴의 토대를 만듭니다.

이 강의에서 배우는 것

  • 1Python `list`(동적 배열)의 슬라이싱 문법과 복잡도를 정확히 이해한다.
  • 2문자열 주요 메서드를 활용하고, 불변성으로 인한 성능 이슈를 회피할 수 있다.
  • 3투 포인터 기법을 이용해 팰린드롬 검사 등의 배열/문자열 문제를 O(n)에 풀 수 있다.

소개

배열(Array)은 모든 자료구조의 근간이 되는 가장 기본적인 선형 자료구조입니다. Python에서는 `list`가 동적 배열(Dynamic Array) 역할을 하며, 인덱스를 이용해 O(1)에 임의 접근이 가능합니다.

문자열(String)은 Python에서 **불변(Immutable)** 객체입니다. 한 번 생성된 문자열은 변경할 수 없으며, `+=` 연산을 반복하면 매번 새로운 문자열 객체가 생성됩니다. 이 특성은 코딩 테스트에서 **성능 함정**이 되기 쉬우므로 반드시 이해해야 합니다.

text
인덱스:  0    1    2    3    4
        +----+----+----+----+----+
값:     | 10 | 20 | 30 | 40 | 50 |
        +----+----+----+----+----+
          ^                   ^
        arr[0]             arr[-1]

핵심 개념

1. 슬라이싱 (Slicing)

python
arr = [0, 1, 2, 3, 4, 5]

arr[1:4]    # [1, 2, 3]  -- 인덱스 1 이상 4 미만
arr[:3]     # [0, 1, 2]  -- 처음부터 3 미만
arr[3:]     # [3, 4, 5]  -- 3부터 끝까지
arr[::-1]   # [5, 4, 3, 2, 1, 0]  -- 역순
arr[::2]    # [0, 2, 4]  -- 2칸 간격
arr[1:5:2]  # [1, 3]  -- 1부터 5미만 2칸 간격
연산시간 복잡도설명
`arr[i]`O(1)인덱스 접근
`arr[i:j]`O(j-i)슬라이싱 (복사 발생)
`arr.append(x)`O(1) 균상끝에 추가
`arr.insert(i, x)`O(n)중간 삽입 (이동 필요)
`arr.pop()`O(1)끝 제거
`arr.pop(i)`O(n)중간 제거 (이동 필요)
`x in arr`O(n)선형 탐색
`len(arr)`O(1)길이 조회
💡

**주의**: `arr[i:j]` 슬라이싱은 O(j-i)의 **새로운 리스트를 복사**합니다.

2. 문자열 메서드 (String Methods)

메서드설명예시반환값
`split(sep)`구분자로 분리`"a,b".split(",")``["a","b"]`
`join(iter)`이터러블 연결`",".join(["a","b"])``"a,b"`
`strip()`양쪽 공백 제거`" ab ".strip()``"ab"`
`lstrip()`왼쪽 공백 제거`" ab ".lstrip()``"ab "`
`rstrip()`오른쪽 공백 제거`" ab ".rstrip()``" ab"`
`replace(old,new)`문자열 치환`"abab".replace("a","x")``"xbxb"`
`find(sub)`부분 문자열 위치`"hello".find("ll")``2`
`upper()`대문자 변환`"hello".upper()``"HELLO"`
`lower()`소문자 변환`"HELLO".lower()``"hello"`
`count(sub)`등장 횟수`"abab".count("ab")``2`
`startswith(s)`접두어 확인`"hello".startswith("he")``True`
`endswith(s)`접미어 확인`"hello".endswith("lo")``True`

3. ASCII 코드 -- ord / chr

python
ord('A')   # 65
ord('a')   # 97
ord('0')   # 48

chr(65)    # 'A'
chr(97)    # 'a'

# 알파벳 인덱스 (0-based)
idx = ord('c') - ord('a')   # 2
문자 범위ASCII 시작
'0' ~ '9'48 ~ 57
'A' ~ 'Z'65 ~ 90
'a' ~ 'z'97 ~ 122

4. 투 포인터 (Two Pointer) -- 팰린드롬 검사

text
문자열: r a c e c a r
인덱스: 0 1 2 3 4 5 6
        ^               ^
       left            right

비교 r==r -> 이동
       ^           ^
비교 a==a -> 이동
         ^       ^
비교 c==c -> 이동
           ^   ^
비교 e==e -> 이동
             left > right -> 팰린드롬!

투 포인터를 사용하면 O(n) 시간, O(1) 공간으로 팰린드롬을 검사할 수 있습니다.

예제로 보기

파일내용핵심 개념
`src/01_slicing.py`슬라이싱 기초 + 2D 예제인덱싱, 복사, 역순
`src/02_string_methods.py`문자열 메서드 실습split, join, replace
`src/03_palindrome.py`팰린드롬 검사 (나이브 + 투포인터)two-pointer, O(n)
`src/04_anagram.py`애너그램 검사Counter, sorted

자주 하는 실수

실수 1: 문자열 += 반복 사용 -- O(n^2) 함정

python
# 잘못된 방법 -- O(n^2): 매번 새로운 문자열 객체 생성
result = ""
for c in chars:
    result += c  # 매번 O(n) 복사!

# 올바른 방법 -- O(n): 리스트에 모아서 join
parts = []
for c in chars:
    parts.append(c)
result = "".join(parts)  # 한 번만 복사

실수 2: `in` 연산자의 복잡도 착각

python
arr = [1, 2, 3, ..., 1000000]
if x in arr:   # O(n) 선형 탐색!
    ...

# 자주 검색한다면 set 또는 dict 사용 -> O(1)
lookup = set(arr)
if x in lookup:   # O(1)
    ...

실수 3: 슬라이싱이 복사를 생성함을 잊음

python
arr = [1, 2, 3, 4, 5]
sub = arr[1:4]   # 새로운 리스트 복사, O(k) 시간 + O(k) 공간
sub[0] = 99
print(arr)   # [1, 2, 3, 4, 5] -- 원본 불변

실수 4: `split()` vs `split(' ')`

python
"a  b".split()    # ['a', 'b']  -- 연속 공백 무시
"a  b".split(' ') # ['a', '', 'b']  -- 빈 문자열 포함!

실수 5: 문자열과 정수 비교 시 ord() 혼동

python
# 잘못된 예
if 'a' > 'Z':   # True -- 아스키값 97 > 90
    ...

# 의도한 동작을 위해 lower()/upper() 사용
if 'a'.lower() == 'A'.lower():   # True
    ...

정리

개념핵심 포인트
동적 배열Python list, 임의 접근 O(1), 삽입/삭제 O(n)
슬라이싱O(k) 복사 발생, 원본 불변
문자열불변 객체, += 반복은 O(n^2)
join()문자열 조합은 항상 join()으로 O(n)
투 포인터양 끝에서 좁혀오는 기법, O(n) 시간 O(1) 공간
ord/chr문자<->아스키 변환, 알파벳 인덱스 계산

직접 해 보기

  1. `src/01_slicing.py` 를 실행하고 각 슬라이싱 결과를 예측해 보세요.
  2. `src/03_palindrome.py` 에서 투 포인터 과정을 손으로 그려 보세요.
  3. `src/04_anagram.py` 에서 Counter 없이 직접 딕셔너리로 구현해 보세요.
  4. `homework/README.md` 의 과제를 풀어 보세요.
예제 코드 / 강의 자료

전체 강의 자료와 예제 코드는 GitHub에서 자유롭게 받아볼 수 있습니다.

GitHub에서 보기 ↗