There are n children standing in a line. Each child is assigned a rating value given in the integer array ratings.
You are giving candies to these children subjected to the following requirements:
Return the minimum number of candies you need to have to distribute the candies to the children.
ratings
rating
이 높은 경우, 그 아이보다 더 많은 사탕을 받아야 한다.rating
이 작거나 같으면 1개만 받아도 된다.rating
이라면, 캔디를 N개 받는 대상자가 된다.class Solution {
public int candy(int[] ratings) {
if (ratings.length == 1) {
return 1;
}
int[] candies = new int[ratings.length]; // 각 사람 별 줄 캔디 수
int countOfCandy = 1; // 대상자가 받을 캔디 개수
Set<Integer> indexes = new HashSet<>(); // 대상자 위치
// 캔디 1개 받을 사람들 지정
if (ratings[0] <= ratings[1]) {
indexes.add(0);
candies[0] = countOfCandy;
}
if (ratings[ratings.length - 1] <= ratings[ratings.length - 2]) {
indexes.add(ratings.length - 1);
candies[ratings.length - 1] = countOfCandy;
}
for (int i = 1; i <= ratings.length - 2; i++) {
if (ratings[i] <= ratings[i - 1] && ratings[i] <= ratings[i + 1]) {
indexes.add(i);
candies[i] = countOfCandy;
}
}
// 캔디 2개 이상 받을 사람들
while (indexes.size() != 0) {
countOfCandy++;
Set<Integer> newIndexes = new HashSet<>();
for (int index : indexes) {
if (index != 0 && ratings[index-1] > ratings[index]) {
newIndexes.add(index-1);
candies[index-1] = countOfCandy;
}
if (index != ratings.length-1 && ratings[index + 1] > ratings[index]) {
newIndexes.add(index+1);
candies[index+1] = countOfCandy;
}
}
indexes = newIndexes;
}
// 총 캔디 수 계산
int totalCandy = 0;
for (int candy : candies) {
totalCandy += candy;
}
return totalCandy;
}
}
양 옆에 있는 사람들의 사탕 받는 개수를 통해 자신이 받을 개수를 정함
rating
이 적거나 같은 경우rating
이 높은 경우rating
이 높은 경우rating
이 적은 애보다 1개 더 받음구현 고려 사항
People
객체 생성class Solution {
public int candy(int[] ratings) {
List<People> peoples = Arrays.stream(ratings)
.mapToObj(People::new)
.collect(Collectors.toList());
for (int i = 0; i < peoples.size() - 1; i++) {
peoples.get(i).setRight(peoples.get(i + 1));
}
for (int i = 1; i < peoples.size(); i++) {
peoples.get(i).setLeft(peoples.get(i - 1));
}
return peoples.stream().mapToInt(People::getCandy)
.sum();
}
class People {
private final int rate;
private People left;
private People right;
private Integer candy;
People(int rate) {
this.rate = rate;
}
public void setLeft(People left) {
this.left = left;
}
public void setRight(People right) {
this.right = right;
}
public int getCandy() {
if (candy != null) {
return candy;
}
if (isMoreThanLeft() && isMoreThanRight()) {
candy = Math.max(left.getCandy(), right.getCandy()) + 1;
return candy;
}
if (!isMoreThanLeft() && !isMoreThanRight()) {
candy = 1;
return candy;
}
if (isMoreThanLeft() && !isMoreThanRight()) {
candy = left.getCandy() + 1;
return candy;
}
if (!isMoreThanLeft() && isMoreThanRight()) {
candy = right.getCandy() + 1;
return candy;
}
return candy;
}
private boolean isMoreThanLeft() {
if (left == null) {
return false;
}
return this.rate > left.rate;
}
private boolean isMoreThanRight() {
if (right == null) {
return false;
}
return this.rate > right.rate;
}
}
}
1번 방법의 경우
2번 방법의 경우
rating
마다 People
객체를 생성해야 하기 때문에 상대적으로 비용이 많이 들어간다.candies
설정 (기본값 : 1)rating
보다 크다면, 이전에 받은 캔디보다 1개 더 많이 받도록 설정rating
보다 크다면, 기존 값과 (이전에 받은 캔디) + 1 중에 큰 값으로 설정한다.class Solution {
public int candy(int[] ratings) {
int[] candies = new int[ratings.length];
for (int i = 0; i < candies.length; i++) {
candies[i] = 1;
}
for (int i = 0; i < ratings.length - 1; i++) {
if (ratings[i + 1] > ratings[i]) {
candies[i + 1] = candies[i] + 1;
}
}
for (int i = ratings.length - 1; i > 0; i--) {
if (ratings[i - 1] > ratings[i]) {
candies[i - 1] = Math.max(candies[i] + 1, candies[i - 1]);;
}
}
int sum = 0;
for (int i = 0; i < candies.length; i++) {
sum += candies[i];
}
return sum;
}
}