알고리즘 풀이 방법입니다.
문제(Problem) -> 생각(Think) -> 해결책(Solution) -> 리뷰(Review) 를 통해서 정리해서 작성합니다.
Problem📄

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

 

코딩테스트 연습 - 문자열 내림차순으로 배치하기

문자열 s에 나타나는 문자를 큰것부터 작은 순으로 정렬해 새로운 문자열을 리턴하는 함수, solution을 완성해주세요. s는 영문 대소문자로만 구성되어 있으며, 대문자는 소문자보다 작은 것으로

programmers.co.kr


Think🤔

char 배열로 담아서 거꾸로 출력하면 된다

또는 아스키 코드 값을 비교해서 제일 큰 값이 앞으로 오게하면 된다.


Solution✍
import java.util.Arrays;

class Solution {
    public String solution(String s) {
        String answer = "";
        char[] ch = s.toCharArray();
        Arrays.sort(ch);
        for(int i=ch.length; i>0; i--){
            answer += ch[i-1];
        }
        
        return answer;
    }
}

for문쪽 이렇게 살짝 변경 가능 

        for(int i=ch.length-1; i>=0; i--){
            answer += ch[i];
        }

 

StringBuilder 응용 코드

import java.util.Arrays;

class Solution {
    public String solution(String s) {
        char[] ch = s.toCharArray();
        Arrays.sort(ch);
        return new StringBuilder(new String(ch,0,ch.length)).reverse().toString();
    }
}

Review🤩

StringBuilder reverse를 사용했고 그냥 reverse만 사용하면 문자를 큰 것 부터 작은 것 까지 정렬하는 부분이 없어서,

Array.sort(ch)로 배열을 뒤집었다.


 

알고리즘 풀이 방법입니다.
문제(Problem) -> 생각(Think) -> 해결책(Solution) -> 리뷰(Review) 를 통해서 정리해서 작성합니다.
Problem📄

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

 

코딩테스트 연습 - 수박수박수박수박수박수?

길이가 n이고, "수박수박수박수...."와 같은 패턴을 유지하는 문자열을 리턴하는 함수, solution을 완성하세요. 예를들어 n이 4이면 "수박수박"을 리턴하고 3이라면 "수박수"를 리턴하면 됩니다. 제한

programmers.co.kr


Think🤔

전에 풀었던 문제다.

1이면 수 2면 수박 3이면 수박수

이런식으로 푸는 방법이다


Solution✍
class Solution {
    public String solution(int n) {
        String answer = "";
        
        for(int i=0; i<n; i++){
            if(i % 2 == 0){
                answer+="수";
            }else{
                answer+="박";
            }
        }
        
        return answer;
    }
}

Review🤩

쉬운 문제였다.


 

알고리즘 풀이 방법입니다.
문제(Problem) -> 생각(Think) -> 해결책(Solution) -> 리뷰(Review) 를 통해서 정리해서 작성합니다.
Problem📄

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

 

코딩테스트 연습 - 최대공약수와 최소공배수

두 수를 입력받아 두 수의 최대공약수와 최소공배수를 반환하는 함수, solution을 완성해 보세요. 배열의 맨 앞에 최대공약수, 그다음 최소공배수를 넣어 반환하면 됩니다. 예를 들어 두 수 3, 12의

programmers.co.kr


Think🤔

두 개의 파라미터 값을 받아서 정수형 배열로 최대공약수와 최소공배수를 return하는 문제이다.

최대 공약수는 더 낮은 값에서 둘다 나뉘어 1부터 비교해서 나눠 떨어지면 최대 공약수가 나온다.

최소 공배수가 좀 어렵다..

구하는 방법은 아는데 막상 알고리즘으로 풀려고 하니 생각이 안난다... 흠....

 

구하는 방법을 식으로 적어보니

둘을 동시에 나누면서 그 값이 이제 동시에 나눠지지 않을때 각각 값이 남는데 그 값을 "서로소"라고 하고 그 서로소 두개를 곱해주면 최소 공배수가 된다.

 

그럼 이제 동시에 나누는 방법을 적용한다.

생각해보면 이미 서로소를 구하는 방법은 쉽다. 아까 구했던 최대 공약수로 각각 n과 m값을 나눠주면 서로소 값이 나온다.


Solution✍
class Solution {
    public int[] solution(int n, int m) {
        int[] answer = new int[2];
        
        // 둘 중 더 작은거까지 조사
        int small = Math.min(n,m);
        //최대공약수
        for(int i=1; i<=small; i++){
            if(n%i == 0 && m%i == 0){
                answer[0] = i;
            }
        }
        
        //최소공배수
        n = n/answer[0];
        m = m/answer[0];
        answer[1] = n * m * answer[0];
        return answer;
    }
}

