티스토리 뷰

1️⃣ 문자열 밀기

 

문제 설명

문자열 "hello"에서 각 문자를 오른쪽으로 한 칸씩 밀고 마지막 문자는 맨 앞으로 이동시키면 "ohell"이 됩니다. 이것을 문자열을 민다고 정의한다면 문자열 A와 B가 매개변수로 주어질 때, A를 밀어서 B가 될 수 있다면 밀어야 하는 최소 횟수를 return하고 밀어서 B가 될 수 없으면 -1을 return 하도록 solution 함수를 완성해보세요.

 

제한사항

  • 0 < A의 길이 = B의 길이 < 100
  • A, B는 알파벳 소문자로 이루어져 있습니다.

입출력 예

A B result
"hello" "ohell" 1
"apple" "elppa" -1
"atat" "tata" 1
"abc" "abc" 0

 

입출력 예 #1

  • "hello"를 오른쪽으로 한 칸 밀면 "ohell"가 됩니다.

입출력 예 #2

  • "apple"은 몇 번을 밀어도 "elppa"가 될 수 없습니다.

입출력 예 #3

  • "atat"는 오른쪽으로 한 칸, 세 칸을 밀면 "tata"가 되므로 최소 횟수인 1을 반환합니다.

입출력 예 #4

  • "abc"는 밀지 않아도 "abc"이므로 0을 반환합니다.

 

💻 나의 풀이

class Solution {
    public int solution(String A, String B) {
        int answer = -1;
        
        // A와 B가 같은 경우
        if(A.equals(B)){   
            answer = 0;
        }
        
        // 문자열 A를 회전하여 B를 만들 수 있는 경우
        for(int i=0; i<A.length(); i++) {
            StringBuilder sb = new StringBuilder();
            // 문자열 A를 회전하여 만들 수 있는 문자열 생성
            for(int j=A.length()-i; j<A.length(); j++) {
                sb.append(A.charAt(j));
            }
            
            for(int j=0; j<A.length()-i; j++) {
                sb.append(A.charAt(j));
            }
            
            // 생성된 문자열이 B와 일치하는지 확인
            if(sb.toString().equals(B)) {
                answer = i;   // 일치하는 경우 회전 횟수를 저장하고 반복 종료
                break;
            }
        }
        return answer;
    }
}

 

먼저 밀지 않아도 같은 경우엔 0을 반환하도록 합니다.

그리고 A의 길이만큼 반복하면서 문자열 A를 회전시켜서 B를 만들 수 있는 경우를 탐색하는데 StringBuilder를 사용했습니다.

for (int j = A.length() - i; j < A.length(); j++) 코드는 A를 오른쪽으로 i번 회전시킨 부분을 추가하는 것입니다.

for (int j = 0; j < A.length() - i; j++) 코드는 나머지 부분을 추가하는 것입니다.

그리고 charAt(int index)를 사용하여 문자열에서 특정 위치에 있는 문자를 가져옵니다. 

마지막으로 생성된 문자열이 B와 일치하는지 확인하고, 일치하면 answer에 회전 횟수를 저장하고 반복을 종료합니다.

 

 

🔎 다른 사람의 풀이

class Solution {
    public int solution(String A, String B) {
        String tempB = B.repeat(3);  // 문자열 B를 3번 반복한 새로운 문자열 생성
        return tempB.indexOf(A);  // 새로운 문자열에서 문자열 A가 처음 등장하는 위치의 인덱스 반환
    }
}

 

너무 신박해서.. 현타오는 다른 사람들의 풀이 ㅎㅎ;

  1. B.repeat(3): 문자열 B를 3번 반복하여 새로운 문자열 tempB를 생성합니다.
  2. tempB.indexOf(A): 생성된 문자열 tempB에서 문자열 A가 처음 등장하는 위치의 인덱스를 반환합니다. 만약 A가 tempB에 없다면 -1을 반환합니다.

여기서 문자열 B를 3번 반복한다는게 무슨 뜻이냐?

문자열 B를 3번 반복한다는 것은 문자열 B를 3번 이어붙인 새로운 문자열을 만든다는 의미입니다. 예를 들어, B가 "abc"라면, B를 3번 반복한 문자열은 "abcabcabc"가 됩니다.

