문제

https://programmers.co.kr/learn/courses/30/lessons/42883?language=java


코드

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public String solution(String number, int k) {
char[] toCharArray = number.toCharArray();

StringBuilder answer = new StringBuilder();

int idx = 0;
for(int i = 0; i < number.length() - k; i++) {
int max = 0;

for(int j = idx; j <= k + i; j++) {
int ch = toCharArray[j] - '0';
if(max < ch) {
max = ch;
idx = j + 1;
}
}

answer.append(max);
}

return answer.toString();
}

흐름

  1. 문자열에서 k 만큼 빼야하니 당연히 문자열 length - k 만큼 반복
  2. 가장 큰 수의 인덱스를 구해서 그 인덱스부터 한 칸씩 밀려야 하니 k + i 한 값 까지 반복
  3. 가장 큰 수의 인덱스부터 반복해야하니 범위 내에서 가장 큰 수를 구해서 그 수의 인덱스를 저장하고 여기서 구한 인덱스를 2번에서 사용
  4. 가장 큰 수를 저장하고 반복이 끝나면 리턴

테스트 케이스

1
2
3
4
5
6
7
assertEquals("23", test.solution("123", 2));
assertEquals("34", test.solution("1234", 2));
assertEquals("94", test.solution("1924", 2));
assertEquals("3234", test.solution("1231234", 3));
assertEquals("775841", test.solution("4177252841", 4));
assertEquals("9", test.solution("9999999999", 9));
assertEquals("93231357719", test.solution("9312131357719", 5));

참고 사이트

댓글 공유

문제

https://programmers.co.kr/learn/courses/30/lessons/42578


코드

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public int solution(String[][] clothes) {
Map<String, Integer> map = new HashMap<String, Integer>();

for (String[] s : clothes) {
int value = 1;
String key = s[1];
if (map.containsKey(key)) {
value = map.get(key);
}

map.put(key, ++value);
}

int answer = 1;
for (Map.Entry<String, Integer> entry : map.entrySet()) {
answer *= entry.getValue();
}

return answer - 1;
}

흐름

  1. [[“yellow_hat”, “headgear”], [“blue_sunglasses”, “eyewear”], [“green_turban”, “headgear”]], clothes안에 이런 식으로 옷이름, 종류 로 저장되어 있으므로 chothes 크기 만큼 반복하면서 옷 종류를 꺼냄

  2. 옷 종류를 key로 하는 Map이 있는 지 확인

  3. 있으면 값을 증겨 시켜야 하므로 value를 꺼내옴

  4. ++해서 값을 증가 시켜서 저장하고, 없으면 해당 key로 새로 저장

  5. 순열과 조합 공식을 바탕으로 value를 모두 곱함

  6. 문제에서 최소 1 개의 옷은 입는다고 하였으므로, 옷을 모두 안입는 경우를 제외하기 위해 -1을 함

조합 공식

Every interaction is both precious and an opportunity to delight.

서로 다른 n개의 원소에서 순서에 상관없이 r개를 뽑을 때, 이를 n개에서 r개를 택하는 조합이라고 한다. 이 조합은 순열과 다른 개념으로 순서 차이가 중요하다.

$$ nCr = nPr / r! = n! / (n-r)!r! $$

  • 이 공식으로 위 문제를 풀어보면 헤어 2개, 안경 1개 이므로
  • 헤어 2개에서는 입을경우, 안 입을 경우 2 가지이고 이를 수식으로 표현하면
  • 0개를 뽑는 경우 = $$ 2C0 = 2P0 / 0! = 2! / (2-0)!0! = 2 / 2 = 1 $$
  • 이 되고, 나머지의 경우도 계산하면 $$ 1 + 2 = 3 $$ 이 된다.
  • 안경도 마찬가지로 입을 경우, 안 입을 경우 2 가지로
  • $$ 1C0 + 1C1 = 1 + 1 = 2 $$ 가 되고
  • 마지막으로 둘 다 안 입는 경우는 없으므로 -1을 하면
  • $$ 3 * 2 - 1 = 5 $$가 된다

다른 분의 코드

1
2
3
4
5
6
7
public int solution(String[][] clothes) {
return Arrays.stream(clothes)
.collect(groupingBy(p -> p[1], mapping(p -> p[0], counting())))
.values()
.stream()
.collect(reducing(1L, (x, y) -> x * (y + 1))).intValue() - 1;
}
  • 람다식 대박

결과

1번