마지막 최소 공배수를 구한 부분을 살짝 줄여보자면

class Solution {
    public int[] solution(int n, int m) {
        int[] answer = new int[2];
        
        // 둘 중 더 작은거까지 조사
        int small = Math.min(n,m);
        //최대공약수
        for(int i=1; i<=small; i++){
            if(n%i == 0 && m%i == 0){
                answer[0] = i;
            }
        }
        
        answer[1] = (n * m) / answer[0];
        return answer;
    }
}

Review🤩

재귀 함수적으로 짜는 코드법을 보았다.

static을 이용해서 새 메서드를 만들어서 재귀적으로 짜는 방법.. (다른 사람 코드)

class Solution {
    public int[] solution(int n, int m) {
        int[] answer = new int[2];
        answer[0] = gcd(n,m);
        answer[1] = (n*m)/answer[0];
        return answer;
    }
    public static int gcd(int p, int q){
        if (q==0) return p;
        return gcd(q, p%q);
    }
}

wow..

첫 번째 answer[0]에 최대 공약수를 넣어주는데 gcd라는 메서드를 먼저 생성한다.

p%q로 3을 12로 나눈 나머지는 0이 돼서 다시 gcd를 타는데 그러면 if 조건에 걸려서 3을 반환시킨다..


 

알고리즘 풀이 방법입니다.
문제(Problem) -> 생각(Think) -> 해결책(Solution) -> 리뷰(Review) 를 통해서 정리해서 작성합니다.
Problem📄

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

 

코딩테스트 연습 - 정수 제곱근 판별

임의의 양의 정수 n에 대해, n이 어떤 양의 정수 x의 제곱인지 아닌지 판단하려 합니다. n이 양의 정수 x의 제곱이라면 x+1의 제곱을 리턴하고, n이 양의 정수 x의 제곱이 아니라면 -1을 리턴하는 함

programmers.co.kr


Think🤔

정수 n에 대해

n이 어떤 정수 x의 제곱인지 아닌지를 판단함

제곱을 판단하는 것은 Math의 내장함수 중에 Math.sqrt()가 존재한다.

Math.sqrt()를 이용해서 150으로 먼저 확인해 본다.

제곱근이 없는 경우 어떻게 나타내는지.. 소수점으로 결과가 나온다.

이러면 양의 "정수" 제곱근이 아닌 것이다.

정수이면서 양수인 것을 제외한 값은 -1이 나오게 해야된다.


Solution✍
class Solution {
    public long solution(long n) {
        long answer = 0;
        if((Math.sqrt(n)*10)%10 == 0){
            answer = ((long)Math.sqrt(n)+1) * ((long)Math.sqrt(n)+1);
        }else{
            answer = -1;
        }
        return answer;
    }
}

long타입을 명시하지 않으면 double 형이 되는데 왜 더블형이 되는걸까?

 

Math.sqrt() 메소드는 입력값과 출력값은 모두 double형 으로 나온다고 한다.

고로, 형 변환이 필요한 부분!

 

다른 방법은 없을까? Math.sqrt를 이용하지 않고 제곱근을 구하는 공식을 검색해보았다.

 

조선시대 제곱근 구하는 방법

조선시대 방법이 존재했다.

나눗셈과 뺼셈만으로도 제곱근을 구했다고 한다.

 

제곱근을 구하려고 하는 수를 2로 맨처음에 나눈다!

그리고 1부터 차례대로 나온 값에서 빼주고 그 값이 마이너스가 되기전까지 빼면 제곱근이 나온다고 한다.

바로 적용해 보았다.

 

양의 정수 제곱값은 올바르게 나온다.

제곱이 아니라면 ?

class Solution {
    public long solution(long n) {
        long answer = 0;
        
        // 제곱근
        long root = 0;
        
        // 처음에 2로 나눔
        n = n / 2;
        
        long count = 1;
        
        while(n > 0){
            if(n - count < 0){
                break;
            }
            n -= count;
            root++;
            count++;
        }
        
        root = root+1;
        System.out.println(n + " : " + root);
        if(n*2 != root){
            return -1;
        }
        
        answer = (root+1)*(root+1);
        
        return answer;
    }
}

뭐가 잘못됐을까? Sysout으로 찍어보고 노트에 적어봤는데

n의 값이 5.5가 나와야 되는데 5로 나오고 있엇다.

