https://leetcode.com/problems/replace-elements-with-greatest-element-on-right-side/

 

 

arr 가 주어진다.

arr 를 index i를 이용하여 순회한다.

순회하면서 i 이후의 값 중에 최대값을 i에 넣는다.

마지막은 -1 이어야 한다.

 

세 가지 방법이 있고, 마지막 방법이 제일 나은 방법이다.

 

 

 

 

1. 2중 for문 이용하는 방법

 

바로 생각나는 2중 for문 알고리즘이다.

 

class Solution {
    public int[] replaceElements(int[] arr) {
        int last = arr.length-1;
        for(int i=0; i<last; i++){
            arr[i]=findMax(i+1, arr);
        }
        arr[last]=-1;
        return arr;
    }
    
    public int findMax(int i, int[] arr){
        int size = arr.length;
        int max = -1;
        for(;i<size; i++){
            if(max<arr[i]) max=arr[i];
        }
        return max;
    }
}

 

시간이 172ms 걸린다.

무지하게 많이 걸리지만 통과는 된다.

하지만 이게 답이 아니라는 걸 말 하지 않아도 알고 있다.

 

 

 

 

 

2. TreeMap 을 이용하는 방법

 

TreeMap(혹은 TreeSet)을 이용하게 되면, 넣는 족족 정렬이 된다.

정말 편하디 편한 자료구조가 아닐 수 없다.

넣는 시간(logN)과 재정렬하는 시간(logN)을 제외하고 최대값을 가져오는 last 는 O(1) 시간을 갖는다.

 

class Solution {
    public int[] replaceElements(int[] arr) {
       	TreeMap<Integer,Integer> map = new TreeMap<>();
		for(int key : arr){
			int value = 1;
			if(map.containsKey(key)) value = map.get(key)+1;
			map.put(key, value);
	    }
		
	    int size = arr.length;
	    for(int i=0; i<size-1; i++){
	        int key = arr[i];
	        int value = map.get(key);
	        if(value==1) map.remove(key);
	        else map.put(key, value-1);
	        arr[i]=map.lastKey();
	    }
        arr[size-1]=-1;
        return arr;
    }
}

 

map 에 arr 의 값을 키로 두고, 그 키 값의 횟수를 value 로 둔다.

arr 를 순회하는 동안 arr의 index i 값을 map 에서 하나 줄인다.

만약 map 의 i 값이 1 이라면 map 자체에서 지워버린다.

그 후 남아있는 map 의 key 중에서 last 를 이용하여 최댓값을 가져온다.

그 가져온 최댓값을 arr 의 index i 자리에 넣는다.

 

이거 나름대로 괜찮다고 생각했다.

시간도 36ms 밖에 걸리지 않는데.. 그 보다 더 나은 방법이 아래 있다.

 

 

 

 

3. 마지막 max 를 유지하는 방법

 

위의 코드처럼 TreeMap 등을 써서 max 값을 따로 계산 할 필요 없이,

그냥 arr 를 뒤에서 순회해가면서 최댓값을 유지하면 된다.

발상은 "index i 이후의 값 중에 최대값"이라는 문장에서 나온다.

 

class Solution {
    public int[] replaceElements(int[] arr) {
        int max = -1;
        for(int i=arr.length-1; i>=0; i--){
            int v = arr[i];
            arr[i]=max;
            max = Math.max(v,max);
        }
        return arr;
    }
}

 

arr 를 뒤에서 순회해간다.

arr 의 index i 값을 일단 변수 v로 백업해두고,

내가 유지하고 있는 max 값을 arr 의 index i 자리에 넣는다.

그 후 max 값을 백업한 v와 현재 갖고 있는 max 값 둘 중 큰 값으로 교체한다.

 

 

이렇게 짧아도 제 역할에 충실한 코드가 세상에 또 있을까.

콜럼버스의 달걀 저리가라다.

 

 

 

'Coding Interview' 카테고리의 다른 글

[leetcode] Last Stone Weight  (0) 2020.02.11
[leetcode] Single Number  (0) 2020.02.11
Longest Increasing Subsequence 알고리즘  (0) 2020.02.02
[Baekjoon] 2156번 포도주 시식  (0) 2020.01.30
[Baekjoon] 11727번 2×n 타일링 2  (0) 2020.01.27

+ Recent posts