번호 속도
테스트 1 통과 (0.93ms, 50.5MB)
테스트 2 통과 (0.85ms, 51.9MB)
테스트 3 통과 (0.86ms, 51.9MB)
테스트 4 통과 (0.93ms, 52.8MB)
테스트 5 통과 (0.80ms, 52MB)
테스트 6 통과 (0.88ms, 50.5MB)
테스트 7 통과 (0.84ms, 52.2MB)
테스트 8 통과 (0.85ms, 52.8MB)
테스트 9 통과 (0.86ms, 51.9MB)
테스트 10 통과 (0.87ms, 52.2MB)
테스트 11 통과 (0.89ms, 52.4MB)
테스트 12 통과 (0.82ms, 51.9MB)
테스트 13 통과 (0.81ms, 52.3MB)
테스트 14 통과 (0.75ms, 51.9MB)
테스트 15 통과 (0.82ms, 50.5MB)
테스트 16 통과 (0.91ms, 50.5MB)
테스트 17 통과 (0.90ms, 52.5MB)
테스트 18 통과 (0.88ms, 52.1MB)
테스트 19 통과 (0.88ms, 51.8MB)
테스트 20 통과 (0.90ms, 52.4MB)
테스트 21 통과 (0.80ms, 52.9MB)
테스트 22 통과 (0.86ms, 51.6MB)
테스트 23 통과 (0.80ms, 50.7MB)
테스트 24 통과 (0.90ms, 50.3MB)
테스트 25 통과 (0.90ms, 52.3MB)
테스트 26 통과 (0.93ms, 52.1MB)
테스트 27 통과 (0.86ms, 52.3MB)
테스트 28 통과 (0.90ms, 50.1MB)

2번

번호 속도
테스트 1 통과 (14.41ms, 53.2MB)
테스트 2 통과 (12.19ms, 52.8MB)
테스트 3 통과 (12.05ms, 52.9MB)
테스트 4 통과 (13.03ms, 50.9MB)
테스트 5 통과 (14.21ms, 50.9MB)
테스트 6 통과 (12.85ms, 51MB)
테스트 7 통과 (13.19ms, 50.9MB)
테스트 8 통과 (13.32ms, 53.6MB)
테스트 9 통과 (13.37ms, 53.1MB)
테스트 10 통과 (12.58ms, 53.2MB)
테스트 11 통과 (12.34ms, 52.7MB)
테스트 12 통과 (13.69ms, 52.4MB)
테스트 13 통과 (13.19ms, 52.7MB)
테스트 14 통과 (12.48ms, 51.1MB)
테스트 15 통과 (11.82ms, 52.5MB)
테스트 16 통과 (12.63ms, 52.7MB)
테스트 17 통과 (13.37ms, 53.1MB)
테스트 18 통과 (13.54ms, 53.1MB)
테스트 19 통과 (13.20ms, 50.7MB)
테스트 20 통과 (13.11ms, 52.7MB)
테스트 21 통과 (12.80ms, 52.6MB)
테스트 22 통과 (13.48ms, 53.2MB)
테스트 23 통과 (12.59ms, 52.5MB)
테스트 24 통과 (13.71ms, 50.9MB)
테스트 25 통과 (12.94ms, 52.4MB)
테스트 26 통과 (13.67ms, 50.9MB)
테스트 27 통과 (13.75ms, 53MB)
테스트 28 통과 (13.04ms, 51.7MB)

테스트 케이스

1
2
assertEquals(5, test.solution(new String[][] {{"yellow_hat", "headgear"}, {"blue_sunglasses", "eyewear"}, {"green_turban", "headgear"}}));
assertEquals(3, test.solution(new String[][] {{"crow_mask", "face"}, {"blue_sunglasses", "face"}, {"green_turban", "face"}}));

참고 사이트

댓글 공유

문제

https://programmers.co.kr/learn/courses/30/lessons/42577


코드

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public boolean solution(String[] phone_book) {
int length = phone_book.length;

for (int i = 0; i < length; i++) {
for (int j = 0; j < length; j++) {
if (i == j) {
continue;
}

if (phone_book[j].startsWith(phone_book[i])) {
return false;
}
}
}
boolean answer = true;
return answer;
}

흐름

  1. 배열을 전부 돌면서 해당 인덱스로 시장하는 단어가 있는 지 확인함


결과

번호 속도
테스트 1 통과 (0.78ms, 52.1MB)
테스트 2 통과 (0.52ms, 50.1MB)
테스트 3 통과 (0.65ms, 52.6MB)
테스트 4 통과 (0.51ms, 54.6MB)
테스트 5 통과 (0.55ms, 52.2MB)
테스트 6 통과 (0.66ms, 52.5MB)
테스트 7 통과 (0.87ms, 50.3MB)
테스트 8 통과 (0.77ms, 52.8MB)
테스트 9 통과 (0.64ms, 52.3MB)
테스트 10 통과 (0.57ms, 50.3MB)
테스트 11 통과 (0.65ms, 52.8MB)
  • 효율성 테스트
번호 속도
테스트 1 통과 (1.96ms, 60.3MB)
테스트 2 통과 (2.14ms, 59.8MB)