그 후에는 tempB.indexOf(A)를 사용하여 문자열 A가 tempB에서 처음 등장하는 위치의 인덱스를 찾습니다. 이 위치를 반환합니다. 만약 A가 tempB에 존재하지 않으면 -1이 반환됩니다.

 


 

2️⃣ 종이 자르기

 

문제 설명

머쓱이는 큰 종이를 1 x 1 크기로 자르려고 합니다. 예를 들어 2 x 2 크기의 종이를 1 x 1 크기로 자르려면 최소 가위질 세 번이 필요합니다.

정수 M, N이 매개변수로 주어질 때, M x N 크기의 종이를 최소로 가위질 해야하는 횟수를 return 하도록 solution 함수를 완성해보세요.

 

제한사항

  • 0 < M, N < 100
  • 종이를 겹쳐서 자를 수 없습니다.

입출력 예

M N result
2 2 3
2 5 9
1 1 0

 

입출력 예 #1

  • 본문과 동일합니다.

입출력 예 #2

  • 가로 2 세로 5인 종이는 가로로 1번 세로로 8번 총 가위질 9번이 필요합니다.

입출력 예 #3

  • 이미 1 * 1 크기이므로 0을 return 합니다.

 

💻 나의 풀이

class Solution {
    public int solution(int M, int N) {
        return (M*N)-1;
    }
}

 

그림이 나와서 쫄았지만 규칙을 찾아보니 넘나 쉬운 문제 였습니다!

 


 

3️⃣ 연속된 수의 합

 

문제 설명

연속된 세 개의 정수를 더해 12가 되는 경우는 3, 4, 5입니다. 두 정수 num과 total이 주어집니다. 연속된 수 num개를 더한 값이 total이 될 때, 정수 배열을 오름차순으로 담아 return하도록 solution함수를 완성해보세요.

 

제한사항

  • 1 ≤ num ≤ 100
  • 0 ≤ total ≤ 1000
  • num개의 연속된 수를 더하여 total이 될 수 없는 테스트 케이스는 없습니다.

입출력 예

num total result
3 12 [3, 4, 5]
5 15 [1, 2, 3, 4, 5]
4 14 [2, 3, 4, 5]
5 5 [-1, 0, 1, 2, 3]

 

입출력 예 #1

  • num = 3, total = 12인 경우 [3, 4, 5]를 return합니다.

입출력 예 #2

  • num = 5, total = 15인 경우 [1, 2, 3, 4, 5]를 return합니다.

입출력 예 #3

  • 4개의 연속된 수를 더해 14가 되는 경우는 2, 3, 4, 5입니다.

입출력 예 #4

  • 설명 생략

💻 나의 풀이

class Solution {
    public int[] solution(int num, int total) {
        int[] answer = new int[num];
        int mid = total / num;  // 연속된 수의 중앙값
        int first;  // 연속된 수의 첫 번째 값
        
        if(num % 2 == 0) {  // num이 짝수
            first = mid - num/2 + 1;
        } else {  // num이 홀수
            first = mid - num/2;
        }
        
        for(int i=0; i<num; i++) {  // 연속된 숫자 배열 생성
            answer[i] = first++;
        }
        
        return answer;
    }
}

 

오늘의 4개의 문제 중에 가장 헤맸던 문제입니다. 개념 자체는 어렵지 않은거 같은데 잘 안되더라구요.

먼저 결과를 저장할 배열의 길이를 num으로 초기화 했습니다.

그리고 연속된 수의 중간값을 계산해주는데 중간값은 total을 num으로 나누어 구할 수 있씁니다.

first는 연속된 수의 첫 번째 값을 담을 변수 입니다.

num이 짝수인 경우 즉, num이 2로 나누어 떨어질 때 첫번째 값은 중간값에서 num/2를 빼주고 1을 더해줘야만 합니다.

num이 홀수인 경우 즉, num이 2로 나누어 떨어지지 않을 때의 첫번째 값은 중간값에서 num/2를 빼주면 됩니다.

num만큼 순회하는 for 루프를 통해서 배열 answer을 채워주고 반환해줍니다.

 

 

🔎 다른 사람의 풀이

