카테고리 없음

[프로그래머스 - 2018카카오] [1차] 캐시

제이G 2023. 4. 15. 12:30

리뷰

소요시간: 40분

30분정도에 끝낼 수 있었는데, 테스트케이스 2개가 틀려서 디버깅을 조금 진행함.

 

 

문제풀이

제한

  • 캐시크기 C: 0 ~ 30
  • 도시 수 N: 1 ~ 100,000  → O(N)

 

 

유형

Goal: 캐시 크기에 따른 실행시간 측정. 입력된 도시이름 배열을 순서대로 처리할 때의 총 실행시간

* hit = 1, mis = 5, 캐시: LRU

→ 도시들을 한 번씩 순회하며, 캐시 hit/miss에 따른 실행시간을 측정하면 되므로 그냥 구현문제

 

 

설계

1. Cache는 List로 사용
LRU이므로 Queue를 사용할까 했지만, hit된 도시를 최신으로 갱신하기 위해서 remove를 해야하므로 List를 사용

 

2. Cache Hit / Miss 에 따른 구현

 

 

구현

import java.io.*;
import java.util.*;

class Solution {
    private static final int MISS = -1;
    public int solution(int cacheSize, String[] cities) {
        // edge case: cacheSize == 0
        int time = 0;
        if(cacheSize == 0) {
            for(int idx=0; idx<cities.length; idx++) {
                time += 5;
            }
            return time;
        }
        return pro(cacheSize, cities);
    }
    
    private int pro(int cacheSize, String[] cities) {
        //1. 도시이름 소문자로 통일: O(N)
        toLowerCase(cities);
        //2. 총 실행시간 계산
        int time = getTotalTime(cacheSize, cities);
        return time;
    }
    
    private int getTotalTime(int cacheSize, String[] cities) {
        List<String> cache = new LinkedList<>();
        int time = 0;
        
        for(int idx=0; idx<cities.length; idx++) {
            String city = cities[idx];
            // 캐시가 비어있는 경우 -> 캐시에 추가하고 시간갱신
            if(cache.isEmpty()) {
                cache.add(city);
                time += 5;
                continue;
            }
            // 캐시가 있는 경우 -> hit, miss 확인
            // 캐시 hit 확인
            int cachedIdx = checkCacheHit(cache, city);
            if(cachedIdx != MISS) { //캐시 hit이면 캐시를 갱신한다.
                cache.remove(cachedIdx);
                cache.add(city);
                time += 1;
            } else {    //캐시 miss면 캐시를 갱신한다.
                if(cache.size() == cacheSize) {
                    cache.remove(0);
                }
                cache.add(city);
                time += 5;
            }
        }
        return time;
    }
    
    
    // 캐시에 존재하는지 확인
    // return: 캐시가 있으면 해당 idx, 없으면 -1
    private int checkCacheHit(List<String> cache, String city) {
        for(int idx=0; idx<cache.size(); idx++) {
            if(cache.get(idx).equals(city)) {
                return idx;
            }
        }
        return -1;
    }
    
    private void toLowerCase(String[] cities) {
        for(int idx=0; idx<cities.length; idx++) {
            cities[idx] = cities[idx].toLowerCase();
        }
    }
}