테스트 케이스

1
2
3
assertFalse(test.solution(new String[] {"119", "97674223", "1195524421"} ));
assertTrue(test.solution(new String[] {"123","456","789"} ));
assertFalse(test.solution(new String[] {"12","123","1235","567","88"} ));

여담

  • 사실 당연히 시간 초과로 안될 줄 알았는데 넘어가서 놀랐다.
  • 찾아보니 Trie 자료구조로 해결하길 바래서 카테고리가 해쉬 인 듯 싶다.
  • 하지만 쉽게 풀 수 있는 문제를 어렵게 풀 이유가 없으니 이 문제는 이렇게 마무리 하려한다.

댓글 공유

문제

https://programmers.co.kr/learn/courses/30/lessons/42747?language=java


코드

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public int solution(int[] citations) {
int answer = 0;
int n = citations.length;

Arrays.sort(citations);

for (int i = 0; i <= citations[n - 1]; i++) {
int high = 0;

for (int j = 0; j < n; j++) {
if (i <= citations[j]) {
high++;
}

if (i <= high) {
answer = i;
}
}
}

return answer;
}

흐름

  1. 논문을 인용한 횟수가 담긴 배열 citations를 정렬

  2. 가장 많이 인용한 횟수 만큼 반복

  3. 0부터 배열 길이만큼 반복하면서 i 값이 인용 횟수보다 작은 경우 i 보다 인용된 횟수가 많은 것이므로 high 변수 증가

  4. h번 이상 인용된 논문이 h편 이상이여야 하므로 i가 high 보다 작을 경우에만 answer에 저장

  5. i가 high보다 커질 경우 answer에 저장되지 않으므로 answer에 마지막으로 저장된 값이 h


다른 해결방법

코드

1
2
3
4
5
6
7
8
9
10
11
public int solution(int[] citations) {
Arrays.sort(citations);

int max = 0;
for(int i = citations.length-1; i > -1; i--){
int min = (int)Math.min(citations[i], citations.length - i);
if(max < min) max = min;
}

return max;
}

위 코드의 로직

  1. 배열을 정렬 후 배열의 마지막 값과 1 부터 증가 시키면서 citations의 길이 만큼 반복함

  2. 예를 들어 {0, 1, 3, 5, 6} 인 경우, citations.length는 5, i = 5 - 1 이므로 4, citations.length - i는 5 - 4가 되므로 1임 그런고로, 1과 citations[4]인 6과 비교해서 작은 놈을 min에 저장

  3. 위 과정을 반복하면
    min = Min(6,1)
    min = Min(5,2)
    min = Min(3,3)
    min = Min(1,4)
    min = Min(0,5)
    가 되고 max는 max가 min 보다 작을 때 max에 min 값이 저장되므로 max엔 최종적으로 3이 저장

  • 어떻게 유추해서 푼 건지 이해가 안간다 천재인 듯

결과

1번

번호 속도
테스트 1 통과 (11.43ms, 50.3MB)
테스트 2 통과 (14.71ms, 52.4MB)
테스트 3 통과 (15.13ms, 50.7MB)
테스트 4 통과 (13.74ms, 50.1MB)
테스트 5 통과 (16.49ms, 50.6MB)
테스트 6 통과 (13.86ms, 50MB)
테스트 7 통과 (10.08ms, 52.4MB)
테스트 8 통과 (7.45ms, 52.6MB)
테스트 9 통과 (8.26ms, 52.9MB)
테스트 10 통과 (10.29ms, 50MB)
테스트 11 통과 (17.04ms, 50.9MB)
테스트 12 통과 (8.21ms, 52.8MB)
테스트 13 통과 (15.30ms, 52.5MB)
테스트 14 통과 (13.62ms, 52.7MB)
테스트 15 통과 (15.64ms, 50.5MB)
테스트 16 통과 (0.97ms, 54.7MB)

2번

번호 속도
테스트 1 통과 (1.10ms, 52.4MB)
테스트 2 통과 (1.36ms, 50.5MB)
테스트 3 통과 (1.36ms, 50.8MB)
테스트 4 통과 (0.85ms, 51.9MB)
테스트 5 통과 (0.95ms, 52.5MB)
테스트 6 통과 (1.35ms, 52.7MB)
테스트 7 통과 (1.00ms, 50.6MB)
테스트 8 통과 (0.87ms, 50.9MB)
테스트 9 통과 (1.06ms, 50.5MB)
테스트 10 통과 (1.11ms, 52.6MB)
테스트 11 통과 (1.39ms, 52.5MB)
테스트 12 통과 (0.91ms, 52.6MB)
테스트 13 통과 (1.22ms, 50.3MB)
테스트 14 통과 (1.50ms, 52.5MB)
테스트 15 통과 (1.36ms, 52.3MB)
테스트 16 통과 (0.94ms, 52.5MB)
  • 속도도 압도적…

