티스토리 뷰
2018 하반기 공채 대비 코딩테스트 실전 모의고사 1회
생각
프로그래머스에서 진행한 2018 하반기 공채 대비 코딩테스트 실전 모의고사 1회를 풀어보았다.
총 3개의 문제가 주어지며, 꼬아져있는 문제는 없었다.
1. 팰린드롬(palindrome) 만들기
앞으로 읽을 때와 뒤로 읽을때가 똑같은 단어를 팰린드롬이라고 한다. 두 자연수 n,m이 주어졌을 때 n이상 m이하의 자연수 중 팰린드롬인 숫자의 개수를 return 하여라.
프로그래머스 스타일을 제대로 안 읽은 것일 수도 있지만 백준이나 SW Expert에서 풀때처럼 제한 사항이 적혀있지는 않았다.
▶ 코드를 제출하면 제약 사항을 테스트는 하지만 기준은 모르겠다(못 본걸수도 있다)
m이 최대 50만 까지이므로 n이 1이라고 치면 총 50만개의 숫자를 살펴보면 되므로 반복문은 숫자를 찾는데 필요한 시간 복잡도는 O(N)일 것이며, 팰린드롬을 체크하는데 필요한 반복분은 십만 단위일 경우 6자리이므로 3번만 살펴보면 된다. 따라서 이부분은 아주 조그마하므로 시간 복잡도는 O(N)이라 할 수 있을 것 같다.
▶ 이런 테스트가 처음이라 먼가가 숨겨져 있을 줄 알고 1의 자리 10의 자리 100의자리를 따져가며 규칙을 찾아보려 했지만 잘 보이지 않아서 제한 사항을 알 수는 없었지만 위와 같이 50만이 최대이므로 모든 수를 살펴보면서 풀이를 하였다.
2. 조선소에서 최소한으로 배상비용을 낼 수 있도록 하여라!
일할 수 있는 시간 N과 일이 담긴 works 배열을 준다. 이때, 1시간마다 한 가지 일을 -1씩 처리할 수 있으며 N시간 동안 진행한다. N 시간동안 작업을 진행후 남아있는 일들을 제곱하여 더하였을 때, 최소값을 출력해라.
"모든 문제는 문제를 잘 읽어야 답을 도출 할 수 있다" 라는 사실을 알려주는 문제라 생각한다. 이번 모의고사중 가장 까다로웠던 문제가 아니였나 싶다.
▶ "문제 속에 답이있다" 예제로 주어진 케이스를 보면 작업량이 제일 많을 때를 -1 시키고있다. 어떻게보면 숫자가 클 수록 제곱을 하였을 때, 많이 커지기 때문에 당연히 제일 큰 숫자를 -1 해주는게 맞겠지만 예제가 없었다면 쉽게 떠올랐을까 라는 생각이 든다.
▶ 이제 문제는 다음이다. 배열에서 항상 제일 큰 숫자를 찾아서 -1을 시켜줘야 한다. 처음 시도는 Arrays.sort() 메소드를 통해서 works 배열을 계속 정렬해주어 맨 뒤의 Index의 값을 -1 해주었다.
▶ N이 최대 1,000,000이고 배열의 크기가 최대 1000이므로 위와 같은 시도는 비효율 적일 것이고, 제출했을 때도 효율성 테스트는 0점을 일반 케이스도 몇 개는 실패를 얻었다.
▶ 항상 최대값을 찾아서 -1을 해주고 다시 최대값을 찾는게 관건이므로 PriorityQueue를 사용해서 내림차순 Comparator를 통해 내림차순 정렬하였다.
▶ PriorityQueue는 이진 트리 구조를 가지고 있고, 내림차순 정렬을 통해 최대값이 항상 queue의 꼭 대기에 있으므로 배열 전체를 정리하는 것보다 빠른 결과를 얻을 수 있다.
▶ 이제 문제를 다 풀었다고 생각했었지만(효율성 통과) 일반 케이스에서 2개가 실패를 하였다. 곰곰히 생각해보니 N이 클경우 배열의 값들이 0을 넘어 음의 값으로 갈 수도 있었다. 결과는 제곱을 해서 제출하므로 음의 값을 가질 경우 잘 못된 결과 값을 갖게된다. 따라서 -1을 해주었을 때 0이하가 되면 해당 값을 제거하였다.
*이미 테스트 끝내기를 눌러서 시도해 볼 수는 없지만 맨 처음 한 번만 정렬하고 그 max값을 저장해두고 그 값과 비교해가며 찾는것도 나쁘진 않을 것 같다.*
3. 버스정류장 돌기!
N개의 버스정류장이 주어졌을 때, 각각의 정류장에서 출발해서 각각의 정류장으로 갈 수 있으면 1 그렇지 않으면 0을 가지고 있는 N*N 배열을 return 하여라.
"백준에서 본듯한 문제인데?"라고 생각했었는데 끝나고 예전 글을 보니 이 문제 였다. [백준] 11403번 경로 찾기
문제의 설명을 위의 링크에서 볼 수 있다. 여기서는 피드백만 해보아야겠다.
▶ 이번에 작성한 코드와 비교를 해보니 더 간단해졌나!? 생각이 들었지만 백준은 입력을 받아 출력도 해야했고, 프로그래머스에서는 입력 값을 매개변수를 통해 주고, 출력값도 return으로 배열을 넘겨주면 되니 더 간단해 보였던것 같다.
▶ 확실히 많이 풀어본 사람이 비슷한 문제(이 경우는 똑같은 문제)를 접하였을 때 빨리 풀 수 있는것 같다 실제 시험을 볼 때까지 많이 풀어봐야 겠다.
코드
1)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | class Solution { public int solution(int n, int m) { int answer = 0; int len = 0; boolean flag = true; for(int i=n;i<=m;i++) { String t = i+""; len = t.length(); flag = true; for(int j=0;j<len;j++) { if(t.charAt(j)!=t.charAt(len-j-1)) { flag = false; break; } } if(flag) answer++; } return answer; } } | cs |
2)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | import java.util.Comparator; import java.util.PriorityQueue; class Solution { public int solution(int no, int[] works) { PriorityQueue<Integer> queue = new PriorityQueue<>(new Comparator<Integer>() { @Override public int compare(Integer o1, Integer o2) { return o1<o2?1:o1==o2?0:-1; } }); int len = works.length; for(int i=0;i<len;i++) queue.add(works[i]); int result = 0; for(int i=0;i<no;i++) { if(queue.isEmpty()) break; int t = queue.poll()-1; if(t<=0) { len--; continue; } queue.add(t); } for(int i=0;i<len;i++) { int t = queue.poll(); result += Math.pow(t, 2); } return result; } } | cs |
3)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | class Solution{ int[][] solution(int n, int[][] signs){ int[][] answer = new int[n][n]; for(int i=0;i<n;i++) solve(n,i,i,signs,answer); return answer; } // 경로만 찾으면 되므로 dfs를 이용. private void solve(int n,int first,int next,int[][] signs,int[][] answer) { for(int i=0;i<n;i++) { if(signs[next][i]==0) continue; if(answer[first][i]!=0) continue; answer[first][i] = 1; solve(n,first,i,signs,answer); } } } | cs |
'알고리즘' 카테고리의 다른 글
[프로그래머스] 같은 숫자는 싫어 (0) | 2018.06.10 |
---|---|
[프로그래머스] 가장 긴 팰린드롬 (0) | 2018.06.10 |
[프로그래머스] 가운데 글자 가져오기 (0) | 2018.06.10 |
[프로그래머스] 2016년 (0) | 2018.06.10 |
- Total
- Today
- Yesterday