연속된 k개 원소의 합이 최대인 구간의 합을 구하는 함수.
def max_subarray_sum(nums, k):
if len(nums) < k:
return 0
window_sum = sum(nums[:k]) # (a) 첫 윈도우
max_sum = window_sum
for i in range(k, len(nums)): # (b) k부터 시작
window_sum += nums[i] - nums[i-k] # (c) 왼쪽 제거
if window_sum > max_sum:
max_sum = window_sum
return max_sum
sum(nums[:k])로 초기값 계산range(k, len(nums))nums[i]) - 왼쪽 제거(nums[i-k])14차에서는 range 시작값에서 힌트가 필요했는데, 이번엔 바로 정답!
연속된 k개 원소의 평균이 최대인 구간의 시작 인덱스를 반환하는 함수.
def solution(nums, k):
std_sum = sum(nums[:k])
std_idx = 0
max_sum = std_sum
for i in range(k, len(nums)):
std_sum += nums[i] - nums[i-k]
if std_sum > max_sum:
max_sum = std_sum
std_idx = i - k + 1
return std_idx
i - k + 1 (빠진 원소의 다음 인덱스)> vs >=: 같은 합일 때 앞쪽 인덱스를 유지해야 하므로 >(초과) 사용수업 중 질문: "첫번째 문제처럼 len(nums) < k인 경우는 없어?"
→ COS Pro 실제 시험에서는 보통 입력 조건이 보장되어 있어서 예외 처리 없이 바로 로직에 집중하면 된다.
문자열을 원형(순환)으로 간주하여 연속된 k글자 중 사전순으로 가장 앞서는 부분 문자열을 반환하는 함수.
def earliest_circular_substring(text, k):
extended = text * 2 # (a) 순환 처리
result = extended[:k]
for i in range(1, len(text)): # (b) 고유 시작점은 len(text)개
substring = extended[i:i+k]
if substring < result:
result = substring
return result
text * 2: 문자열을 두 번 이어붙여서 끝을 넘어가는 케이스 해결len(text): 원형 문자열에서 고유한 시작점은 원본 길이만큼만 존재처음에 len(extended) - k로 답했는데, 동작은 하지만 중복 순회가 발생한다. 시험 빈칸 채우기에서는 len(text)가 정답이므로 오답 처리될 수 있다는 피드백을 받았다.
| i | "dbca"(k=2) | 비고 |
|---|---|---|
| 0 | db | |
| 1 | bc | |
| 2 | ca | |
| 3 | ad | ← 순환으로만 나오는 조합 |
| 4 | db | i=0과 동일 (불필요) |
| 5 | bc | i=1과 동일 (불필요) |
문자열을 순환으로 간주하여 연속된 k글자로 만들 수 있는 서로 다른 부분 문자열의 개수를 반환하는 함수.
def solution(text, k):
extended = text * 2
str_set = set()
for i in range(0, len(text)):
sub_str = extended[i:i+k]
str_set.add(sub_str)
return len(str_set)
len(text) 범위로 정확히 설정str_set — str로 지었으면 내장함수를 덮어쓸 뻔했는데 잘 피함학생들의 점수에서 상위 k명과 하위 k명의 평균 차이를 반환하는 함수.
def solution(scores, k):
sorted_scores = sorted(scores)
high_avg = sum(sorted_scores[-k:]) / k
low_avg = sum(sorted_scores[:k]) / k
return high_avg - low_avg
sorted()로 원본 안 건드림 (좋은 습관)[-k:], [:k] 슬라이싱 정확sorted_scores — 내장함수명 안 겹침수업 중 질문: "abs() 감싼다는 건 마지막 return할 때
abs(high_avg - low_avg)하라는 거야?"
→ 맞다. 이 문제에서는 정렬 후 상위 >= 하위가 보장되지만, "절댓값으로 반환하라"는 조건이 명시된 문제라면abs()를 감싸는 게 안전하다.
풀이 중 출제자가 제시한 예시 답(35.0)이 틀렸다는 것을 직접 계산해서 발견했다 (정답: 40.0). 검증 습관이 좋다는 피드백을 받았다.
문자열 리스트에서 모음(a, e, i, o, u)이 가장 많은 단어를 반환하는 함수.
def solution(words):
lowered_words = [x.lower() for x in words] # 여기서 원본 소실!
chk_list = ['a', 'e', 'i', 'o', 'u']
max_count = 0
result_word = ""
for w in lowered_words: # 소문자 버전을 순회
...
result_word = w # 소문자 버전이 저장됨
return result_word
문제: lowered_words를 순회하면서 result_word에 소문자 변환된 값이 저장된다. ["APPLE"] 입력 시 "apple"이 반환됨.
def solution(words):
chk_list = ['a', 'e', 'i', 'o', 'u']
max_count = 0
result_word = ""
for w in words: # 원본을 순회
cnt = 0
for ch in w.lower(): # 비교할 때만 소문자로
if ch in chk_list:
cnt += 1
if cnt > max_count:
max_count = cnt
result_word = w # 원본이 저장됨
return result_word
| 방식 | 코드 | 원본 유지 |
|---|---|---|
| 변환 리스트 순회 | for w in lowered_words: | X |
| 원본 순회 + 비교만 변환 | for w in words: ... w.lower() | O |
핵심: 비교/검색에만 변환을 쓰고, 결과에는 원본을 저장할 것!
추가로 chk_list 대신 문자열로도 가능하다는 팁을 받았다: if ch in "aeiou"