테스트 케이스

1
2
3
4
5
6
7
8
9
10
11
assertEquals(3, test.solution(new int[] {3,0,6,1,5}));
assertEquals(3, test.solution(new int[] {6,5,4,3,1,1,1,1,1}));
assertEquals(3, test.solution(new int[] {0, 1, 1, 1, 1, 3, 3, 4}));
assertEquals(3, test.solution(new int[] {5, 5, 5, 0}));
assertEquals(2, test.solution(new int[] {2,2,2,2,2}));
assertEquals(4, test.solution(new int[] {5, 5, 5, 5}));
assertEquals(5, test.solution(new int[] {5, 5, 5, 5, 5}));
assertEquals(1, test.solution(new int[] {7}));
assertEquals(3, test.solution(new int[] {4, 3, 3, 3, 3}));
assertEquals(0, test.solution(new int[] {0,0,0,0,0,0}));
assertEquals(3, test.solution(new int[] {6, 5, 3, 1, 0}));

댓글 공유

문제

https://programmers.co.kr/learn/courses/30/lessons/42746


코드

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
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
public String solution(int[] numbers) {

List<Numbers> list = new ArrayList<Numbers>();
for (int i = 0; i < numbers.length; i++) {
int number = numbers[i];

char[] str = String.valueOf(number).toCharArray();
StringBuilder fourDigitString = new StringBuilder();

fourDigitString.append(str);
if (str.length < 4) {

for (int j = 0; j < 4 - str.length; j++) {
fourDigitString.append(str[((j) % str.length)]);
}
}

list.add(new Numbers(i, Integer.parseInt(fourDigitString.toString())));
}

Collections.sort(list, new Comparator<Numbers>() {

@Override
public int compare(Numbers o1, Numbers o2) {
return o2.value.compareTo(o1.value);
}
});

StringBuilder sb = new StringBuilder();
int sum = 0;
for (Numbers n : list) {
sum += n.value;
sb.append(numbers[n.postion]);
}

if (sum == 0) {
sb.setLength(0);
sb.append(0);
}

return sb.toString();
}

class Numbers {
public Integer postion;
public Integer value;

public Numbers(Integer postion, Integer value) {
this.postion = postion;
this.value = value;
}
}

흐름

  1. 문제에서 numbers의 원소 값이 1000 이하라고 했으므로 numbers 크기 만큼 돌면서 numbers 안에 값이 4자리가 아닌 경우 자기 숫자를 뒤에 덧붙여서 4자리로 만듬
    • ex) 121 > 1212, 1 > 1111, 23 > 2323, …
  2. 현재 배열의 index와 값을 비교하기 위에 inner class를 하나 만들어서 index와 value를 저장하고 class를 list에 추가
  3. list를 class의 value 값으로 큰 수부터 나오도록 정렬
  4. list를 돌면서 value를 StringBuilder로 붙임
  5. 이 때, 0 0 0 0 일 경우 0 이 되어야 하므로 value들을 모두 더했을 때 값이 0이라면 0 만 붙임
  6. toString() 으로 String형으로 return

다른 분들의 해결방법

다른분의 코드

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public String solution(int[] numbers) {
String answer = "";

List<Integer> list = new ArrayList<>();
for(int i = 0; i < numbers.length; i++) {
list.add(numbers[i]);
}
Collections.sort(list, (a, b) -> {
String as = String.valueOf(a), bs = String.valueOf(b);
return -Integer.compare(Integer.parseInt(as + bs), Integer.parseInt(bs + as));
});
StringBuilder sb = new StringBuilder();
for(Integer i : list) {
sb.append(i);
}
answer = sb.toString();
if(answer.charAt(0) == '0') {
return "0";
}else {
return answer;
}
}

위 코드의 로직

  • list에 numbers array를 그대로 저장하고 list의 저장된 element를 앞뒤로 붙여서 정수로 바꾼 후 비교해서 정렬
  • String을 다루는 부분이 많아서 속도는 살짝 떨어지는 듯

결과

1 번

번호 속도
테스트 1 통과 (139.80ms, 83.2MB)
테스트 2 통과 (88.71ms, 67MB)
테스트 3 통과 (167.96ms, 82.4MB)
테스트 4 통과 (17.95ms, 50.7MB)
테스트 5 통과 (129.09ms, 77.4MB)
테스트 6 통과 (116.84ms, 71.2MB)
테스트 7 통과 (1.44ms, 52.3MB)
테스트 8 통과 (1.38ms, 52.7MB)
테스트 9 통과 (1.20ms, 50.2MB)
테스트 10 통과 (1.46ms, 52.6MB)
테스트 11 통과 (1.65ms, 52.9MB)

2 번