class Solution {
    public int[] solution(int num, int total) {
        // 결과를 저장할 배열 초기화
        int[] answer = new int[num];
        
        // 등차수열의 합을 계산하여 check에 저장
        int check = num * (num + 1) / 2;
        
        // 시작 숫자 계산
        int start = (total - check) / num + 1;
        
        // 배열에 순차적으로 값을 할당
        for (int i = 0; i < answer.length; i++) {
            answer[i] = start + i;
        }
        
        // 결과 배열 반환
        return answer;
    }
}

 

수학 공식을 활용한 풀이 입니다.

1부터 n까지의 자연수 합을 구하는 공식은 (n*(n+1)) / 2 입니다.

이 공식을 활용하여 기본형 total 값에서 구하려고 하는 total 값을 빼고 시작점을 찾기 위해 num으로 나눈 후에 1를 더해줍니다.

  1. check = num * (num + 1) / 2: 등차수열의 합 공식을 이용하여 연속된 숫자의 합을 계산합니다.
  2. start = (total - check) / num + 1: 시작 숫자를 계산합니다. 총 합에서 등차수열의 합을 빼고, 숫자의 개수로 나눈 값에 1을 더합니다.
  3. for 루프를 통해 배열 answer를 채웁니다. 시작하는 숫자는 start이며, 순서대로 증가하면서 배열에 저장합니다.
  4. 생성된 배열 answer를 반환합니다.

 

 


 

4️⃣ 다음에 올 숫자

 

문제 설명

등차수열 혹은 등비수열 common이 매개변수로 주어질 때, 마지막 원소 다음으로 올 숫자를 return 하도록 solution 함수를 완성해보세요.

 

제한사항

  • 2 < common의 길이 < 1,000
  • -1,000 < common의 원소 < 2,000
    • common의 원소는 모두 정수입니다.
  • 등차수열 혹은 등비수열이 아닌 경우는 없습니다.
  • 등비수열인 경우 공비는 0이 아닌 정수입니다.

입출력 예

common result
[1, 2, 3, 4] 5
[2, 4, 8] 16

 

입출력 예 #1

  • [1, 2, 3, 4]는 공차가 1인 등차수열이므로 다음에 올 수는 5이다.

입출력 예 #2

  • [2, 4, 8]은 공비가 2인 등비수열이므로 다음에 올 수는 16이다.

💻 나의 풀이

class Solution {
    public int solution(int[] common) {
        int answer = 0;
        
        // 등차수열인 경우
        if(common[1]-common[0] == common[2]-common[1]) {
            answer = common[common.length-1] + (common[1]-common[0]);
        } else {  // 등비수열인 경우
            answer = common[common.length-1] * (common[1]/common[0]);
        }
        
        return answer;
    }
}

 

등차수열 등비수열 이라는 단어를 본 게 너무 오랜만이에요...

 

 


 

 

이렇게 드디어 0단계가 끝났습니다...!

일단 하루에 4문제씩 꾸준히 풀고 풀이를 이해하면서 기록하자고 다짐했던 것이 지켜져서 만족스럽습니다.

그리고 if문, for문 등의 간단한 문법들과 여러가지 함수들 그리고 기본적인 풀이법들이 많이 체화된 것 같은 느낌이 듭니다. 수업듣는다, 자바 언어 공부한다, 프로젝트 한다 등등의 핑계로 코테 푸는 것을 미뤘었는데...살짝 후회가 되네요. 잘 몰라도 더 일찍 시작했다면 좋았을 걸 싶어요. 확실히 직접 부딪히고 써보니까 백날천날 강의 듣는 것보다 습득이 되는 느낌이 확 들거든요. 

 

앞으로의 계획은

0단계 중에 특히나 어려웠던 문제들을 다시 한번씩 보고 더 효율적인 풀이도 있는지 고민해보는 시간을 가질겁니다.

그 후엔 알고리즘에 관한 강의를 하나 들으면서 1단계를 시작해볼까 해요. 속도가 좀 더디더라도 기본적인 개념을 좀 잡고 가야 훨씬 효율적인 풀이가 나올 것 같습니다. 😀

공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
TAG
more
«   2024/05   »
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
글 보관함