[dahyeong-yun] WEEK 08 Solutions - #2811
Conversation
There was a problem hiding this comment.
🏷️ 알고리즘 패턴 분석
reverse-bits/dahyeong-yun.java
/**
* TC : O(1)
* - 32번의 루프를 2번 반복하므로 O(1)
* SC : O(1)
* - 32칸 고정 길이의 stack이 필요하므로 O(1)
*/
class Solution {
public int reverseBits(int n) {
int answer = 0;
Deque<Integer> stack = new ArrayDeque<>();
for(int i = 0; i<32; i++) {
stack.add(n % 2);
n /= 2;
}
int j = 0;
while(!stack.isEmpty()) {
int bit = stack.getLast();
stack.removeLast();
answer += bit * Math.pow(2, j);
j += 1;
}
return answer;
}
}- 패턴: Stack / Queue, Bit Manipulation
- 설명: 주어진 코드는 32비트 정수를 비트를 스택에 쌓고, 다시 꺼내며 자리수에 따라 반전된 비트를 구성한다. 비트 단위 조작과 스택 사용으로 비트 반전의 과정을 다룬다.
📊 시간/공간 복잡도 분석
| 복잡도 | |
|---|---|
| Time | O(1) |
| Space | O(1) |
피드백: 고정된 32비트 길이의 루프와 고정 크기 스택으로 구성되어 있어 시간과 공간이 상수로 보장된다.
개선 제안: 현재 구현이 적절해 보입니다.
💡 풀이에 시간/공간 복잡도를 주석으로 남겨보세요!
📊 dahyeong-yun 님의 학습 현황이번 주 제출 문제
누적 학습 요약
문제 풀이 현황
🤖 이 댓글은 GitHub App을 통해 자동으로 작성되었습니다. 🔢 API 사용량 (gpt-5-nano)
|
There was a problem hiding this comment.
한번 쉬프트 연산자를 활용해보시는건 어떨까요?
방금 저도 자바로 풀어봤는데 11줄까지 코드를 줄일수 있었어요!
if ((n & 1) == 1) answer |= 1;
이런 느낌으로 연산이 됩니다.
There was a problem hiding this comment.
또한 쉬프트연산자 쓰시면 별도의 스택같은 자료형이 필요 없기때문에 성능도 좋을거에요!
There was a problem hiding this comment.
🏷️ 알고리즘 패턴 분석
longest-repeating-character-replacement/dahyeong-yun.java
/**
* TC : O(n)
* - 문자열의 길이 n 만큼 반복하고 루프 안에서는 고정 길이를 반복하므로 O(n)
* SC : O(1)
* - 26개 알파벳의 카운트를 위한 배열을 생성하므로 O(1)
*/
class Solution {
public int characterReplacement(String s, int k) {
int max = 0;
int len = s.length();
int deleteTarget = 0;
int[] count = new int[26];
for(int i=0; i<len; i++) {
char c = s.charAt(i);
count[c - 'A']++;
int maxCountAlphabet = 0;
int total = count[0];
for(int j=1; j<26; j++) {
total += count[j];
if(count[j] > count[maxCountAlphabet]) maxCountAlphabet = j;
}
if(total - count[maxCountAlphabet] <= k) {
max = Math.max(max, total);
} else {
count[s.charAt(deleteTarget++) - 'A']--;
}
}
return max;
}
}- 패턴: Sliding Window, Greedy, Hash Map / Hash Set
- 설명: 문자열 슬라이딩 윈도우로 부분 문자열 길이를 확장하며, 최대 반복 문자 수를 유지해 k만큼의 대체로 길이를 늘리는 탐욕적 전략을 사용합니다. 문자 빈도 배열을 이용해 현재 윈도우에서 필요한 교체 수를 계산합니다.
📊 시간/공간 복잡도 분석
| 유저 분석 | 실제 분석 | 결과 | |
|---|---|---|---|
| Time | O(n) | O(n) | ✅ |
| Space | O(1) | O(1) | ✅ |
피드백: 26개 알파벳의 카운트를 유지하는 배열과 윈도우 좌/우 포인터를 사용해 부분 문자열의 문자 다수의 갯수를 트래킹한다.
개선 제안: 현재 구현은 최대 등장 문자 인덱스를 갱신하는 로직은 있지만 maxCountAlphabet의 값을 직접 인덱스로 비교하는 부분에서 혼란을 줄 수 있다. 더 명확하게 maxCountAlphabet 값을 문자 빈도 중 최댓값의 문자 인덱스로 관리하면 오류를 줄일 수 있다.
There was a problem hiding this comment.
🏷️ 알고리즘 패턴 분석
palindromic-substrings/dahyeong-yun.java
/**
* TC : O(n^2)
* - 문자열 길이 n 만큼 반복하고, 각 인덱스에서 n/2 만큼의 회문을 확인하므로 n * (n/2) => O(n^2)
* SC : O(1)
* - 별도 유의미한 공간을 사용하지 않음
*/
class Solution {
public int countSubstrings(String s) {
int len = s.length(), count = 0;
for(int i = 0; i<len; i++) {
int start = i, end = i;
// 홀수 길이 회문 카운트
while(
start >= 0 && end < len && s.charAt(start) == s.charAt(end)
) {
count++;
start--;
end++;
}
// 짝수 길이 회문 카운트
start = i;
end = i+1;
while(
start >= 0 && end < len && s.charAt(start) == s.charAt(end)
) {
count++;
start--;
end++;
}
}
return count;
}
}- 패턴: Two Pointers, Monotonic Stack, Hash Map / Hash Set
- 설명: 문자열의 각 인덱스에서 좌우로 확장하며 팰린드롬을 센다. 중앙 기준으로 홀수/짝수 길이의 회문을 확장하는 두 포인터 방식이 핵심 패턴이다.
📊 시간/공간 복잡도 분석
| 유저 분석 | 실제 분석 | 결과 | |
|---|---|---|---|
| Time | O(n^2) | O(n^2) | ✅ |
| Space | O(1) | O(1) | ✅ |
피드백: 모든 위치에서 가운데를 기준으로 좌우로 확장하며 회문을 세는 방식으로 구현되어 있습니다.
개선 제안: 현재 구현이 적절해 보입니다.
| * - 32칸 고정 길이의 stack이 필요하므로 O(1) | ||
| */ | ||
|
|
||
| class Solution { |
There was a problem hiding this comment.
저는 시프트로 비트를 하나씩 꺼내 자리에 얹는 방식으로 풀었는데, 스택에 담았다가 반대로 꺼내는 접근도 있군요. "뒤집는다"는 동작이 스택에 그대로 드러나서 의도가 잘 읽혔습니다.
두 부분이 눈에 들어 왔는데,
- getLast() 후 removeLast()는 pollLast() 하나로도 될 것 같습니다!
- 그리고 answer += bit * Math.pow(2, j) 부분인데, Math.pow가 double을 반환하다 보니 암묵적 (int) 로 변환됩니다. 이 부분을 bit << j로 쓰면 정수 연산만으로 끝나서, 20만 건 기준으로는 333ms에서 35ms로 줄어들더라고요. 복잡도는 똑같이 O(1)이라 통과에는 영향이 없지만 상수 차이가 있어서 공유드려봅니다!
There was a problem hiding this comment.
와우.. 상세한 설명 감사해요. 고민이 거기까지 미치지 못했는데 시야가 넓어지는 느낌이네요!
| count[s.charAt(deleteTarget++) - 'A']--; | ||
| } | ||
| } | ||
|
|
There was a problem hiding this comment.
코드 잘 읽었습니다!
count 26칸을 더한 total이 윈도우에 들어 있는 글자 수, 즉 윈도우 길이고, count[maxCountAlphabet]이 그 안에서 가장 많이 나온 문자의 개수네요.
그래서 total - count[maxCountAlphabet] <= k가 "바꿔야 할 개수가 k 이하인가"로 표현이 되네요!
저는 위 부분을 left, right와 windowLength로 표현했는데, 이번에 카운트의 합으로 length를 표현할 수 있다는걸 배워갑니다!
답안 제출 문제
작성자 체크 리스트
In Review로 설정해주세요.검토자 체크 리스트
Important
본인 답안 제출 뿐만 아니라 다른 분 PR 하나 이상을 반드시 검토를 해주셔야 합니다!