번호 속도
테스트 1 통과 (340.75ms, 105MB)
테스트 2 통과 (236.67ms, 82.1MB)
테스트 3 통과 (350.56ms, 126MB)
테스트 4 통과 (80.72ms, 59.7MB)
테스트 5 통과 (300.18ms, 110MB)
테스트 6 통과 (280.61ms, 87.6MB)
테스트 7 통과 (31.26ms, 57.2MB)
테스트 8 통과 (35.88ms, 53.4MB)
테스트 9 통과 (34.27ms, 55.3MB)
테스트 10 통과 (30.44ms, 55.6MB)
테스트 11 통과 (40.16ms, 55.3MB)

테스트 케이스

1
2
3
4
5
6
7
8
9
assertEquals("6210", test.solution(new int[] {6, 10, 2}));
assertEquals("9534330", test.solution(new int[] {3, 30, 34, 5, 9}));
assertEquals("220200", test.solution(new int[] {2,200,20}));
assertEquals("2200", test.solution(new int[] {2,0,20}));
assertEquals("0", test.solution(new int[] {0,0,0}));
assertEquals("21212", test.solution(new int[] {12, 212}));
assertEquals("21221", test.solution(new int[] {212, 21}));
assertEquals("7000", test.solution(new int[] {0, 0, 70}));
assertEquals("1000000", test.solution(new int[] {0, 0, 0, 1000}));

댓글 공유

문제

https://programmers.co.kr/learn/courses/30/lessons/60057


