30. [Java] 분기점 찾기
https://school.programmers.co.kr/learn/courses/30/lessons/181894
- 정수 배열 arr가 주어진다.
- 배열 안의 2가 모두 포함된 가장 작은 연속된 부분 배열을 return
- 단, arr에 2가 없는 경우 [-1]을 return
- 1 ≤ arr의 길이 ≤ 100,000
- 1 ≤ arr의 원소 ≤ 10
정답코드
import java.util.*;
class Solution {
public int[] solution(int[] arr) {
int startIndex = -1;
int endIndex = -1;
// 처음, 마지막 2 위치 찾기
for (int i = 0; i < arr.length; i++) {
if (arr[i] == 2) {
if (startIndex == -1) {
startIndex = i;
}
endIndex = i;
}
}
// 2없는 경우
if (startIndex == -1) {
return new int[]{-1};
}
// startIndex부터 endIndex까지 배열 복사
return Arrays.copyOfRange(arr, startIndex, endIndex + 1);
}
}
조건문 분기점
문제는 간단한데 분기점 찾기가 어려웠다. 이 문제는 "2가 어디서 시작되고 어디서 끝나는지"를 알아내는 것이 전부이다. 분기점을 찾는 건 결국 **처음 2가 나온 인덱스 (startIndex
)와 마지막 2가 나온 인덱스 (endIndex
)를 찾는 과정이다.
어려웠던 점은 한 번의 for문으로 시작 인덱스와 끝 인덱스 두 개를 각각 변수에 집어넣을 수 있는지였는데, 시작 인덱스의 초기값이 -1
이면 아직 2를 한 번도 만나지 않았다는 뜻이므로, 처음으로 2를 발견했을 때 한 번만 first
에 대입하고, 이후엔 건너뛸 수 있다.
반면 last
는 2를 만날 때마다 계속 갱신하면 가장 마지막 2의 위치를 저장할 수 있다. 결국 한 번의 순회만으로도 이 두 개의 인덱스를 모두 처리할 수 있었고, 이를 통해 2가 포함된 최소 연속 부분 배열을 정확하게 추출할 수 있었다.
// 배열을 순회하며 처음 등장하는 2의 인덱스를 startIndex에 저장하고,
// 마지막으로 등장한 2의 인덱스를 endIndex에 저장한다.
for (int i = 0; i < arr.length; i++) {
if (arr[i] == 2) {
if (startIndex == -1) {
startIndex = i; // 첫 번째 2의 위치 저장
}
endIndex = i; // 마지막 2의 위치 계속 갱신
}
}
✅ return new int[]{-1};
int[] result = solution(new int[]{1, 3, 5}); // 2가 없음
System.out.println(Arrays.toString(result)); // [-1]
- 자바에서 -1 하나만 담긴 배열을 return 문에서 직접 생성해서 바로 반환하는 코드이다.
✅ Arrays.copyOfRange(arr, startIndex, endIndex + 1);
자바에서 배열을 슬라이싱(slice)하는 가장 대표적인 방법이다.
Arrays.copyOfRange(원본배열, 시작인덱스, 끝인덱스+1);
startIndex
: 포함됨 (inclusive)endIndex + 1
: 미만 (exclusive) → 그래서+1
해줘야 진짜endIndex
까지 포함됨
예를 들면 :
int[] arr = {10, 20, 30, 40, 50};
int[] result = Arrays.copyOfRange(arr, 1, 4);
System.out.println(Arrays.toString(result)); // [20, 30, 40]
- 1번 인덱스부터 3번 인덱스까지 포함됨 (
endIndex = 3
) 4
를 넣어야30
,40
까지 포함됨