[Java] 12924 숫자의 표현
1. 문제
숫자의 표현
2. 정답코드
등차수열
class Solution {
public int solution(int n) {
int count = 0;
for (int k = 1 ; (k - 1) * k / 2 < n; k++) {
int numerator = n - k * (k - 1) / 2;
if (numerator % k == 0) {
count++;
}
}
return count;
}
}
등차수열의 합 공식
- 여기서는 숫자가 1 간격으로 늘어남
1 + 2 + 3 + ... + (k-1)
합 = (첫째 수 + 마지막 수) * 개수 / 2
- 첫째 수 = 1
- 마지막 수 = k-1
- 개수 = (k-1)
1 + 2 + 3 + ... + (k-1) = (1 + (k-1)) * (k-1) / 2
= k * (k-1) / 2
(k-1)*k/2
연속된 k개의 숫자를 더하면
x + (x+1) + ... + (x+k-1) = n
공식으로 바꾸면:
k*x + k*(k-1)/2 = n
x를 구하면:
x = (n - k*(k-1)/2) / k
여기서 k가 연속된 숫자의 개수이고 구한 x가 시작점
* ****
** ***
*** **
**** *
삼각형 두개 더하고 나누는 원리랑 같다
공식그대로 쓴 코드
이건 chatGPT에 물어봐서 내거보다 훨씬 간단한 코드
class Solution {
public int solution(int n) {
int count = 0;
// k: 수열 길이
for (int k = 1; k <= n; k++) {
// 등차수열 합 공식: n = k * (2a + k - 1) / 2
// 2n = k * (2a + k - 1)
// 2a = (2n / k) - (k - 1)
if ((2 * n - k * (k - 1)) % (2 * k) == 0) {
count++;
}
}
return count;
}
}
- k는 수열의 길이(1, 2, 3, ...)
- 수열의 합 공식에서 a 계산하면
2a = (2n / k) - (k - 1) - a가 자연수인지 확인하기 (2n - k(k-1)) % (2*k) == 0
나머지가 0이면 a가 정수 → 자연수 수열 존재 - 존재하면 count++
투포인터
class Solution {
public int solution(int n) {
int count = 0;
int left = 1, right = 1, sum = 1;
while (left <= n) {
if (sum < n) {
right++;
sum += right;
} else if (sum > n) {
sum -= left;
left++;
} else { // sum == n
count++;
sum -= left;
left++;
}
}
return count;
}
}
- left와 right를 연속 구간의 시작과 끝으로 둔다.
- 처음에는 left = 1, right = 1, sum = 1
- sum > n → 오른쪽 범위를 늘리고 (right++), 합 키우기
- sum < n → 왼쪽 범위 줄이고 (left++), 합을 줄여
- sum == n 이면 → 하나의 경우를 찾은 거니까 count++,
그리고 계속 탐색하려고 left++ 하면서 다음 구간을 체크 - left가 n을 넘어가면 종료
왜 등차수열과 동일한지?
- 투 포인터로 찾는 left ~ right 구간은 결국 연속된 자연수의 합
- 즉, (left + (left + 1) + ... + right) 이런 꼴인데, 이게 바로 등차수열의 합