코드

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
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
public int solution(String s) {
int stringLength = s.length();

StringBuilder result = new StringBuilder();
String origin = new String();
char[] tochar = s.toCharArray();
int min = Integer.MAX_VALUE;

for (int i = 1; i <= stringLength / 2; i++) {
int compression = 1;
result.setLength(0);
origin = new String(tochar, 0, i);

String nextWord = new String();
for (int j = i; j < stringLength; j+=i) {
if (j + i > stringLength) {
nextWord = s.substring(j, stringLength);
} else {
nextWord = new String(tochar, j , i);
}

if (origin.equals(nextWord)) {
++compression;
} else {
if (compression != 1) {
result.append(compression);
}

result.append(origin);

origin = nextWord.toString();
compression = 1;
}
}

if (compression != 1) {
result.append(compression);
}

result.append(origin);

if (min > result.length()) {
min = result.length();
}
}

int answer = min > stringLength ? stringLength : min;
return answer;

흐름

  1. 문자열을 반으로 나눠서 2개로 나눈 것 보다 짧을 수 없으므로 문자열 길이 / 2 한 값 만큼 반복

  2. 비교 할 문자열을 구함(origin)

    • 처음엔 1개 짜리 이후엔 2개, 3개, … 증가 할 수 있도록 i를 증가 시키면서 i 번째 까지 자름
  3. i 번째 문자 이후로 비교 할 문자를 구함

  4. 같으면 압축율을 증가시키고

  5. 다르면 압축율과 문자를 더해서 압축문자열(result)을 만듬

  6. 비교 할 문자를 구하면서 마지막 문자는 안 붙여지고 팅기므로 for 문 밖에서 마지막 문자를 붙임

  7. 이전에 구했던 압축문자열 길이와 비교해서 더 작은 길이를 저장함


결과

번호 속도
테스트 1 통과 (0.99ms, 52.4MB)
테스트 2 통과 (2.92ms, 49.9MB)
테스트 3 통과 (1.72ms, 52.7MB)
테스트 4 통과 (0.99ms, 52.1MB)
테스트 5 통과 (0.84ms, 50MB)
테스트 6 통과 (1.03ms, 52.4MB)
테스트 7 통과 (3.49ms, 50.4MB)
테스트 8 통과 (2.49ms, 50.3MB)
테스트 9 통과 (4.46ms, 52.6MB)
테스트 10 통과 (9.25ms, 52.4MB)
테스트 11 통과 (1.25ms, 50.2MB)
테스트 12 통과 (1.28ms, 52.3MB)
테스트 13 통과 (9.63ms, 51.8MB)
테스트 14 통과 (4.35ms, 52.2MB)
테스트 15 통과 (1.31ms, 52.1MB)
테스트 16 통과 (0.85ms, 50.2MB)
테스트 17 통과 (8.91ms, 52.6MB)
테스트 18 통과 (7.70ms, 52.6MB)
테스트 19 통과 (8.63ms, 54.9MB)
테스트 20 통과 (7.89ms, 52.6MB)
테스트 21 통과 (9.99ms, 52.7MB)
테스트 22 통과 (10.63ms, 52.7MB)
테스트 23 통과 (9.68ms, 52.5MB)
테스트 24 통과 (7.89ms, 54.4MB)
테스트 25 통과 (10.43ms, 52.9MB)
테스트 26 통과 (8.17ms, 52.5MB)
테스트 27 통과 (15.60ms, 52.6MB)
테스트 28 통과 (0.88ms, 50.4MB)
  • result에 문자열을 더하지 말고 그냥 문자열 길이를 더하는 방식으로 하면 더 시간을 줄일 수 있음

테스트 케이스

1
2
3
4
5
6
7
8
assertEquals(7, test.solution("aabbaccc"));
assertEquals(9, test.solution("ababcdcdababcdcd"));
assertEquals(8, test.solution("abcabcdede"));
assertEquals(14, test.solution("abcabcabcabcdededededede"));
assertEquals(17, test.solution("xababcdcdababcdcd"));
assertEquals(1, test.solution("a"));
assertEquals(2, test.solution("aaaaa"));
assertEquals(3, test.solution("aaaaaaaaaa"));

참고 사이트

댓글 공유

문제

https://programmers.co.kr/learn/courses/30/lessons/42583?language=java


코드

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
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
public int solution(int bridge_length, int weight, int[] truck_weights) {
LinkedList<Truck> queue = new LinkedList<Truck>();

for (int i = 0; i < truck_weights.length; i++) {
queue.offer(new Truck(bridge_length, truck_weights[i]));
}

int answer = 1;
int bridgeOnTruck = 0;
while (!queue.isEmpty()) {

int totalWeight = 0;
for (int i = 0; i < bridgeOnTruck; i++) {
totalWeight += queue.get(i).weight;
}

int nextWeight = 0;
if (queue.size() > bridgeOnTruck) {
nextWeight = queue.get(bridgeOnTruck).weight;
}

if (totalWeight + nextWeight <= weight) {
if (queue.size() > bridgeOnTruck) {
++bridgeOnTruck;
}
}

for (int i = 0; i < bridgeOnTruck; i++) {
Truck truck = queue.get(i);
truck.position = truck.position - 1;
}

if (queue.peek().position == 0) {
queue.poll();
--bridgeOnTruck;
}

++answer;
}

return answer;
}

class Truck {
public int position;
public int weight;

public Truck(int position, int weight) {
this.position = position;
this.weight = weight;
}
}

흐름

  1. 트럭 array를 queue에 모두 저장
  2. 트럭 모두 건널 때 까지 반복
  3. 한 번에 몇 개의 트럭까지 건널 수 있을 지 계산하기 위해 현재 다리 위에 있는 트럭의 개수 만큼 돌면서 트럭 무게를 더함
  4. 다음 번 트럭까지 다리에 올라 올 수 있는 지 확인하기 위해 큐의 마지막 index가 아니라면 queue에서 다음 번 트럭의 무게를 가져옴
  5. 현재 다리에 있는 트럭들의 무게 + 다음 트럭의 무게를 더한 값이 다리가 버틸 수 있는 무게 보다 가벼우면
  6. 큐의 마지막인지 체크해서 큐의 마지막이 아니라면 그 다음 트럭도 다리 위에 올라와야 하기 때문에 다리 위 트럭의 개수(truckAmount)를 증가 시킴
  7. 다리 위 트럭의 수 만큼 반복하면서 트럭을 앞으로 한칸 씩 움직임
  8. 첫 번째 트럭이 다리를 건넜다면 queue에서 제거하고 다리 위 트럭 수를 하나 감소 시킴
  9. 초를 증가 시킴

결과

번호 속도
테스트 1 통과 (3.63ms, 52.1MB)
테스트 2 통과 (14.16ms, 52.1MB)
테스트 3 통과 (1.65ms, 53.3MB)
테스트 4 통과 (41.49ms, 53.8MB)
테스트 5 통과 (70.64ms, 53.9MB)
테스트 6 통과 (53.31ms, 56.1MB)
테스트 7 통과 (3.09ms, 50MB)
테스트 8 통과 (1.97ms, 50.3MB)
테스트 9 통과 (10.68ms, 54.6MB)
테스트 10 통과 (2.20ms, 53MB)
테스트 11 통과 (1.10ms, 52.5MB)
테스트 12 통과 (2.35ms, 52.2MB)
테스트 13 통과 (4.50ms, 52.2MB)
테스트 14 통과 (1.26ms, 53MB)

테스트 케이스

1
2
3
assertEquals(8, test.solution(2, 10, new int[] {7,4,5,6}));
assertEquals(101, test.solution(100, 100, new int[] {10}));
assertEquals(110, test.solution(100, 100, new int[] {10,10,10,10,10,10,10,10,10,10}));

댓글 공유

https://programmers.co.kr/learn/courses/30/lessons/62048?language=java


코드

1
2
3
4
5
6
7
8
9
10
11
12
public long solution(long w,long h) {
long big = w > h ? w : h;
long small = w > h ? h : w;

while (small != 0) {
long r = big % small;
big = small;
small = r;
}

return (w * h) - (w + h - big);
}

흐름

  1. 최대 공약수를 구함

  2. 전체 사각형 수 (w * h) 에서 안 멀쩡한 사각형 수(w + h - 최대 공약수)를 뺌


최대 공약수를 사용하는 이유

아래 블로그에서 잘 설명 해주셨음


결과

번호 속도
테스트 1 통과 (0.76ms, 50.7MB)
테스트 2 통과 (0.81ms, 52.4MB)
테스트 3 통과 (0.75ms, 52.6MB)
테스트 4 통과 (0.70ms, 52.6MB)
테스트 5 통과 (0.82ms, 51.9MB)
테스트 6 통과 (0.80ms, 52.1MB)
테스트 7 통과 (0.85ms, 52.4MB)
테스트 8 통과 (0.86ms, 54.6MB)
테스트 9 통과 (0.72ms, 52.3MB)
테스트 10 통과 (0.73ms, 52.6MB)
테스트 11 통과 (0.74ms, 52.2MB)
테스트 12 통과 (0.58ms, 52.5MB)
테스트 13 통과 (0.51ms, 52.5MB)
테스트 14 통과 (0.60ms, 52.6MB)
테스트 15 통과 (0.53ms, 50.3MB)
테스트 16 통과 (0.61ms, 52.5MB)
테스트 17 통과 (0.61ms, 52.3MB)
테스트 18 통과 (0.80ms, 52.3MB)

테스트 케이스

1
2
3
4
5
assertEquals(80, test.solution(8, 12));
assertEquals(12, test.solution(5, 4));
assertEquals(40, test.solution(10, 5));
assertEquals(352, test.solution(17, 23));
assertEquals(30467460, test.solution(3, 15233730));

참고 사이트

본문 참조

댓글 공유

https://programmers.co.kr/learn/courses/30/lessons/42587


코드

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
34
public int solution(int[] priorities, int location) {
int answer = 0;

LinkedList<Integer> queue = new LinkedList<Integer>();
for (int i = 0; i < priorities.length; i++) {
queue.offer(priorities[i]);
}

while (queue.size() != 0) {
for (int i = 1; i < queue.size(); i++) {
if (queue.peek() < queue.get(i)) {
queue.offer(queue.poll());

if (location == 0) {
location = queue.size() - 1;
} else {
--location;
}

i = 0;
}
}

answer++;
if (location == 0) {
break;
}

--location;
queue.poll();
}

return answer;
}

흐름

  1. 우선순위가 담긴 배열(priorities)을 Queue에 저장

  2. 큐에 첫 번째 값을 꺼내서 그 뒤 값들과 비교

  3. 첫 번째 값이 뒤에 있는 값들 보다 작다면 큐에 맨 뒤로 보냄

  4. 출력해야 되는 프린터의 index를 조정

    • index가 0 이라면 맨 뒤로 이동했을테니 큐 크기 - 1;
    • 아니라면 앞으로 한 칸 이동 했을테니 -1
  5. 맨 뒤로 이동 시켰으면 맨 앞에 값이 변경 됐으므로 처음부터 다시 검사

  6. 큐의 0 번째 인덱스가 가장 큰 값이라면 count를 증가시키고 출력해야 하는 프린터의 위치를 확인

  7. 출력해야하는 프린터가 맨 앞이라면 break로 반복문을 빠져나와 프로그램 종료

  8. 아니라면 맨 앞에 값을 삭제하고 index를 -1 해서 한 칸 앞으로 당김

  9. 끝날 때 까지 반복


결과

번호 속도
테스트 1 통과 (3.17ms, 52.8MB)
테스트 2 통과 (3.41ms, 52.6MB)
테스트 3 통과 (1.33ms, 52.6MB)
테스트 4 통과 (1.15ms, 50.8MB)
테스트 5 통과 (0.85ms, 52.2MB)
테스트 6 통과 (1.44ms, 52.7MB)
테스트 7 통과 (1.58ms, 50.4MB)
테스트 8 통과 (3.89ms, 52.9MB)
테스트 9 통과 (1.04ms, 52.8MB)
테스트 10 통과 (1.57ms, 52.3MB)
테스트 11 통과 (3.90ms, 52.7MB)
테스트 12 통과 (1.07ms, 52.3MB)
테스트 13 통과 (4.36ms, 52.1MB)
테스트 14 통과 (0.83ms, 52MB)
테스트 15 통과 (0.95ms, 50.4MB)
테스트 16 통과 (1.21ms, 50.3MB)
테스트 17 통과 (2.79ms, 50.7MB)
테스트 18 통과 (0.94ms, 50.7MB)
테스트 19 통과 (2.61ms, 53.1MB)
테스트 20 통과 (1.51ms, 52.3MB)

테스트 케이스

1
2
3
4
assertEquals(1, test.solution(new int[] {2, 1, 3, 2}, 2));
assertEquals(5, test.solution(new int[] {1, 1, 9, 1, 1, 1}, 0));
assertEquals(6, test.solution(new int[] {2, 2, 2, 1, 3, 4}, 3));
assertEquals(2, test.solution(new int[] {1, 2, 3, 2}, 3));

댓글 공유

https://programmers.co.kr/learn/courses/30/lessons/42586


소스

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
public int[] solution(int[] progresses, int[] speeds) {
int start = 0;
List<Integer> list = new ArrayList<Integer>();
while (start != progresses.length) {
int deploy = 0;
for (int i = start; i < progresses.length; i++) {
progresses[i] += speeds[i];
}

for (int i = start; i < progresses.length; i++) {
if (progresses[start] < 100) {
break;
}

if (progresses[i] >= 100) {
++start;
++deploy;
}
}

if (deploy != 0) {
list.add(deploy);
}
}

int[] answer = list.stream().mapToInt(i -> i).toArray();
return answer;
}

흐름

  1. 기능개발이 완료된 인덱스부터 반복하기 위해 start 변수 생성

  2. 기능개발이 끝날 때 까지 반복

  3. 개발이 안 끝난 기능 index 부터 돌면서 작업 속도를 더 함

  4. 개발이 안 끝난 기능 index 부터 돌면서 첫 번째 기능이 개발 됐는지 확인하고 안 끝났으면 3 번으로 돌아감

  5. 첫 번째 기능이 완료 되었으면 그 다음 기능개발을 위해 ++start 하고, deploy된 기능을 카운팅하는 deploy 변수를 증가

  6. deploy한 기능이 있는 경우에만 list에 저장

  7. ArrayList를 int[]로 변경


다른 분의 소스

1
2
3
4
5
6
7
8
9
10
11
public int[] solution(int[] progresses, int[] speeds) {
int[] dayOfend = new int[100];
int day = -1;
for(int i=0; i<progresses.length; i++) {
while(progresses[i] + (day*speeds[i]) < 100) {
day++;
}
dayOfend[day]++;
}
return Arrays.stream(dayOfend).filter(i -> i!=0).toArray();
}

로직

  • 기능 갯수 만큼 돌면서 진도율과 날짜 * 개발 속도를 비교해서 100 보다 작으면 다음날로 증가시키고 크면 그 날짜에 저장되는 갯수를 증가시킴

  • 대박


결과

1 번

번호 속도
테스트 1 통과 (4.53ms, 50.8MB)
테스트 2 통과 (5.07ms, 50.6MB)
테스트 3 통과 (5.09ms, 52.8MB)
테스트 4 통과 (5.29ms, 52.4MB)
테스트 5 통과 (8.36ms, 55MB)
테스트 6 통과 (4.95ms, 51.2MB)
테스트 7 통과 (5.58ms, 52.6MB)
테스트 8 통과 (5.18ms, 50.7MB)
테스트 9 통과 (5.44ms, 52.5MB)
테스트 10 통과 (5.22ms, 50.5MB)

2 번

번호 속도
테스트 1 통과 (6.60ms, 51.4MB)
테스트 2 통과 (6.83ms, 53.1MB)
테스트 3 통과 (6.92ms, 52.5MB)
테스트 4 통과 (6.70ms, 52.8MB)
테스트 5 통과 (19.88ms, 52.4MB)
테스트 6 통과 (5.05ms, 50.7MB)
테스트 7 통과 (7.01ms, 52.5MB)
테스트 8 통과 (4.68ms, 50.5MB)
테스트 9 통과 (6.95ms, 52.2MB)
테스트 10 통과 (5.31ms, 50.8MB)
  • 두 소스 모두 Arrays.stream을 사용하지 않고 반복해서 저장하면 1초 대로 줄어듬.
  • 확실히 스트림이 느린 듯함.

테스트 케이스

1
2
3
assertArrayEquals(new int[] {2,1}, test.solution(new int[] {93, 30, 55}, new int[] {1, 30, 5}));
assertArrayEquals(new int[] {3}, test.solution(new int[] {0, 30, 55}, new int[] {1, 99, 99}));
assertArrayEquals(new int[] {1,1,1}, test.solution(new int[] {3, 2, 1}, new int[] {1, 1, 1}));

전체 소스

https://github.com/jungguji/algorithm_training/blob/master/src/main/java/algorithm/programmers/level2/stackqueue/%EB%8B%A4%EB%A6%AC%EB%A5%BC_%EC%A7%80%EB%82%98%EB%8A%94_%ED%8A%B8%EB%9F%AD.java

댓글 공유

Junggu Ji

author.bio


author.job