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

 

프로그래머스

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

programmers.co.kr

 

이번 문제는 링크드리스트를 활용하여 트리를 만들어 계산을 하면되는 문제입니다.

 

기억해야할점들

 

첫번째. 이 문제 같은경우 child에서 parent로 올라가는 경우만 고려합니다.

문제를 보면 child에서 어떤 물건을 구매하고 하나씩 prev를 거쳐가며 parent까지 가는 방식으로 양방향 노드를 사용할 필요가 없습니다.

 

두번째, 각 노드의 객체정보를 알기 위하여 HashMap을 사용하여 편하게 알아냅니다.

 

세번째, Calculate(int amount) 함수에서 amount < 10 인경우(원 단위에서 절사하는 경우)를 갈라주면 최대 10배이상 빨라집니다.

 

코드입니다.

class Solution {
public Node center = new Node("-");
public HashMap<String, Node> hashmap = new HashMap<String, Node>();
public int[] solution(String[] enroll, String[] referral, String[] seller, int[] amount) {
int[] answer = new int[enroll.length];
//각 노드들의 위치를 쉽게 연결하기 위하여 HashMap을 통해서 관리합니다.
hashmap.put("-", center);
//각 판매원의 이름을 담은 배열 enroll을 통하여, referall과 함꼐 Parent를 연결시킵니다.
for(int i=0;i<enroll.length;i++){
String enrolltemp = enroll[i];
String referraltemp = referral[i];
//판매원의 이름으로 node를 생성
Node node = new Node(enrolltemp);
hashmap.put(enrolltemp, node);
//판매원을 다단계 조직에 참여시킨 다른 판매원의 이름, node의 parent로 넣습니다.
//굳이 양방향으로 할필요 없으므로 자식에서 prev만 연결시킵니다.
//항상 parent가 먼저 입력되므로 hashmap.get을 사용하면 바로 알수 있습니다.
Node prev = (Node) hashmap.get(referraltemp);
node.prev = prev;
}
for(int i=0;i<seller.length;i++){
String sellertemp = seller[i];
int amounttemp = amount[i]*100;
Node sellernode = hashmap.get(sellertemp);
sellernode.calculate(amounttemp);
}
for(int i=0;i<enroll.length;i++){
answer[i] = hashmap.get(enroll[i]).money;
}
// for(Entry <String, Node> entrySet : hashmap.entrySet()){
// System.out.println(" "+entrySet.getKey() + " "+entrySet.getValue().name);
// }
return answer;
}
}
class Node{
String name=null;
Node prev;
int money=0;
public Node(){
}
public Node(String name){
this.name = name;
}
public void calculate(int amount){
//재귀를 사용
int moneytoParent = amount / 10;
this.money += amount - moneytoParent;
if(this.prev != null)
this.prev.calculate(moneytoParent);
//일반 코드
// Node now = this;
// while(now != null){
// int moneytoParent = amount / 10;
// if(amount < 10){
// now.money += amount;
// return ;
// }
// now.money += amount - moneytoParent;
// amount = moneytoParent;
// now = now.prev;
// if(now.prev == null){
// return ;
// }
// }
//가장 빠른 코드, if amount < 10 이면 바로끝내서 제일 빠른듯합니다.
// Node now = this;
// while(now != null){
// if(amount < 10){
// now.money += amount;
// return ;
// }
// int movemoney = amount/10;
// amount -= amount / 10;
// now.money += amount;
// amount = movemoney;
// now = now.prev;
// if(now.prev == null){
// return ;
// }
// }
return ;
}
}

 

HashMap으로 푼경우, 조회가 훨씬 빠르기에 속도가 현저히 줄어듭니다. 

import java.util.Map.*;
import java.util.*;
class Solution {
HashMap<String, Node> hashmap= new HashMap<String, Node>();
Node root = new Node();
public int[] solution(String[] enroll, String[] referral, String[] seller, int[] amount) {
int[] answer = {};
for(int i=0;i<enroll.length;i++){
Node temp = new Node();
hashmap.put(enroll[i], temp);
}
for(int i=0;i<referral.length;i++){
String parent = referral[i];
if(parent.equals("-")){
Node temp = hashmap.get(enroll[i]);
temp.parent = root;
}
else{
Node temp = hashmap.get(enroll[i]);
temp.parent = hashmap.get(parent);
}
}
for(int i=0;i<seller.length;i++){
String seller_value = seller[i];
int money = amount[i] * 100;
Node temp = hashmap.get(seller_value);
while(true){
if(money < 10 || temp == root){
temp.money += money;
break;
}
int distributemoney = (int)Math.ceil(money * 0.9);
temp.money += distributemoney;
money = money - distributemoney;
if(temp == root)
break;
temp = temp.parent;
}
}
answer = new int[enroll.length];
for(int i=0;i<answer.length;i++){
answer[i] = hashmap.get(enroll[i]).money;
}
// System.out.print(root.money);
// for (Entry<String, Node> entry : hashmap.entrySet()) {
// System.out.print("[key]:" + entry.getKey() + ", [value]:" + entry.getValue().money);
// }
return answer;
}
class Node{
Node parent =null;
int money = 0;
public Node(){
}
}
}

 

새로 풀어봤을떄, HashMap으로 풀려했지만, 더빠르게 풀기위해 ArrayList로 바로 풀어봤습니다.

import java.util.*;
class Solution {
ArrayList<Node> graph = new ArrayList<Node>();
Node root = new Node();
int[] answer = {};
public int[] solution(String[] enroll, String[] referral, String[] seller, int[] amount) {
root.name="-";
for(int i=0;i<enroll.length;i++){
String name = enroll[i];
Node temp = new Node();
temp.name = name;
graph.add(temp);
}
for(int i=0; i<referral.length;i++){
String referral_name = referral[i];
if(referral_name.equals("-")){
graph.get(i).parent = root;
}else{
for(int j=0;j<graph.size();j++){
if(referral_name.equals(graph.get(j).name)){
graph.get(i).parent = graph.get(j);
}
}
}
}
for(int i=0;i<seller.length;i++){
String name = seller[i];
int count = amount[i] * 100;
for(int j=0;j<graph.size();j++){
if(name.equals(graph.get(j).name)){
Node temp = graph.get(j);
while(true){
if(count < 10 || temp == root){
temp.money += count;
break;
}
int distribute = (int)Math.ceil(count * 0.9);
temp.money += distribute;
count = count - distribute;
temp = temp.parent;
}
}
}
}
System.out.print("root:"+root.money);
for(int k=0;k<graph.size();k++){
System.out.print(" "+graph.get(k).money);
}
System.out.println();
// System.out.println(root.money);
answer = new int[graph.size()];
for(int i=0;i<graph.size();i++){
answer[i] = graph.get(i).money;
}
return answer;
}
class Node{
String name;
Node parent=null;
int money = 0;
public Node(){
}
}
}

+ Recent posts