프로그래머스/Lv. 1

[프로그래머스 코딩테스트] 음양 더하기(Java)

Sigfriede 2023. 4. 5. 01:19

  문제 설명

  어떤 정수들이 있습니다. 이 정수들의 절댓값을 차례대로 담은 정수 배열 absolutes와 이 정수들의 부호를 차례대로 담은 불리언 배열 signs가 매개변수로 주어집니다. 실제 정수들의 합을 구하여 return 하도록 solution 함수를 완성해주세요.

 

  제한사항

  • absolute의 길이는 1 이상 1,000 이하입니다.
  • absolutes의 모든 수는 각각 1 이상 1,000 이하입니다.
  • signs의 길이는 absolutes의 길이와 같습니다.
  • signs[i]가 참이면 absolutes[i]의 실제 정수가 양수임을, 그렇지 않으면 음수임을 의미합니다.

 

  입출력 예

absolutes signs result
[4, 7, 12] [true, false, true] 9
[1, 2, 3] [false, false, true] 0
class Solution {
    public int solution(int[] absolutes, boolean[] signs) {
        int answer = 0;
        for (int i = 0; i < signs.length; i++) {
                if (!signs[i]) {
                    absolutes[i] *= -1;
                }
        }
        for (int i = 0; i < absolutes.length; i++) {
            answer += absolutes[i];
        }
        return answer;
    }
}

  이 풀이에서 관건은 signs 배열에서 false인 원소[i]와 대응하는 absolutes[i]를 음수로 바꿔주는 것입니다.

  for문이 signs의 길이만큼 순회합니다. 만약 signs[i]가 false라면 absolutes[i]에 * -1을 함으로써 음수로 바꾸어줍니다. 이제 absolutes 배열은 음수와 양수가 반영된 상태입니다. 이를 다시 for문으로 absolutes의 길이만큼(signs과 길이가 같으므로 어떤 것을 써도 무방) 순회하면서 각 원소의 값을 더해줍니다.

  하지만 저는 이 문제를 보고 보수 계산으로도 풀 수 있지 않을까 싶어 풀어보았습니다.

 

class Solution {
    public int solution(int[] absolutes, boolean[] signs) {
        int answer = 0;
        for (int i = 0; i < signs.length; i++) {
            if (!signs[i]) {
                answer += ~absolutes[i] + 1;
            } else {
                answer += absolutes[i];
            }
        }
        return answer;
    }
}

  위 풀이는 2의 보수(~)로 계산했습니다. 보수 계산 역시 음수를 양수로, 양수를 음수로 바꾸어주는 계산입니다. 다만 마지막에 꼭 1을 더해주어야 합니다. 예를 들어 5를 Not 연산을 한다면 -6이 됩니다. 앞서 말했듯 1를 더해주어야 -5가 되겠죠. 이는 1을 더함으로써 맨 끝자리 수에 1이 추가되며 이진수에서 자리올림이 발생하여 모든 비트를 반전시키는 효과가 있기 때문입니다.

  두 코드 모두 실행시켜본 결과 속도면에서는 별차이가 없었습니다. 다만 컴퓨터적 풀이에 더 가까운 보수 연산이 0.0n초 정도 빠른 결과를 보였습니다. 유의미한 차이는 아닌 듯 합니다.