Skip to content

Latest commit

 

History

History
179 lines (155 loc) · 6.37 KB

week2_20200105_821_tess.md

File metadata and controls

179 lines (155 loc) · 6.37 KB

821. Shortest Distance to a Character

출제자: 테스

Link

  • 출제 이유
    • 다양한 풀이가 나올 수 있는 문제를 내고 싶었다.

Latte

  • Time complexity: O(n)
  • Space complexity: O(1)

처음에 문제를 접했을 때, 딱 떠올랐던 컨셉이 오른쪽으로 원패스로 진행하면서 CPoint 에서 다음 CPoint의 사이 값들만 갱신해주면 된다고 생각했다. 시작하고 나서 첫 CPoint가 나오는 지점까지 기억했다가 해결하기, 새로운 CPoint나오면 이전 값이랑 현재 인덱스 사이에 값들 중에 민 값을 찾아서 해결했다.

최악은 2n 최선은 n이라 일반적인 2n보다 때에 따라 나을 수도 있지만 코드가 복잡하고 한눈에 이해하기 어려운 부분이 아쉬웠다

Kevin

  • Time complexity: O(n)
  • Space complexity: O(1)
  • 음 양옆에 타깃이 어딨는지를 비교해서 더 작은 값을 알아야하니까 어떻게 해야 할까.. 고민하다 보니 그냥 왼쪽으로 한번, 오른쪽으로 한번씩 iterate하면서 더 작은 값을 넣으면 되겠다는 생각이 들었다.
  • 처음엔 왼쪽 오른쪽 iteration한 값들을 따로 array에 저장한 후 최종적으로 더 작은 값으로 합쳐서 return해야할까 싶었는데 생각해보니 그냥 하나의 array에 값을 넣을 때 min 함수에 넣어서 하면 되겠구나 싶어서 따로 공간을 더 쓰지도 않게 되었다.
  • 테쓰가 가져온 솔루션도 이와 같은 방식으로 하였다 하니 괜찮게 푼듯 ^.^

stella

class Solution(object):
    def shortestToChar(self, S, C):
        """
        :type S: str
        :type C: str
        :rtype: List[int]
        """
        forw=[]
        cnt=0
        for i in range(len(S)):
            if S[i]!=C:
                forw.append(cnt)
                cnt+=1
            else:
                forw.append(-1)
                cnt=0
        back=[]
        cnt=0
        for i in range(len(S)-1, -1, -1):
            if S[i]!=C:
                back.append(cnt)
                cnt+=1
            else:
                back.append(-1)
                cnt=0

        ans1=[]
        cnt=10000
        for f in range(len(forw)-1, -1, -1):
            if forw[f]<0:
                ans1.append(0)
                cnt=0
            else:
                cnt+=1
                ans1.append(cnt)

        ans2=[]
        cnt=10000
        for b in range(len(back)-1, -1, -1):
            if back[b]<0:
                    ans2.append(0)
                    cnt=0
            else:
                cnt+=1
                ans2.append(cnt)

        return [min(list(reversed(ans1))[i], ans2[i]) for i in range(len(ans1))]
  • Time complexity : O(n)
  • Space complexity : O(n)
  • 돌아가긴 돌아가지만 풀이가 매우 길고 복잡하다...
  • 쓸데없는 부분이 많다. ans1 과 ans2 를 정리하는 코드에서 결국 target 이 되는 char 만 찾고, forward backward 에서 적었던 숫자들은 활용하지 않기때문에 사실상 forward backward 생성 과정은 필요가 없다.
  • 위의 코드에서 redundant 한 과정들을 제거하고, min 을 backward loop 내에서 미리 구하는 방식을 취하면 아래와 같이 구할 수 있다.
class Solution(object):
    def shortestToChar(self, S, C):
        """
        :type S: str
        :type C: str
        :rtype: List[int]
        """
        cnt=10000
        forward=[]
        for i in range(len(S)):
            if S[i]==C:
                cnt=0
            else:
                cnt+=1
            forward.append(cnt)
        cnt=10000    
        ans=[]
        for i in range(len(S)-1, -1, -1):
            if S[i]==C:
                cnt=0
            else:
                cnt+=1
            ans.append(min(forward[i], cnt))
        return list(reversed(ans))
  • 코드작성 전에 풀이과정을 다시한번 생각해보고 쓸데없는 과정은 없는지 잘 확인할 필요가 있을 것 같다.

Damian

  • Time complexity: O(n^2)
  • Space complexity: O(n)
  • 시간 안에 더 나은 방법을 생각해내지 못 해서 Brute Force에 가깝게 풀었다. 돌아가긴 하지만 좋은 점수를 얻긴 힘들 풀이이다. 자료구조를 거꾸로 순회한다는 생각을 잘 하지 못 하는 것 같다. 뭔가 틀에 갇혀있는 것 같은 느낌이다. 다양한 유형의 문제를 많이 풀어봐야겠다.
  • 처음엔 Latte의 풀이처럼 인덱스를 세밀하게 다뤄 최적화하는 방법을 처음에 고민했는데 실패할 것 같아 풀이로 옮기지 못 했다. 이 부분은 많은 연습이 필요할 것 같다.
// 수정된 풀이
public int[] shortestToChar(String S, char C) {        
    int[] answer = new int[S.length()];
    int currentCIndex = -1;
    
    for (int i = 0; i < S.length(); i++) {
        if (S.charAt(i) == C) {
            currentCIndex = i;
            answer[i] = 0;
        } else {
            if (currentCIndex != -1) {
                answer[i] = i - currentCIndex;
            } else {
                answer[i] = Integer.MAX_VALUE;
            }                
        }
    }
    
    currentCIndex = -1;
    for (int i = S.length() - 1; i >= 0; i--) {
        if (S.charAt(i) == C) {
            currentCIndex = i;        
        } else {
            if (currentCIndex != -1) {
                answer[i] = Math.min(answer[i], currentCIndex - i);
            }
        }
    }

    return answer;
}

Tess

class Solution(object):
    def shortestToChar(self, S, C):
        prev = float('-inf') # 1e9 보다 빠르다.
        ans = []
        for i, x in enumerate(S):
            if x == C:
                prev = i
            ans += [i - prev] #

        prev = float('inf') # 뒤에서 C가 없는 경우를 대비해서 inf로 해야한다.
        for i in range(len(S) - 1, -1, -1):
            if S[i] == C:
                prev = i
            ans[i] = min(ans[i], prev - i)

        return ans
  • Time complexity: O(n)
  • Space complexity: O(1)
  • 이 문제를 풀면서 python 에서는 append보다 그리고 1e9로 설정하는거보다 += [] 와 float('inf')로 대체하는게 시간복잡도면에서 다르다는 것을 알게되었다.