[알고리즘] ealry return, while문은 언제쓸까?

Soozynn·2022년 4월 8일
0

알고리즘 풀이

목록 보기
2/6

Day3

문제

/*

There are numBottles water bottles that are initially full of water.
You can exchange numExchange empty water bottles from the market with one full water bottle.
The operation of drinking a full water bottle turns it into an empty bottle.
Given the two integers numBottles and numExchange,
return the maximum number of water bottles you can drink.

[Example 1]
https://assets.leetcode.com/uploads/2020/07/01/sample_1_1875.png

Input: numBottles = 9, numExchange = 3
Output: 13
Explanation: You can exchange 3 empty bottles to get 1 full water bottle.
Number of water bottles you can drink: 9 + 3 + 1 = 13.

[Example 2]
https://assets.leetcode.com/uploads/2020/07/01/sample_2_1875.png

Input: numBottles = 15, numExchange = 4
Output: 19
Explanation: You can exchange 4 empty bottles to get 1 full water bottle.
Number of water bottles you can drink: 15 + 3 + 1 = 19.

[Constraints]
1 <= numBottles <= 100
2 <= numExchange <= 100

[문제 링크]
https://leetcode.com/problems/water-bottles/

*/

내가 작성한 풀이

export default function calculateNumberOfBottles(numBottles, numExchange) {
  let interchangeableBottles = Math.floor(numBottles / numExchange);
  let remainingBottles = numBottles % numExchange;
  let bonusBottles = interchangeableBottles;

  if (numBottles === numExchange) {
    return numBottles + 1;
  }

  if (numBottles < numExchange) {
    return numBottles;
  }

  while ((interchangeableBottles + remainingBottles) >= numExchange) {
    bonusBottles += Math.floor((interchangeableBottles + remainingBottles) / numExchange);
    interchangeableBottles = Math.floor((interchangeableBottles + remainingBottles) / numExchange);
    remainingBottles = interchangeableBottles % numExchange;
  }

  return numBottles + bonusBottles;
}

다른 분들 풀이

export default function calculateNumberOfBottles(numBottles, numExchange) {
  let result = numBottles;
  let empty = numBottles;

  while (Math.floor(empty / numExchange)) {
    const exchanged = Math.floor(empty / numExchange);
    result += exchanged;
    empty = exchanged + (empty % numExchange);
  }

  return result;
}

테스트 코드

// ✅ test code
import { expect } from "chai";
import calculateNumberOfBottles from "../lib/03-waterBottle";

describe("3. Calculate Number of water bottles", () => {
  it("It should pass basic cases", () => {
    expect(calculateNumberOfBottles(9, 3)).to.eql(13);
    expect(calculateNumberOfBottles(15, 4)).to.eql(19);
    expect(calculateNumberOfBottles(5, 5)).to.eql(6);
    expect(calculateNumberOfBottles(2, 3)).to.eql(2);
    expect(calculateNumberOfBottles(17, 3)).to.eql(25);
  });
});

🌟 되짚어본 점

이번 알고리즘을 통해 느낀 점은 사소한 부분이긴 하지만,

1) 현재 연산에서는 복잡한 연산이 존재하지 않기 때문에 굳이 early return을 쓰지 않아도 된다는 점이다.
문제의 난이도가 있고 while문 내에서 공간/시간 복잡도에 차이가 커지는 이유가 있다면 당연히 early return을 써주겠지만, 현재 로직에서는 굳이 필요하지 않다는 점.

2) while을 언제 사용할까?
나는 보통 동일한 조건을 계속 반복해야할 때 자주 썼었다.
ex) 어느 현 시점이 되기 전까지 어떤 동작을 계속 반복해야할 경우

  • for문while문의 차이점은 무엇일까?🧐
    일반적으로 반복 횟수가 예측 가능할 때는 for 문을 사용하는 것이 가독성이 더 좋고, 반복 횟수를 예측할 수 없으면 while 문을 사용하는 것이 더 적합한 경우가 많은 것 같다.
  • break, continue
    • continue: 이어서,현재 반복에서 명령문의 실행을 종료하고 반복문의 처음으로 돌아가여 루프문의 다음 코드를 실행.
    • break: stop, 현재 반복문을 종료하고, 그 다음 문으로 프로그램 제어를 넘김.

3) 또 하나는 나는 불필요하게 전역에 변수를 3개나 설정을 해주었는데, 다른 분의 풀이에서는 while문 내에서 하나의 변수를 선언해주고 전역에서는 2개의 변수만 선언해주어 불필요한 부분에서 변수를 선언하지 않고, 조금 더 간결하게 로직을 짰다는 점이다.

다른 분의 풀이를 보았다가 내 풀이를 다시 보았을 때, 가독성이 떨어지고 한 눈에 들어오지 않음을 느꼈다.

문제 출처) leetcode

0개의 댓글