본문 바로가기
알고리즘

99클럽 코테 스터디 2일차 TIL(최댓값과 최솟값 /프로그래머스)

by 순원이 2024. 3. 27.

문제                                                  

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

 

 

1 번째 시도                                            

import java.util.*;

class Solution {
    public String solution(String s) {
        String[] ch = s.split(" "); 
        int n = ch.length; 
        int[] numbers = new int[n];
        
        for (int i = 0; i < n; i++) {
            numbers[i] = Integer.parseInt(ch[i]);
        }
        
        int min = numbers[0];
        int max = numbers[0];
       
        for (int j = 1; j < n; j++) {
            min = Math.min(min, numbers[j]);
            max = Math.max(max, numbers[j]);
        }
        
        return min + " " + max;
    }
}



문제가 너무 쉽기 때문에 요구사항을 따로 정리하지 않았습니다. 
쉬운문제를 금방 풀었을지라도 더 좋은 풀이법이 있는지 다른 분의 코드를 보며 공부해봤습니다.
 

import java.util.Arrays;
public class Solution {
    public String solution(String str) {
        String[] arrStr = str.split(" ");
        int[] arrInt = new int[arrStr.length];
        int i=0;
        for(String part : arrStr){
          arrInt[i] = Integer.parseInt(part);
          i++;
        }

        StringBuffer sb = new StringBuffer();
        sb.append(Arrays.stream(arrInt).min().getAsInt());
        sb.append(" ");
        sb.append(Arrays.stream(arrInt).max().getAsInt());

        return sb.toString();
    }
}

출처:  프로그래머스 Ranny의 코드

 
 
다른 사람의 풀이인데요 제 코드보다 10배는 빠른 걸 확인할 수 있습니다.
이 분의 코드와 저의 코드는 다른 점이 두 가지가 있습니다.
1. StringBuffer를 이용한다.
2. Arrays.stream.min(), max() 함수를 이용한다.




나의 코드에 Stream 적용                          

        // StringBuffer sb = new StringBuffer();
        String min = Arrays.stream(arrInt).min().getAsInt() + "";
        // sb.append(" ");
        String max = Arrays.stream(arrInt).max().getAsInt() + "";

        return min + " " + max;

처음 for문과 Stream의 차이인 줄 알고 위 코드로 수정하고 테스트 했지만, 오히려 제 코드보다 2배는 느렸습니다. 당연히 Stream보다 for문이 빠른 사실을 재차 확인할 수 있었습니다.
그럼 StringBuffer의 차이일 것 같은데요 

제 코드에 StringBuffer를 적용 시켜보겠습니다.


나의 코드에 StringBuffer 적용                      

import java.util.*;

class Solution {
    public String solution(String s) {
        String[] ch = s.split(" "); 
        int n = ch.length; 
        int[] numbers = new int[n];
        
        for (int i = 0; i < n; i++) {
            numbers[i] = Integer.parseInt(ch[i]);
        }
        
        int min = numbers[0];
        int max = numbers[0];
       
        for (int j = 1; j < n; j++) {
            min = Math.min(min, numbers[j]);
            max = Math.max(max, numbers[j]);
        }
        
        StringBuffer sb = new StringBuffer();
        sb.append(min);
        sb.append(" ");
        sb.append(max);

        return sb.toString();
    }
}

 
그 어떤 코드보다 빨라졌습니다. 제 코드보다 100배는 빨라졌고 Ranny 코드보다 10배는 빨라졌습니다.
그렇다면 왜 StringBuffer를 쓰면 빨라질까요?


  1. 불변 문자열: Java에서 'String' 객체는 불변입니다. + 연산자를 사용하여 문자열을 연결하면 매번 새로운 String 개체가 생성됩니다. 이 작업은 특히 루프나 여러 문자열을 연결할 때 메모리와 시간 측면에서 비용이 많이 듭니다.
  2. StringBuffer는 변경 가능합니다: String과 달리 StringBuffer는 변경 가능합니다. StringBuffer에 추가하면 새 객체를 생성하는 대신 기존 버퍼를 수정합니다. 이는 특히 루프에서 또는 연속 작업을 통해 문자열을 작성하는 시나리오에서 메모리 할당 및 가비지 수집과 관련된 오버헤드를 크게 줄입니다.

 
 
그렇다 하더라도 StringBuff 차이로 속도가 100배 차이나는 건 잘 이해가 되지 않네용...
좀 더 고민해보아야 할 것 같습니다

 
+) TIL 같이 하시는 99클럽분들에게  위글을 공유하니 감사하게도 몇 가지 피드백이 올라와서 공유으립니다!