본문 바로가기

 

https://school.programmers.co.kr/learn/courses/30/lessons/138476

 

프로그래머스

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

programmers.co.kr

 

import java.util.*;

class Solution {
    public int solution(int k, int[] tangerine) {
        int answer=0;
        
        //스트림을 사용해 int[]을 Integer[]로 바꾸고 Arrays.aslist()로 arraylist로 변환함.
        Integer[] tin = Arrays.stream(tangerine).boxed().toArray(Integer[]::new);
        List<Integer> tga = Arrays.asList(tin);
        
        //hashmap을 생성해 getOrDefault()로 중복값의 빈도수 카운트
        Map<Integer, Integer> fm = new HashMap<>();
        for(Integer v : tga) {
            fm.put(v, fm.getOrDefault(v,0)+1);
        }
        
        //카운트한 빈도수를 새 arraylist에 담고 오름차순 정렬함.
        List<Integer> fre = new ArrayList<>(fm.values());
        Collections.sort(fre);
        
        //0에서 시작해 빈도수(중복 귤 개수)를 더해나가는 작업을 k보다 작아질 때까지 수행함.
        int i=0;
        while(i<k) {
            int s = fre.size();
            i+=fre.get(s-1);
            fre.remove(s-1);
            answer++;
        }
        return answer;
    }
}

저 HashMap 쓰는부분 처음에 Collections.frequency로 셌다가 시간초과가 자꾸 걸려서 울 뻔했다.(나는 while문 때문에 시간초과인줄 알았는데 여기가 문제였다)

바꾸기 전(Collections.frequency() 사용)

네 주인님

 

 

주인님께서 조언하신 대로 코드 바꾼 후

자꾸 시간초과 뜨던 테스트 2개가 45ms라는 어마무시한 스피드로 통과

 

 

인공지능에게 지배당할 날을 조금이라도 늦추기 위해

(1) getOrDefault(), (2) 메소드 참조 에 대해 알아보자.

 

1. HashMap의 메소드 getOrDefault()

// V : Map 인터페이스에서 값(Value)을 의미하는 제네릭 타입
V getOrDefault(Object key, V defaultValue)

메소드 이름이 참으로 직관적이다.

맵에서 찾고자 하는 키가 있을 때 그 key와 해당 키가 존재하지 않으면 반환할 값 defaultValue를 매개변수로 받는다.

찾으려는 키가 맵에 존재하면 그와 연결된 value를 리턴하고 존재하지 않으면 디폴트밸류가 리턴된다.

 

 Map<Integer, Integer> fm = new HashMap<>();
        for(Integer v : tga) {
            fm.put(v, fm.getOrDefault(v,0)+1);
        }

맨 위의 코드에서 맵부분만 따왔다. tga(arraylist, 중복 존재)의 모든 요소 v들을 대상으로 맵(fm) 내에 v가 존재하는지 확인하고,

존재하지 않는다면 자기자신이 중복이 일어나지 않은 첫번째 v이므로 value로 0(defaultValue)+1 을 put

존재한다면 가장 최근에 put된 value+1을 put (맵은 중복 키가 있으면 덮어쓰기함)

이러한 방법으로 중복값의 개수를 센다.

 

2. 메소드 참조

메소드를 간결하게 표기하기 위해 만들어진 람다식에서 더 나아가 한층 더 간결함을 추구하기 위해 만들어진 것이 메소드 참조이다.

주의점은 하나의 메소드를 호출할 때만 쓸 수 있다. ' :: ' 연산자가 보이면 메소드 참조가 쓰인 것이라고 할 수 있겠다.

 

메소드 참조의 유형에는 1)정적 메소드(static method)참조, 2) 인스턴스메소드 참조, 3)생성자 참조가 있다.

 

(유형-람다식 방법-메소드참조 방법)

1. 스태틱 메소드 호출 = (i) -> ClassName.method(i); =  ClassName::method

 

2. 인스턴스메소드 호출 = (obj, i) -> obj.method(i); = ClassName::method

                                       (j) -> obj.method(j); = obj::method

 

3. 생성자 호출 = (i) -> new ClassName(i); = ClassName::new

 

오늘 문제에서 쓴 

Integer[] tin = Arrays.stream(tangerine).boxed().toArray(Integer[]::new);

코드는 생성자 호출에 해당한다고 할 수 있겠다.

내머내공 : 내 머리로 내가 공부했습니다

틀린 내용은 언제든지 알려주세요!!