목차
문제
코드
코드 보기
import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.util.StringTokenizer; public class Main { static int N; static int[] S; static boolean binarySearch(int offset, int index) { int mid = offset + S[index-1] + (index + 2); if(N <= offset + S[index-1]) { return binarySearch(offset,index-1); } else if(N <= mid) { return N == mid - (index + 1); } else { return binarySearch(mid, index-1); } } public static void main(String[] args) throws IOException { BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); N = Integer.parseInt(br.readLine()); S = new int[50]; int index = 0; while(N>S[index]) { index++; S[index] = S[index-1] * 2 + (index + 2); } if(binarySearch(0,index)) System.out.println("m"); else System.out.println("o"); } }
해설
문제의 N의 범위가
1 ≤ N ≤ 10^9 이므로 O(N) 으로는 풀 수 없고
이분탐색을 이용하여 풀었다
1. 점화식을 통해 N번째 글자가 나오기 시작하는 S(k) 구하기
- 코드
S = new int[50]; int index = 0; while(N>S[index]) { index++; S[index] = S[index-1] * 2 + (index + 2); }
- 점화식
S[index] = S[index-1] * 2 + (index + 2);
문제에서는 S(k)를 수열 자체로 봤지만
여기 코드에서는 수열의 길이로 두었다
( 수열 자체로 두면 10^9 길이의 문자열은 메모리 제한을 벗어난다 )
문제에서
이라고 하였고 k 대신 index를 쓴 것을 제외하고는 완벽히 똑같다는 걸 알 수 있다
그리고
`N번째 글자가 나오기 시작하는 S(k)` 를 구하기 위해
수열의 길이가 N 보다 작은 동안은 점화식을 계속 반복했고
N과 같거나 큰 순간 while 문을 빠져 나왔다
- 코드
2. 이분탐색으로 통해 N번째 위치에 있는 글자 구하기
- 코드
static boolean binarySearch(int offset, int index) { int mid = offset + S[index-1] + (index + 2); if(N <= offset + S[index-1]) { return binarySearch(offset,index-1); } else if(N <= mid) { return N == mid - (index + 1); } else { return binarySearch(mid, index-1); } }
앞서 N번째 글자가 나오기 시작하는 index를 구했고 그 index를 가지고
binarySearch(0,index)
위와 같이 main 함수에서 재귀함수를 호출했다
재귀함수에는 이분탐색을 위해
현재 탐색하고 있는 수열의 index와
현재 탐색의 offset(시작위치)을 매개변수로 받고 있다
수열의 구분
문제에서 알 수 있듯이
수열 규칙상
수열을 앞부분, 중간부분, 뒷부분으로 구분 지을 수 있고
여기서 핵심은
중간부분은 index가 몇이 되든
"mooo..." 와 같이 맨 처음만 m이고 나머지는 o라는 사실이다
따라서,
else if(N <= mid) { return N == mid - (index + 1);
N이 맨 처음이면 return true → main함수에서 "m" 출력
아니면 return false → main함수에서 → "o" 출력
하여 N번째 글자를 출력했다
- 코드
'알고리즘' 카테고리의 다른 글
[LeetCode] 104. Maximum Depth of Binary Tree (golang) (0) | 2021.06.07 |
---|---|
[LeetCode] 66. Plus One (golang) (0) | 2021.06.02 |
[LeetCode] 205. Isomorphic Strings (golang) (0) | 2021.06.02 |
[LeetCode] 455. Assign Cookies (golang) (0) | 2021.06.01 |
[LeetCode] 572. Subtree of Another Tree (golang) (0) | 2021.06.01 |
댓글