Post

[프로그래머스/LV2] Summer/Winter Coding(~2018) - 점프와 순간 이동 - greedy, bit (Java)

점프와 순간 이동 문제를 Java로 해결한 풀이입니다. greedy 그리고 bit 알고리즘을 활용하여 2가지 풀이로 문제를 정의합니다.

Summer/Winter Coding(~2018) - 점프와 순간 이동

🙋‍♂️ 들어가며

아이언슈트를 활용해 건전지 사용량의 최솟값을 구하는 문제이다.

목표

  • 한번에 k칸 점프 -> 건전지 사용량 += k
  • 텔레포트 (현재까지 온 거리 * 2) -> 건전지 x


0부터 x까지 구해보았다

1
2
3
4
5
6
7
# tc-1 : N = 5
0 -> 1(++) -> 2(1*2) -> 4(2*2) -> 5(++)

# tc-2 : N = 6
0 -> 1(++) -> 2 (1*2) -> 3(++) -> 6(3*2)

# tc-3 : N = 5000

N : 5000 을 구하려니 너무 복잡하더라

그래서 다시 바꿔생각해서 N -> 0으로 거꾸로 계산해보았다

5000 -> 2500 -> 1250 -> 625(홀) -> 312 -> 156 -> 78 -> 39(홀) -> 19(홀) -> 9(홀) -> 4 -> 2 -> 1(홀) -> 0

5가 나오네?

다른 testcase로

N = 9를 보았다

0 -> 1(++) -> 2(12) -> 4(22) -> 8(4*2) -> 9(++)

9(홀) -> 4 -> 2 -> 1(홀) -> 0


이어서 N = 19

0 -> 1(++) -> 2(12) -> 4(22) -> 8(42) -> 9(++) -> 18(92) -> 19(++)

19(홀) -> 9(홀) -> 4 -> 2 -> 1(홀) -> 0

N -> 0 방향으로 홀,짝 조건을 이용해 그리디 코드가 맞다고 판단이 들어서 다음과 같이 코드를 작성했다


✅ 정답 코드 (greedy)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public class Solution {
    public int solution(int n) {
        int cnt = 0;
        
        // 1. 거꾸로 n -> 0
        while (n > 0) {
            
            // 1-1. 홀
            if (n % 2 == 1) {
                n /= 2;
                cnt++;
            }
            
            // 1-2. 짝
            else if (n % 2 == 0) {
                n /= 2;
            }
        }

        return cnt;
    }
}









그리고 생각해보니 2배라서 2진 비트로도 풀이가 가능할 지 시도해보게 되었다

| 대상 | 16384 | 8192 | 4096 | 2048 | 1024 | 512 | 256 | 128 | 64 | 32 | 16 | 8 | 4 | 2 | 1 | |—:|—:|—:|—:|—:|—:|—:|—:|—:|—:|—:|—:|—:|—:|—:|—:| | 5 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 1 | | 6 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 1 | 0 | | 315 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 1 | 1 | 1 | 1 | 1 | 1 | | 5000 | 0 | 0 | 1 | 0 | 0 | 1 | 1 | 1 | 0 | 0 | 0 | 1 | 0 | 0 | 0 |

315(홀) -> 157(홀) -> 78 -> 39(홀) -> 19(홀) -> 9(홀) -> 4 -> 2 -> 1(홀) -> 0

답 : 5

어????? 2진 비트 풀이도 맞겠다는 생각이 들었다

그래서 다음과 같이 구현했으나 String temp = "" temp += ch 일 경우 매번 새로운 String을 만든다고 해서 시간초과가 나게 되었다

❌ 오답 코드 (2진 bit)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
public class Solution {
    public int solution(int n) {
        int cnt = 0;
        
        // 1. 비트변환기
        String bit = bit_converter(n);
        
        // int x = 315;
        // String test = bit_converter(x);
        // System.out.println(bit);
        // System.out.println("--------");
        // System.out.println(test);
        
        
        // 2. 결과
        for (int i = 0; i < bit.length(); i++) {
            char ch = bit.charAt(i);
            if (ch == '1') cnt++;
        }
        
        return cnt;
    }
    
    
    // 2. 함수 : 2진 비트 변환기
    static String bit_converter(int n) {
        String temp = "";
        
        while (n > 0) {
            // 2-1. 짝수면?
            if (n % 2 == 0) {
                temp += '0';
                n /= 2;
            }
            // 2-2. 홀수면?
            else if (n % 2 == 1) {
                temp += '1';
                n /= 2;
            }
        }
        
        String res = "";
        for (int i = 0; i < temp.length(); i++) {
            char ch = temp.charAt(temp.length()-1-i);
            res += ch;
        }
        
        return res;
    }
    
    
}




StringBuilder를 사용하면 내부 Buffer에 계속 추가하는거라 훨씬 효율적이기에 StringBuilder로 교체하게 되었다

✅ 정답 코드 (2진 비트)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
public class Solution {
    public int solution(int n) {
        int cnt = 0;
        
        // 1. 비트변환기
        String bit = bit_converter(n);
        
        int x = 315;
        String test = bit_converter(x);
        // System.out.println(bit);
        // System.out.println("--------");
        // System.out.println(test);
        
        
        // 2. 결과
        for (int i = 0; i < bit.length(); i++) {
            char ch = bit.charAt(i);
            if (ch == '1') cnt++;
        }
        
        return cnt;
    }
    
    
    // 2. 함수 : 2진 비트 변환기
    static String bit_converter(int n) {
        StringBuilder sb = new StringBuilder();
        String res = "";
        
        while (n > 0) {
            // 2-1. 짝수면?
            if (n % 2 == 0) {
                sb.append('0');
                n /= 2;
            }
            // 2-2. 홀수면?
            else if (n % 2 == 1) {
                sb.append('1');
                n /= 2;
            }
        }

        res = sb.reverse().toString();
        return res;
    }
    
    
}
This post is licensed under CC BY 4.0 by the author.

Trending Tags

반갑습니다 무엇을 도와드릴까요?