안녕하세요! delay100입니다.
요 며칠 감기때문에 앓다가 오늘 낮에 병원에 다녀왔는데.. 인후염과 기관지염에 걸려서 약 먹고 골골대고 있어요..
아무튼 오늘은 4월의 첫 TIL.. 그리고 4월의 첫 세션에 참가했습니다!!
미들러 문제.
1번. 햄버거 만들기
https://school.programmers.co.kr/learn/courses/30/lessons/133502
1-1. 실패 코드
재료(ingredient) 배열을 순환합니다.
재료 배열에서 빵이 나온 경우와 빵이 아닌 경우(야채, 고기)를 구분합니다.
빵이 나온 경우에는 stack의 가장 상단에 고기가 있는지 확인하고
고기가 있는 경우 그 아래에 야채가 있는지 확인하고
야채가 있는 경우 그 아래에 고기가 있는지 확인합니다.
그 안에 빵이 있는 경우 만들 수 있는 햄버거 수를 증가시킵니다.
빵이 나오지 않은 경우에는 stack에 야채, 고기를 그냥 넣어줍니다.
이 때 stack을 2개 사용하여 stk에서 pop한 값을 버리지 않고 stk2에 이동시켜 둡니다.
만약 햄버거(빵-야채-고기-빵)가 만들어지지 않았을 경우 다시 stk2에 있던 값을 stk으로 옮겨주기 위함입니다.
import java.io.*;
import java.util.*;
class Solution {
public int solution(int[] ingredient) {
int answer = 0;
Stack<Integer> stk = new Stack<>();
Stack<Integer> stk2 = new Stack<>();
for(int i=0; i<ingredient.length; i++) {
int ingre = ingredient[i];
if(ingre == 1) { // 빵(1)인 경우 stack에 이미 들어있는 값들 확인시작
if(!stk.isEmpty() && (stk.peek() == 3)) { // 스택에 고기가 들어있는 경우
stk2.push(stk.pop());
if(!stk.isEmpty() && stk.peek() == 2) { // 스택에 야채가 들어있는 경우
stk2.push(stk.pop());
if(!stk.isEmpty() && stk.peek() == 1) { // 스택에 빵이 들어있는 경우
stk.pop();
answer++;
} else {
stk.push(stk2.pop());
}
} else {
stk.push(stk2.pop());
}
} else {
stk.push(ingre);
}
while(!stk2.isEmpty()) {
stk2.pop();
}
} else { // 야채(2), 고기(3)인 경우 stack에 넣어줌
stk.push(ingre);
}
}
return answer;
}
}
3~12번 테스트 케이스를 통과하지 못했습니다.
햄버거(빵-야채-고기-빵)가 만들어 졌든 안 만들어 졌든 stk2에 있는 값을 stk으로 옮겨줬기 때문입니다.
1-2. 성공 코드
따라서 실패 코드와 전반적인 코드는 같지만, 빵-야채-고기-빵 조합에 도달한 경우에는 stack2에 있는 스택을 그냥 pop으로 날려주었습니다.
또한 현재 도달한 1이 햄버거(빵-야채-고기-빵 조합)를 만들지 않은 경우에만 1을 stack에 push하도록 해주었습니다.
import java.io.*;
import java.util.*;
class Solution {
public int solution(int[] ingredient) {
int answer = 0;
Stack<Integer> stk = new Stack<>();
Stack<Integer> stk2 = new Stack<>();
for(int i=0; i<ingredient.length; i++) {
int ingre = ingredient[i];
if(ingre == 1) { // 빵(1)인 경우 stack에 이미 들어있는 값들 확인시작
boolean isTrue = false;
if(!stk.isEmpty() && (stk.peek() == 3)) { // 스택에 고기가 들어있는 경우
stk2.push(stk.pop());
if(!stk.isEmpty() && stk.peek() == 2) { // 스택에 야채가 들어있는 경우
stk2.push(stk.pop());
if(!stk.isEmpty() && stk.peek() == 1) { // 스택에 빵이 들어있는 경우
stk2.push(stk.pop());
isTrue = true;
answer++;
while(!stk2.isEmpty()) {
stk2.pop();
}
}
}
}
while(!stk2.isEmpty()) {
stk.push(stk2.pop());
}
if(!isTrue) stk.push(ingre); // 현재 햄버거를 만들지 않았을 때만
} else { // 야채(2), 고기(3)인 경우 stack에 넣어줌
stk.push(ingre);
}
}
return answer;
}
}
2번. 둘만의 암호
https://school.programmers.co.kr/learn/courses/30/lessons/155652
1. 성공 코드
이 문제에서 생각해야할 점은 두 가지였습니다.
1. skip할 알파벳을 어떻게 알아 볼 것인가?
-> isSkip배열을 만들어서 아스키코드 a~z까지 각각을 0~25로 대응시킵니다.
skip해야 하는 알파벳인 경우, true로 변경합니다.
2. z를 넘어섰을 때 어떻게 다시 a부터 순회할 것인가?
-> while문을 두어서 z(25)를 넘어선 경우 a(0)부터 다시 순회할 수 있도록 합니다.
코드에 대한 전반적인 흐름은 주석으로 작성해두었습니다.
import java.io.*;
import java.util.*;
class Solution {
public String solution(String s, String skip, int index) {
StringBuilder sb = new StringBuilder();
char[] c = s.toCharArray();
boolean[] isSkip = new boolean[26]; // 알파벳 0~25개
for(int i=0; i<skip.length(); i++) {
isSkip[skip.charAt(i) - 97] = true; // 각 알파벳 별 사용 여부를 담은 리스트
}
for(int i=0; i<s.length(); i++) {
int cnt = 0;
int x = c[i] - 96; // 현재 위치 - 1(현재 아스키코드 보다 하나 큰 위치), 현재 위치는 세지 않아야 하기 때문임
boolean isTrue = false; // z를 넘어가는 경우에 a부터 순환하기 위한 변수
while(!isTrue) { // 원하는 index에 도달했거나, z를 넘어가지 않은 경우 while문 종료
for(int j=x; j<26; j++) { // 현재 위치한 알파벳의 위치
if(!isSkip[j]) cnt++; // 알파벳이 스킵하는 알파벳이 아닌 경우에 cnt를 증가
if(cnt == index) { // cnt가 도달해야하는 index에 도착한 경우
isTrue = true; // while문을 종료하도록 함
sb.append((char)(j+97)); // index로 바꾸었던 값을 아스키코드로 변환
break;
}
}
x = 0; // z를 만난 경우 다시 a부터 검사해야하므로 x=0으로 설정
}
}
String answer = sb.toString();
return answer;
}
}
+ 비기너 문제
1번.
https://school.programmers.co.kr/learn/courses/30/lessons/12917
2번.
https://school.programmers.co.kr/learn/courses/30/lessons/12932
+ 챌린저 문제
1번.
https://school.programmers.co.kr/learn/courses/30/lessons/42628
2번.
https://school.programmers.co.kr/learn/courses/30/lessons/77486
또한 4월 1일인만큼 만우절 이벤트도 올려주셨어요!!
https://school.programmers.co.kr/learn/courses/30/lessons/120831
n이하의 합을 구하면 되는 아주 간단한 문제이지만, 만우절인 만큼 가장 복잡하고 길게 풀어야 한다는 조건이 달려있습니다!
1. 실패 코드 - 스택오버플로우
쓸데없이 하드코딩(i의 값)되고 반복(%2)되는 것 만큼 비효율 적인건 없죠!
아래의 코드를 이용해 재밌는 코드를 만들어 볼 겁니다.
for (int i = 1; i <= 1000; i++) {
System.out.println("else if (i == " + i + ") {");
System.out.println(" if (i % 2 == 0) {");
System.out.println(" answer += i;");
System.out.println(" }");
System.out.println("}");
}
처음에는 아래와같이 for문을 돌리면서 if문 하나하나 검색하여 i=1000까지 만들었는데..
class Solution {
public int solution(int n) {
int answer = 0;
for(int i=1; i<=n; i++) {
if(i == 1) {
if(i % 2 == 0) {
answer++;
}
} else if(i == 2) {
if(i % 2 == 0) {
answer++;
}
..
}
}
}
}
스택 오버플로우가 발생하더군요 ㅠㅠ
2. 성공 코드
흐음.. 하지만 이렇게 물러날 수는 없죠..
i의 최대 개수를 500으로 줄이니 잘 실행이 되는군요?
for (int i = 1; i <= 500; i++) {
System.out.println("else if (i == " + i + ") {");
System.out.println(" if (i % 2 == 0) {");
System.out.println(" answer += i;");
System.out.println(" }");
System.out.println("}");
}
for (int i = 501; i <= 1000; i++) {
System.out.println("else if (i == " + i + ") {");
System.out.println(" if (i % 2 == 0) {");
System.out.println(" answer += i;");
System.out.println(" }");
System.out.println("}");
}
for문을 2개로 나누어서 실패코드1과 같은 방법으로 제출했습니다!ㅋㅋ
코드가 너무 길어서(5천줄이 넘음..) 차마 여기에는 못 올리겠군용.. 너무 길어서 다른 글에 올려서 제출했습니다.
날씨가 쌀쌀한데 감기 조심하시구 행복 코딩하시길!
저는 감기약을 먹어서 너무 졸려서.. 이만 자러 가봅니다...
'항해99 > 99club1기TIL' 카테고리의 다른 글
[99club/TIL] 2주차 - 수요일 TIL(Today I Learned) (0) | 2024.04.03 |
---|---|
[99club/TIL] 2주차 - 화요일 TIL(Today I Learned) (0) | 2024.04.02 |
[99club/TIL] 1주차 - 일요일 TIL(Today I Learned) (0) | 2024.03.31 |
[99club/TIL] 1주차 - 토요일 TIL(Today I Learned) (0) | 2024.03.30 |
[99club/TIL] 1주차 - 금요일 TIL(Today I Learned) (0) | 2024.03.30 |