[Level 2] 단체사진 찍기 (Java)
프로그래머스의 Level2 문제인 단체사진 찍기를 풀었다. 나같은 경우 해당 문제를 아래와 같이 풀었었다.
- 알파벳 8자리에서 나올 수 있는 모든 경우의 수를 모두 구한다. (8! = 40320)
- 구한 경우의 수들을 조건에 맞는지 확인 후 조건에 만족할 경우 +1 해준다.
import java.util.*;
public class 단체사진_찍기 {
public static void main(String[] args) {
int n = 0;
// String[] data = {
// "N~F=0",
// "R~T>2"
// };
String[] data = {
"M~C<2",
"C~M>1"
};
System.out.println(solution(n, data));
}
static char[] friendsAlphabet = new char[] { 'A', 'C', 'F', 'J', 'M', 'N', 'R', 'T' };
public static int solution(int n, String[] data){
int answer = 0;
createAllFriendsRow(0);
for (String cs : createFriendsRowList) {
if (checkCondition(cs, data)){
answer++;
}
}
return answer;
}
static boolean[] visited = new boolean[8];
static List<String> createFriendsRowList = new ArrayList<String>();
static char[] createFriendsRowArray = new char[8];
public static void createAllFriendsRow(int index){
if (index == visited.length){
createFriendsRowList.add(String.valueOf(createFriendsRowArray));
}
else{
for(int i=0; i<visited.length; i++){
if (!visited[i]){
visited[i] = true;
createFriendsRowArray[index] = friendsAlphabet[i];
createAllFriendsRow(index + 1);
visited[i] = false;
}
}
}
}
public static boolean checkCondition(String friendsArray, String[] data){
String[] splits;
String startFriend, endFriend;
String condition;
int conditionCount = 0;
int gap;
int indexGap = 0;
int endIndex, startIndex;
for (String c : data) {
splits = c.split("");
startFriend = splits[0];
endFriend = splits[2];
condition = splits[3];
gap = Integer.parseInt(splits[4]);
startIndex = friendsArray.indexOf(startFriend);
endIndex = friendsArray.indexOf(endFriend);
indexGap = Math.abs(endIndex - startIndex) - 1;
switch (condition) {
case "=":
if (indexGap != gap){
return false;
}
conditionCount++;
break;
case ">":
if (indexGap <= gap){
return false;
}
conditionCount++;
break;
case "<":
if (indexGap >= gap){
return false;
}
conditionCount++;
break;
}
}
if (conditionCount == data.length){
return true;
}
else{
return false;
}
}
}
그 결과...
8.6초라는 어마어마한 성능을 가지고 있었다;
8! 만큼 2번 (프렌즈의 모든 경우의 수 구할 때, 조건에 맞는지 구할 때)을 돌아서 성능이 저렇게 나온건지 해서 아래와 같이 수정했었다.
- 모든 경우의 수를 구함과 동시에 조건에 맞는지 확인한다.
- 조건에 맞다면 +1 해준다.
위와 같이 작성해봐도 동일하게 8초 이상이 출력되었다. 그래서 다시 확인한 결과 checkCondition 함수에서 split 메소드로 문자열을 자르는 부분이 있었는데, 이 부분을 split 대신 charAt 메소드를 사용하여 구현해 보았다.
class Solution {
char[] friendsAlphabet = new char[] { 'A', 'C', 'F', 'J', 'M', 'N', 'R', 'T' };
public int solution(int n, String[] data){
int answer = 0;
createAllFriendsRow(0, data);
answer = correctCount;
return answer;
}
boolean[] visited = new boolean[8];
char[] createFriendsRowArray = new char[8];
int correctCount = 0;
public void createAllFriendsRow(int index, String[] data){
if (index == visited.length){
if (checkCondition(String.valueOf(createFriendsRowArray), data)){
correctCount++;
}
}
else{
for(int i=0; i<visited.length; i++){
if (!visited[i]){
visited[i] = true;
createFriendsRowArray[index] = friendsAlphabet[i];
createAllFriendsRow(index + 1, data);
visited[i] = false;
}
}
}
}
public boolean checkCondition(String friendsArray, String[] data){
char startFriend, endFriend;
char condition;
int conditionCount = 0;
int gap;
int indexGap = 0;
int endIndex, startIndex;
for (String c : data) {
startFriend = c.charAt(0);
endFriend = c.charAt(2);
condition = c.charAt(3);
gap = c.charAt(4) - '0';
startIndex = friendsArray.indexOf(startFriend);
endIndex = friendsArray.indexOf(endFriend);
indexGap = Math.abs(endIndex - startIndex) - 1;
switch (condition) {
case '=':
if (indexGap != gap){
return false;
}
conditionCount++;
break;
case '>':
if (indexGap <= gap){
return false;
}
conditionCount++;
break;
case '<':
if (indexGap >= gap){
return false;
}
conditionCount++;
break;
}
}
if (conditionCount == data.length){
return true;
}
else{
return false;
}
}
}
위와 같이 작성 한 후 다시 제출했더니 아래와 같은 결과가 나왔다.
속도와 메모리가 9배 이상 차이가 남을 확인할 수 있었다.
결론.
- split 대신 charAt을 사용할 수 있는 경우 charAt을 사용하는 것이 성능상에 유리하다.
'0x20. 알고리즘 > 0x22. 프로그래머스' 카테고리의 다른 글
[Level 2] 전화번호 목록 (0) | 2021.09.28 |
---|---|
[Level 2] 124 나라의 숫자 (0) | 2021.09.16 |
[Level 2] 멀쩡한 사각형 (0) | 2021.09.15 |
프로그래머스 Level 1 문제풀이 리스트 (0) | 2021.09.06 |
[Level 1] 완주하지 못한 선수 (Java) (0) | 2021.08.01 |