[Programmers] 체육복
ds_chanin
·2019. 10. 1. 01:56
본 게시글은 PC 환경에서 보기 편하도록 설정이 되어 있습니다.
체육복
탐욕법(Greedy)으로 분류 되어 있는 문제입니다.
학생들의 체육복 보유 여부와 빌려줄 수 있는지를 빠르게 계산하는 것이 문제의 핵심이었던 것 같습니다.
저는 이를 int[] studentStatus
를 이용하여 -1, 0, 1로 각각 나타내었습니다.
풀이 스타일
Java와 같은 객체지향 언어를 이용하여 알고리즘을 푼다면 객체지향스럽게 알고리즘을 풀어야 한다고 생각합니다.
단순한 알고리즘 풀이는 가독성은 당연히 떨어지고, Java를 쓰는 이유가 퇴색되는 것 같습니다.
따라서, Java를 이용해서 문제를 푸신다면 객체가 해야할 행동으로 문제를 풀 수 있도록 하시는 것을 추천드립니다.
Student
객체는 체육복을 빌려야하는지 알려주어야하고, 체육복을 빌려줄수 있는 상황인지 알려줄 수 있어야합니다.
따라서 각 객체는 식별자인 index.
체육복을 잃어버렸는지의 여부 값인 lost
체육복을 빌려줄 수 있는지의 여부값인 lendable
을 멤버변수로 가지고 있습니다.
코드
import java.util.ArrayList;
import java.util.List;
class Solution {
public int solution(int n, int[] lost, int[] reserve) {
int[] studentStatus = new int[n + 1];
makeStudentStatus(studentStatus, lost, reserve);
List<Student> students = new ArrayList<>();
makeStudents(students, n, studentStatus);
lendEachOther(students);
return (int) students.stream()
.filter(Student::hasSportsKit)
.count();
}
private void makeStudentStatus(int[] studentStatus, int[] lost, int[] reserve) {
for (int index : lost) {
studentStatus[index]--;
}
for (int index : reserve) {
studentStatus[index]++;
}
}
private void makeStudents(List<Student> students, int n, int[] studentStatus) {
for (int i = 1; i <= n; i++) {
Student student = makeStudent(i, studentStatus[i]);
students.add(student);
}
}
private Student makeStudent(int index, int studentStatus) {
if (studentStatus == -1) {
return Student.makeLostStudent(index);
}
if (studentStatus == 0) {
return Student.makeNormalStudent(index);
}
return Student.makeReserveStudent(index);
}
private void lendEachOther(List<Student> students) {
for (int i = 0; i < students.size() - 1; i++) {
Student producer = students.get(i);
Student consumer = students.get(i + 1);
producer.lendTo(consumer);
consumer.lendTo(producer);
}
}
}
class Student {
private Integer index;
private boolean lost;
private boolean lendable;
public Student(Integer index, boolean lost, boolean lendable) {
this.index = index;
this.lendable = lendable;
this.lost = lost;
}
public static Student makeLostStudent(int index) {
return new Student(index, true, false);
}
public static Student makeReserveStudent(int index) {
return new Student(index, false, true);
}
public static Student makeNormalStudent(int index) {
return new Student(index, false, false);
}
public void lendTo(Student student) {
if (!canLendable()) {
return;
}
if (student.needLend()) {
student.lend();
this.lendable = false;
}
}
private void lend() {
this.lost = false;
}
public boolean hasSportsKit() {
return !this.lost;
}
private boolean needLend() {
return this.lost;
}
private boolean canLendable() {
return this.lendable;
}
}
'스터디 > 알고리즘' 카테고리의 다른 글
[백준] 블랙잭 (0) | 2019.10.10 |
---|---|
[Programmers] 프린터 (0) | 2019.10.02 |
[Programmers] 베스트 앨범 (0) | 2019.09.29 |
[Programmers] 가장 먼 노드 (0) | 2019.09.29 |
[Programmers] 여행경로 (0) | 2019.09.27 |