두 정수 사이의 합 / p와 y의 개수

나의 기록·2026년 6월 5일

코딩테스트

목록 보기
10/35

문제 1. 두 정수 사이의 합

문제 설명

두 정수 a, b가 주어졌을 때 a와 b 사이에 속한 모든 정수의 합을 리턴

  • a와 b가 같은 경우는 둘 중 아무 수나 리턴
  • a와 b는 -10,000,000 이상 10,000,000 이하인 정수
  • a와 b의 대소관계는 정해져있지 않음

풀이 - 등차수열 합 공식

등차수열 합 공식

S = (첫째항 + 마지막항) * 항의 개수 / 2

a, b 사이의 정수 합이니까:

  • 첫째항 = a, 마지막항 = b
  • 항의 개수 = |a - b| + 1
S = (a + b) * (|a - b| + 1) / 2

내 풀이

import java.lang.Math;
class Solution {
    public long solution(int a, int b) {
        long answer = 0;
        answer = (long)(a + b) * (long)(Math.abs(a - b) + 1) / 2;
        return answer;
    }
}

핵심 포인트

① 나눗셈 순서 주의

처음에 이렇게 짰다가 버그 발생:

answer = (a + b) / 2 * (Math.abs(a - b) + 1);  // ❌

Java 정수 나눗셈은 소수점을 버리기 때문에 (a + b)가 홀수면 오차 발생.

a=3, b=4일 때:
(3 + 4) / 2 * 2 = 3 * 2 = 6  // 기대값은 7!

→ 곱셈 먼저, 나눗셈 나중으로 순서 변경:

answer = (a + b) * (Math.abs(a - b) + 1) / 2;  // ✅

② 왜 항상 2로 나눠떨어지나?

(a + b)와 (|a - b| + 1) 두 값의 홀짝성은 항상 반대.

aba+b|a-b|+1
358 (짝)3 (홀)
347 (홀)2 (짝)
4610 (짝)3 (홀)

→ 홀수 × 짝수는 항상 짝수 (짝수 = 2의 배수이므로, 곱 안에 2가 항상 포함됨)
→ 따라서 항상 2로 나눠떨어짐이 보장됨

③ long 캐스팅으로 오버플로우 방지

a, b 최대값이 10,000,000이므로 중간 계산값이 int 범위를 초과할 수 있음.

(long)(a + b) * (long)(Math.abs(a - b) + 1) / 2

다른 풀이 비교

class Solution {
    public long solution(int a, int b) {
        return sumAtoB(Math.min(a, b), Math.max(b, a));
    }
    private long sumAtoB(long a, long b) {
        return (b - a + 1) * (a + b) / 2;
    }
}
내 풀이다른 풀이
대소처리Math.abs()Math.min/max로 사전 정렬
구조단일 메서드책임 분리 (정렬 / 계산)
가독성보통sumAtoB 이름만 봐도 의도 파악 가능

→ 메서드로 분리하면 관심사 분리가 되어 가독성이 올라감



문제 2. p와 y의 개수

문제 설명

대문자와 소문자가 섞인 문자열 s에서 'p'의 개수와 'y'의 개수를 비교해 같으면 true, 다르면 false 리턴

  • 'p', 'y' 모두 없는 경우 항상 true
  • 대소문자 구별 없이 비교

풀이 과정

① 문자열 전체를 소문자로 변환 후 순회

s.toLowerCase()

→ 미리 소문자로 변환하면 이후 비교가 단순해짐

② split("") 대신 toCharArray() 사용

// ❌ split("") - 정규식 엔진 오버헤드 발생
String[] strArr = s.split("");

// ✅ toCharArray() - 단순 char 배열 변환, 더 효율적
char[] charArr = s.toCharArray();

③ 삼항연산자 대신 boolean 직접 반환

return cntP == cntY ? true : false;  // ❌ 불필요한 삼항연산자
return cntP == cntY;                 // ✅ == 비교 자체가 boolean 반환

최종 풀이

class Solution {
    boolean solution(String s) {
        int cntP = 0;
        int cntY = 0;
        char[] charArr = s.toCharArray();
        for (char c : charArr) {
            char lower = Character.toLowerCase(c);
            if (lower == 'p') {
                cntP++;
            } else if (lower == 'y') {
                cntY++;
            }
        }
        return cntP == cntY;
    }
}

핵심 포인트 정리

항목변경 전변경 후이유
문자열 순회split("")toCharArray()정규식 오버헤드 제거
대소문자 처리equalsIgnoreCase()Character.toLowerCase()미리 변환 후 단순 비교
반환cntP==cntY ? true : falsecntP==cntY== 자체가 boolean
for문for(int i=0; i<arr.length; i++)for(char c : arr)enhanced for문으로 간결하게

뭔가 간결하게 풀어보고 싶은데 한참 멀은듯.
다른 사람들이 푼거보니까 비슷한것도 많은데 저렇게 깔끔하게 처리한 것도 많았음. 좀 더 깔끔하게 풀 수 있도록 노력해야겠음.

profile
뭐든 남겨본다

0개의 댓글