개발/코딩테스트

[LeetCode] 67. Add Binary #Easy #Java

brobro332 2025. 3. 1. 22:50
반응형
문제
Given two binary strings a and b, return their sum as a binary string.
예제 1
Input: a = "11", b = "1"
Output: "100"

예제 2
Input: a = "1010", b = "1011"
Output: "10101"
제약조건
✅ 1 <= a.length, b.length <= 104 

✅ a and b consist only of '0' or '1' characters. 
✅ Each string does not contain leading zeros except for the zero itself.

 
문제풀이 1

import java.math.BigInteger;

class Solution {
    public String addBinary(String a, String b) {
        // 1. 변수 선언 및 초기화
        BigInteger numA = new BigInteger(a, 2);
        BigInteger numB = new BigInteger(b, 2);
        BigInteger result = numA.add(numB);

        // 2. 반환
        return result.toString(2);
    }
}

  • BigInteger의 함수들이 어떻게 실행되는지는 모르겠지만 굉장히 느리다.
가독성은 좋지만 주어지는 두 문자열이 항상 길이가 긴 경우가 아니라면 비효율적인 코드라고 생각한다. 

 

문제풀이 2 

class Solution {
    public String addBinary(String a, String b) {
        // 1. 변수 선언 및 초기화
        int lengthA = a.length(); 
        int indexA = lengthA - 1; 
        int lengthB = b.length(); 
        int indexB = lengthB - 1; 
        boolean carryFlag = false;
        StringBuilder sb = new StringBuilder();

        // 2. 순회하며 덧셈 결과 문자열 생성
        while (indexA >= 0 || indexB >= 0) {
            int intA = indexA >= 0 ? a.charAt(indexA--) - '0' : 0;
            int intB = indexB >= 0 ? b.charAt(indexB--) - '0' : 0;
            int valueSum = intA + intB + (carryFlag ? 1 : 0);

            carryFlag = valueSum >= 2;

            sb.append(valueSum % 2);
        }

        // 3. 마지막 올림수 있을 경우 추가
        if (carryFlag) sb.append(1);

        // 4. 거꾸로 반환
        return sb.reverse().toString();
    }
}

  • 이번 문제를 풀면서 몇 가지 알게 된 사실이 있다.
  • 첫 번째로 자바에서는 다음과 같이 두 개 이상의 변수를 한 번에 초기화하지 못한다.
/*
 * int lengthA;
 * int indexA = a.length();
 */
int lengthA, indexA = a.length();

 

  • 내가 의도한 대로 코드를 작성하려고 한다면 다음과 같이 작성해야 한다.
/*
 * int lengthA = a.length();
 * int indexA = lengthA - 1;
 */
int lengthA = a.length(), indexA = lengthA - 1;
근데 가독성이 많이 떨어진다. 처음 읽는 입장에서 indexA를 발견할 수 있을까? 

 

  • 두 번째로 삼항연산자를 다음과 같이 피연산자에 사용할 수도 있다는 걸 알게 되었다.
// 1 번째 코드
int valueSum = intA + intB;
if (carryFlag) valueSum++;

// 2 번째 코드
int valueSum = intA + intB + (carryFlag ? 1 : 0);
chatGPT는 성능적으로 차이가 있다곤 하는데, 흠..
어차피 조건문 타는 건 똑같아서 차이가 있더라도 미미할 것 같다. 구글링 해봐도 관련 내용도 별로 없다.
실제로 코드를 바꿔서 제출해 봐도 실행속도가 최적화되지는 않았다.
다만 본인은 메서드 줄이 적을수록, 또 짧을수록 가독성이 좋다고 생각해서 나름 수확이 있다.

 

  • 세 번째로 삼항연산자도 결국에 조건문이라는 점이다.
// 삼항연산자 사용
carryFlag = valueSum >= 2 ? true : false;

// 최적화된 코드
carryFlag = valueSum >= 2;
  • 불필요하게 사용하면 결국 분기를 타게 되므로 가능하면 자제하는 것이 좋다.
근데 위 코드는 그냥 내가 불필요한 분기를 작성한 것 같긴 하다. 😅
  • 정리하자면 삼항연산자를 떠나서 분기를 치지 않을 수 있다면 최대한 자제하라는 것이다.

 

이미지 출처

 

[김은우의 에듀테크 트렌드 따라잡기] 코딩 교육 사이트 LeetCode가 보여주는 코딩교육의 핵심

[김은우의 에듀테크 트렌드 따라잡기] 코딩 교육 사이트 LeetCode가 보여주는 코딩교육의 핵심

edu.chosun.com