1. 기지국 설치
https://programmers.co.kr/learn/courses/30/lessons/12979
Sol 1) 기본형 이용- 정확성: 0.02ms, 효율성: 1.19ms
<hide/>
// 기지국 설치
// https://programmers.co.kr/learn/courses/30/lessons/12979
import java.util.*;
public class T3 {
public static int solution(int n, int[] stations, int w) { // 16, [9], 2
int cnt = 0; // 기지국 개수
int position = 1; // 1동부터 시작
int idx = 0; // stations[] 내의 idx
// 위치의 개념 position
// 등호가 꼭 필요하다.
while(position <= n){
// 기지국 설치 하지 않아도 되는 상황
// 현 위치 position은 station[idx]으로부터 전파가 터지는 상황이다.
if(idx < stations.length && stations[idx] - w <= position){
// position에 2w + 1만큼 온전히 더할 수 없는 상황이니까 position을 변경한다.
position = stations[idx] + w + 1;
++idx;
System.out.println("position: " + position + ", idx: "+ idx);
continue;
}
// 기지국 설치해야하는 상황
++cnt;
position += 2 * w + 1;
System.out.println("position: " + position + ", cnt: " + cnt);
}
return cnt;
}
public static void main(String[] args){
int[] stations = {4, 11};
System.out.println(solution(11, stations, 1)); // 3
stations = new int[]{9};
System.out.println(solution(16, stations, 2)); // 3
stations = new int[]{3, 7, 9};
System.out.println(solution(16, stations, 1)); // 4
}
}
- 그리디(greedy) 알고리즘을 이용한다.
- 루프는 효율성 테스트에서 시간을 많이 잡아 먹는다.
- primitive 타입을 사용하는 게 Objects타입( ex) stack, queue ) 사용 보다 빠르다.
- 그런데 while문에 등호가 빠지면 점수가 깎인다..
Sol 2) Queue 이용 - 정확성: , 효율성:
Sol 3) 제출 답안
<hide/>
class Solution {
public int solution(int n, int[] stations, int w) { // 11, [4, 11] , 1
int left = 0; //기지국 범위 외 왼쪽
int right = 0; //기지국 범위 외 오른쪽
int baseL = 0; //기지국 범위 내 왼쪽
int baseR = 0; //기지국 범위 내 오른쪽
int result = 0;
for(int i = 0; i < stations.length; ++i){
int base = stations[i]; // 4, 11
left = baseR; // 왼쪽 값은 기지국 내의 오른쪽 값, 나중에 개수를 구하기위해 굳이 +1하지않는다.
baseL = base - w;
baseR = base + w; // 너비 w에 따른 기지국의 범위 baseL ~ baseR
if(baseL < 0 ) baseL = 0;
if(baseR > n ) baseR = n; // 배열의 범위를 초과할 때 한정시켜준다.
right = baseL - 1;
if(right < 0) continue;
if(left == right) continue; // 같다면 기지국 사이가 커버 되었을 때이다. ??
if(left > right) continue;
double temp = (double) (right - left) / ((2 * w) + 1);
if(temp % 1 == 0) result += (int) temp; // temp가 정수 일 때
else result += (int) temp + 1;
}
if(baseR != n){ // 모두 처리한 후, baseR은 n이 되어야 한다.
double temp = (double) (n - baseR) / ((2 * w) + 1);
if(temp % 1 == 0) result += (int) temp;
else result += ((int) temp) + 1 ;
}
return result;
}
}
2. 가장 큰 수
Sol)
- 배열
- 숫자로 생각해서 풀지 않고 문자열을 다룬다 생각하고 푼다.
- 숫자 -> 문자 -> 내림차순 정렬 -> 조합
- 정확성 테스트에서 시간 초과되는 경우: 무한 루프가 돌거나 연산이 느린 경우
- 간결한 버전
<hide/>
import java.util.*;
import java.util.stream.*;
// 스트림 사용하기
class Solution {
public String solution(int[] numbers) {
String answer = IntStream.of(numbers)
.mapToObj(String::valueOf)
.sorted((s1, s2) -> (s2 + s1).compareTo(s1 + s2))
.collect(Collectors.joining());
// 숫자를 문자로 바꾼다.
// 정렬된 문자열을 하나의 문자열로 합친다.
// 최종 문자열은 answer
if(answer.startsWith("0")) return "0";
// startsWith로 비교하는 게 더욱 권장된다.
return answer;
}
}
<hide/>
import java.util.*;
class Solution {
public String solution(int[] numbers) {
String[] strNums = new String[numbers.length];
for(int i = 0; i < numbers.length; ++i){
strNums[i] = "" + numbers[i];
}
//strNums에 String이 들어 있기 때문에 s1, s2는 당연히 String
Arrays.sort(strNums, (s1, s2) -> (s2+ s1).compareTo(s1 + s2)); // 내림차순
String answer = "";
for(String s: strNums){
answer += s;
}
if(answer.startsWith("0")) return "0";
// startsWith로 비교하는 게 더욱 권장된다.
return answer;
}
}
- 참고
<hide/>
import java.util.*;
class Solution {
public String solution(int[] numbers) {
String[] strNums = new String[numbers.length];
for(int i = 0; i < numbers.length; ++i){
strNums[i] = "" + numbers[i];
}
Arrays.sort(strNums, new Comparator<String>(){
public int compare(String s1, String s2){
return (s2+ s1).compareTo(s1 + s2);
}
});
String answer = "";
for(String s: strNums){
answer += s;
}
if(answer.charAt(0) == '0') return "0";
return answer;
}
}
3. 예산
Sol)
- 이분법을 이용하기 위해 최솟값, 최댓값을 구한다.
- Stream을 이용하면 간결하게 표현 가능하다.
- final을 붙여야 효율성 테스트를 통과한다.
<hide/>
import java.util.stream.*;
class Solution {
public int solution(int[] budgets, int M) {
int min = 0;
int max = IntStream.of(budgets).max().orElse(0);
int answer = 0;
while(min <= max){
final int mid = (min + max) / 2; // 상한값
int sum = IntStream.of(budgets)
.map(b -> Math.min(b, mid))
.sum();
if(sum <= M){
min = mid + 1; // 상향 조정
answer = mid;
continue;
} // 하향 조정
max = mid - 1;
}
return answer;
}
}
<hide/>
class Solution {
public int solution(int[] budgets, int M) {
int max = 0;
int min = 0;
for(int b : budgets){
if(b > max) max = b;
}
int answer = 0;
while(min <= max){
int mid = (min + max) / 2; // 상한값
int sum = 0;
for(int b : budgets){
if(b > mid) sum += mid;
else sum += b;
}
if(sum <= M){
min = mid + 1; // 상향 조정
answer = mid;
}else{ // 하향 조정
max = mid - 1;
}
}
return answer;
}
}
4. 숫자 게임
Sol)
- 루프를 거꾸로 돌면서 서로 가장 큰 값을 비교한다.
- 단일 루트로 풀면 효율성 테스트 통과
- A와 B를 먼저 정렬시킨 다음에 A와 B에 인덱스를 다르게 준다.
- A[i] < B[index] 를 만족하면 index를 마이너스하고 answer을 플러스한다.
<hide/>
import java.util.*;
class Solution {
public int solution(int[] A, int[] B) {
Arrays.sort(A);
Arrays.sort(B);
int index = B.length - 1;
int answer = 0;
for (int i = A.length -1; i >= 0 ; --i) {
if (A[i] < B[index]) {
--index;
++answer;
}
}
return answer;
}
}
'자료구조와 알고리듬 With Java > [프로그래머스] KDC' 카테고리의 다른 글
[3주차] Coding Test 해시 / BFS / DFS / 동적계획법 (0) | 2022.05.04 |
---|