출처: 프로그래머스 코딩 테스트 연습
https://school.programmers.co.kr/learn/courses/30/lessons/77486
1차 시도
public int[] solution(string[] enroll, string[] referral, string[] seller, int[] amount)
{
int[] answer = new int[enroll.Length];
var enrollDict = Enumerable.Range(0, enroll.Length)
.ToDictionary(e => enroll[e], e => referral[e]);
for(int i = 0; i < seller.Length; ++i)
{
string s = seller[i];
int money = amount[i] * 100;
string refer = string.Empty;
while(true)
{
int tenPercent = (int)Math.Floor(money * 0.1);
AddMoney(answer, enroll, s, money - tenPercent); // 자기자신에게 90% 배분
refer = enrollDict[s];
if(refer == "-")
break;
s = refer;
money = tenPercent;
}
}
return answer;
}
void AddMoney(int[] answer, string[] enroll, string owner, int money)
{
int index = Array.IndexOf(enroll, owner);
answer[index] += money;
}
자신에게 90%이득을 남기고, 금액을 다음사람에게 넘기는 방식으로 루프문으로 하면 간단하게 구현이 가능하다.
그런데 재귀로 구현한 것도 아닌데 시간초과 발생.
enroll 길이 10,000 이하 / seller 길이 100,000 이하
최적화가 필요하다.
나의 풀이
public int[] solution(string[] enroll, string[] referral, string[] seller, int[] amount)
{
var enrollDict = Enumerable.Range(0, enroll.Length)
.ToDictionary(e => enroll[e], e => referral[e]);
var moneyDict = Enumerable.Range(0, enroll.Length)
.ToDictionary(e => enroll[e], e => 0);
for(int i = 0; i < seller.Length; ++i)
{
string s = seller[i];
int money = amount[i] * 100;
while(true)
{
int tenPercent = (int)Math.Floor(money * 0.1);
moneyDict[s] += money - tenPercent; // 자기자신에게 90% 배분
if(tenPercent == 0) break;
if(enrollDict[s] == "-") break;
s = enrollDict[s];
money = tenPercent;
}
}
return enroll.Select(e => moneyDict[e]).ToArray();
}
1.
금액을 지급할 때 IndexOf로 위치를 찾는 부분을 Dictionary로 변경하여 최적화하였다.
2.
분배금이 0일때 break를 해주는 부분이 누락되서 추가하였다.
'🛡️ 코딩 테스트' 카테고리의 다른 글
C# 디스크 컨트롤러 - 힙 / 프로그래머스 [Lv.3] (0) | 2023.05.15 |
---|---|
C# 가장 긴 팰린드롬 - 투 포인터 / 프로그래머스 [Lv.3] (0) | 2023.05.14 |
C# 여행경로 - DFS / 프로그래머스 [Lv.3] (1) | 2023.05.11 |
C# 기지국 설치 / 프로그래머스 [Lv.3] (0) | 2023.05.07 |
C# 숫자 게임 - 정렬 / 프로그래머스 [Lv.3] (0) | 2023.05.06 |