n root
60.5 1
59.5 2
57.5 3
54.5 4
50.5 5
45.5 6
39.5 7
32.5 8
24.5 9
15.5 10
5.5 11
class Solution {
    public long solution(long nL) {
        long answer = 0;
        
        // 제곱근
        long root = 1;
        
        // 처음에 2로 나눔 double 형으로 바꿔야 함
        double n = (double)nL / 2;
        
        while(n > 0){
            if(n - root < 0){
                break;
            }
            n -= root;
            root++;
        }
        
        // 남은수의 2를 곱한 값이 while문을 돌린 횟수랑 같으면 제곱근, 아니면 -1
        if(n*2 != root){
            return -1;
        }
        
        answer = (root+1)*(root+1);
        
        return answer;
    }
}

double형으로 바꿔주니 정상적을 작동한것을 확인했다.

 

Math.pow()

Math.pow()함수를 이용하면 더 깔끔하게 짤 수 있다. pow또한 인자 두개를 받고, 둘다 double형이다.

class Solution {
    public long solution(long n) {
        
        double sqr = (int)Math.sqrt(n);
        // 만약 제곱근이 맞으면
        if(Math.pow(sqr,2) == n){
            return (long)Math.pow(sqr+1,2);
        } else{
            return -1;
        }
    }
}

삼항 연산자로 바꿔본다.

class Solution {
    public long solution(long n) {
        double sqr = (int)Math.sqrt(n);
        // 만약 제곱근이 맞으면
        return Math.pow(sqr,2) == n ? (long)Math.pow(sqr+1,2) : -1;
    }
}

Review🤩

sqrt의 입력값과 반환값이 double형 타입임을 알게 되었다.

삼항 연산자를 알 수 있었고, 조선 시대 제곱근 구하는 방법도 신박했다!


알고리즘 풀이 방법입니다.
문제(Problem) -> 생각(Think) -> 해결책(Solution) -> 리뷰(Review) 를 통해서 정리해서 작성합니다.
Problem📄

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

 

코딩테스트 연습 - 콜라츠 추측

1937년 Collatz란 사람에 의해 제기된 이 추측은, 주어진 수가 1이 될때까지 다음 작업을 반복하면, 모든 수를 1로 만들 수 있다는 추측입니다. 작업은 다음과 같습니다. 1-1. 입력된 수가 짝수라면 2

programmers.co.kr


Think🤔

일단 방법에서 하라는대로 해본다.

짝수라면 2로 나누고, 또는 홀수라면 3을 곱하고 1을 더 해준다. 그리고 

결과가 1이 나올때까지 반복하고 그 과정이 반복될 때마다 카운트해주면 될 것 같다.


Solution✍
class Solution {
    public int solution(int num) {
        int answer = 0;
        if(num == 0){
            return -1;
        }
        
        while(num != 1){
            if(answer >= 500){
                return -1;
            }
            if(num % 2 == 0){
                num/=2;
                answer++;
            }else{
                num = num * 3 + 1;
                answer++;
            }
        }
        return answer;
    }
}

문제가 말한대로 짯는데 500번 시도해도 1이 되지 못하면 -1이 되어야 하는데

626331은 488번에 풀린다 근데 이게 overflow가 되면서 중간에 값의 범위를 아마 넘어가지 못하는 것 같다.

class Solution {
    public int solution(int num) {
        int answer = 0;
        long longNum = (long)num;
        if(num == 0){
            return -1;
        }
        
        while(longNum != 1){
            if(longNum % 2 == 0){
                longNum/=2;
            }else{
                longNum = longNum * 3 + 1;
            }
            answer++;
            
            if(answer >= 500){
                return -1;
            }
        }
        return answer;
    }
}

Review🤩

오버플로우(넘쳐흐른다)가 발생할 수 있으므로 이 부분도 잘 생각해서 코딩을 해야겠다.


 

알고리즘 풀이 방법입니다.
문제(Problem) -> 생각(Think) -> 해결책(Solution) -> 리뷰(Review) 를 통해서 정리해서 작성합니다.
Problem📄

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

 

코딩테스트 연습 - 짝수와 홀수

정수 num이 짝수일 경우 "Even"을 반환하고 홀수인 경우 "Odd"를 반환하는 함수, solution을 완성해주세요. 제한 조건 num은 int 범위의 정수입니다. 0은 짝수입니다. 입출력 예 num return 3 "Odd" 4 "Even"

programmers.co.kr


Think🤔

엄청 쉬운문제 2로 나눠지면 짝수, 아니면 홀수이다.


Solution✍
class Solution {
    public String solution(int num) {
        String answer = "";
        if(num % 2 == 0){
            answer = "Even";
        }else{
            answer ="Odd";
        }
        return answer;
    }
}
class Solution {
    public String solution(int num) {
        return num % 2 == 0 ? "Even" : "Odd";
    }
}

Review🤩

삼항 연산자, 그리고 2로 나눠서 나머지가 없으면 짝수 인 것!


 

+ Recent posts