Cộng đồng Hỏi & Đáp của Inflearn
외부 문제 질문
Viết
·
114
0
안녕하세요 강사님 혹시 괜찮으시다면
어디선가 봤는데 아직도 기억에 남는 코테 문제가 있습니다.
아직도 못풀고 제 머릿속에 남아있는데요 혹시 도움을 주실 수 있으면 감사하겠습니다.
문제는 아래와 같습니다.
N에 해당하는 개수의 숫자가 나옵니다
테스트 데이터
6
0 1 -1 2 -2 3
첫 줄 N은 0<=200,000 범위
수는 음의 정수 , 0 , 양의정수입니다.
위와 같이 숫자가 5개가 나오면 다 처음부터 더하는 것인데 여기서 n개의 수 중 딱 한개를 0으로 변환시킬 수 있습니다.
그랬을 때 0이 최대가 되는 개수가 몇인지 고르는 겁니다.
DP 문제인 것 같은데 아직도 해결을 못하겠네요..
가령 위 데이터에서는
처음은 0이니 0
두번째 1를 더해서 1
세번째 -1를 더해서 0
네번째 2를 더해서 2
다섯번째 -2를 더해서 0
여섯번째 3를 더해서 3입니다.
즉 0은 3개인데 여기서 0이 아닌 3개중 하나 아무거나 바꿔도 0의 최대 개수는 4개임으로
답은 4입니다.
이걸 어떻게 풀어나가야 할까요?
혹시 이러한 비슷한 백준문제나 프로그래머스 문제가 있으신가요?
도움 부탁드려요 ㅠㅠ
Câu trả lời 2
0
안녕하세요^^
제가 문제 이해를 정확하게 했는지 모르겠지만 수열의 숫자 중 최대 한개까지만 0으로 바꾸어 첫 항부터 시작하는 누적합이 0이 되는 경우가 최대가 되도록 하는 문제라 이해했습니다. 아래는 제가 짜본 코드입니다.
이 문제는 누적합과 해시맵을 적절히 사용하면 O(n) 시간복잡도에 가깝게 해결할 수 있습니다.
아침에 짠거라 출근해야 해서 여러 케이스로 검증을 하지는 못했습니다. 시간날 때 검증을 해봐야 겠습니다.
import java.util.*;
class Solution {
public int solution(int n, int[] nums){
int answer = 0;
HashMap<Integer, Integer> freq = new HashMap<>();
int[] prefix_sum = new int[n];
prefix_sum[0] = nums[0];
for(int i = 1; i < n; i++) prefix_sum[i] = prefix_sum[i-1] + nums[i];
int[] left_zero = new int[n+1]; //left_zero[i]값은 i번째 앞에까지 누적합 중 0의 개수
for(int i = 1; i <= n; i++){
if(prefix_sum[i-1] == 0) left_zero[i] = left_zero[i-1] + 1;
else left_zero[i] = left_zero[i-1];
}
for(int x : prefix_sum){
freq.put(x, freq.getOrDefault(x, 0) + 1);
}
answer = left_zero[n]; //아무것도 바꾸지 않았을 때 누적합 0의 개수
for(int i = 0; i < n; i++){
int tmp = left_zero[i] + freq.getOrDefault(nums[i], 0); // i번째를 0으로 변경했을 때 누적합 0의 개수
answer = Math.max(answer, tmp);
freq.put(prefix_sum[i], freq.get(prefix_sum[i]) - 1); // i번째 숫자를 0으로 바꾸면 i번째 이후의 누적합만 변경되므로 그 이전 것은 다 지워줘야 함
}
return answer;
}
public static void main(String[] args){
Solution T = new Solution();
System.out.println(T.solution(6, new int[]{0, 1, -1, 2, -2, 3}));
}
}
0
안녕하세요, 인프런 AI 인턴입니다. youngyou1324님!
코딩테스트 문제와 관련하여 도움을 드릴 수 있는 자료를 찾아보았습니다. 그러나 이 문제에 해당되는 직접적인 자료는 찾기 어려웠습니다. 하지만 비슷한 유형의 문제가 여러 가지 있을 수 있는데요, 특히 동적 프로그래밍(DP) 접근법을 사용하여 배열을 탐색하고 이를 통해 원하는 결과를 도출해야 하는 문제들이 일반적입니다.
이제 문제에 대한 간단한 접근 방식을 설명드리겠습니다:
누적 합 계산: 주어진 수열을 두 번 순회합니다. 첫 번째는 원래의 누적 합을 계산하고, 두 번째는 한 원소를 0으로 바꾸었을 때의 상황을 각각 계산합니다.
0으로 바꾸기: 배열에서 각 원소를 0으로 바꾸면서, 그때의 누적 합 결과를 확인합니다. 각 경우의 수 마다 0이 발생하는 횟수를 기록합니다.
최적화된 계산: 매번 계산하는 대신, 이전 결과를 재활용하여 빠르게 계산할 수 있도록 구조를 잡습니다. 이를 통해 최다의 0이 발생할 수 있는 설정을 찾습니다.
비슷한 유형의 문제를 더 많이 풀어보시고, 그런 문제의 솔루션을 참고하시면 좋을 것 같습니다. 예시로는 프로그래머스의 ‘연속된 부분수열의 합’ 류의 문제가 있습니다. 이렇게 특정 조건 하에서 배열의 값을 조작해 최대화하는 문제를 집중적으로 분석해보세요.
아래는 알고리즘적 사고를 키우는 데 도움이 되는 링크를 소개합니다:
- 백준의 연속 부분합 문제
- 프로그래머스의 연속 부분수열 문제
위 링크들을 통해 기본적인 접근 방식을 익힌 뒤 응용하여 주어진 문제를 풀어보세요.
저는 질문자님의 이해를 돕고자 지식공유자님의 기존 답변을 참고하여 유사한 답변 링크를 추천해드리고 있습니다. 현재 베타 기능으로 답변이 만족스럽지 않을 수 있는 점 양해 부탁드립니다. 🙏 추가적으로 궁금한 점이 있으시면, 이어서 질문해 주세요. 곧 지식공유자께서 답변해 주실 것입니다.





