자바 배열 내용 출력하는 방법 (2가지)
배열 내용 출력하는 방법배열은 단순 System.out.println으로 출력 시 아래와 같이 원하는 값으로 출력되지 않는다.         int[] arr = {0, 1, 2, 4, 3};                  System.out.println(arr);         // 출력: [I@b4c966a  따라서 배열의 요소들을 확인하고 싶을 경우 다른 추가적인 방법을 사용해야 하는데, 배열 내용을 출력하는 방법 중 가장 많이 사용되는 것은 2가지가 있다.  반복문을 이용한 출력for문, while문 등을 통해 배열의 인덱스 하나 하나 들어가 요솟값을 출력한다.형변환을 이용한 출력Arrays 메서드인 toString()를 사용하여 문자형으로 형변환하여 출력한다.   1. 반복문을 이용한 출력 ..
2024.04.29
no image
프로그래머스: 큰 수 만들기 (자바, Java)
[프로그래머스] 큰 수 만들기 (Lv.2)https://school.programmers.co.kr/learn/courses/30/lessons/42883  문제어떤 숫자에서 k개의 수를 제거했을 때 얻을 수 있는 가장 큰 숫자를 구하려 한다.예를 들어, 숫자 1924에서 수 두 개를 제거하면 [19, 12, 14, 92, 94, 24] 를 만들 수 있으며, 이 중 가장 큰 숫자는 94이다.문자열 형식으로 숫자 number와 제거할 수의 개수 k가 solution 함수의 매개변수로 주어진다.  number에서 k 개의 수를 제거했을 때 만들 수 있는 수 중 가장 큰 숫자를 문자열 형태로 return 하도록 solution 함수를 완성하라.   나의 답안(오답)내가 생각한 구조는 다음과 같다.  가장 큰 ..
2024.04.28
프로그래머스: 구명보트 (자바, Java)
[프로그래머스] 구명보트 (Lv.2)https://school.programmers.co.kr/learn/courses/30/lessons/42885  문제사람들을 구명보트를 이용하여 구출하려고 한다. 구명보트는 한 번에 최대 2명까지만 탈 수 있고, 무게 제한도 있다.예를 들어, 사람들의 몸무게가 [70kg, 50kg, 80kg, 50kg]이고 구명보트의 무게 제한이 100kg이라면 2번째 사람과 4번째 사람은 같이 탈 수 있지만 1번째 사람과 3번째 사람의 무게의 합은 150kg이므로 구명보트의 무게 제한을 초과하여 같이 탈 수 없다.구명보트를 최대한 적게 사용하여 모든 사람을 구출하려 하며, 사람들의 몸무게를 담은 배열 people과 구명보트의 무게 제한 limit가 매개변수로 주어질 때, 모든 사..
2024.04.27
프로그래머스: 체육복 (자바, Java)
[프로그래머스] 체육복 (Lv.1)   문제 점심시간에 도둑이 들어 일부 학생이 체육복을 도난당했다. 다행히 여벌 체육복이 있는 학생이 이들에게 체육복을 빌려주려 한다. 학생들의 번호는 체격 순으로 매겨져 있어, 바로  앞번호의 학생이나 바로 뒷번호의 학생에게만 체육복을 빌려줄 수 있다. 예를 들어, 3번 학생은 2번 학생이나 4번 학생에게만 체육복을 빌려줄 수 있다. 체육복이 없으면 수업을 들을 수 없으므로 체육복을 적절히 빌려 최대한 많은 학생이 체육수업을 들을 수 있도록 해야 한다.전체 학생의 수 n, 체육복을 도난당한 학생들의 번호가 담긴 배열 lost, 여벌의 체육복을 가져온 학생들의 번호가 담긴 배열 reserve가 매개변수로 주어질 때, 체육수업을 들을 수 있는 학생의 최댓값을 return ..
2024.04.26
no image
프로그래머스: 정수 삼각형 (자바, Java)
[프로그래머스] 정수 삼각형 (Lv.3)   문제        7      3  8    8  1  0  2  7  4  44  5  2  6  5  위와 같은 삼각형 배열의 꼭대기에서 바닥까지 경로 중 거쳐간 숫자의 합이 가장 큰 경우를 찾아보려고 한다. 아래 칸으로 이동할 때는 대각선 방향으로 한 칸 오른쪽 또는 왼쪽으로만 이동 가능하다. 예를 들어 3에서는 그 아래칸의 8 또는 1로만 이동이 가능하다. 삼각형의 정수들이 담긴 배열 triangle이 매개변수로 주어질 때 거쳐간 숫자의 최댓값을 return 하는 메서드를 완성하라.   나의 답안최근 싸피 준비를 하며 알고리즘 공부를 하고 있다.   우선 종이로 풀어봤을 때, 상단 좌 우 칸의 누적값 중 더 큰 값과 더했을 때 최대값이 될 것이다. 빨간..
2024.04.25
프로그래머스: 문자열 내 p와 y의 개수 (자바, Java)
[프로그래머스] 문자열 내 p와 y의 개수   문제정수 l과 r이 주어졌을 때, l 이상 r이하의 정수 중에서 숫자 "0"과 "5"로만 이루어진 모든 정수를 오름차순으로 저장한 배열을 return 하는 solution 메서드를 완성하시오만약 그러한 정수가 없다면, -1이 담긴 배열을 return 하시오   나의 답안 p와 y를 count 할 변수를 각각 1개씩 생성for문과 if문을 사용해 한 글자씩 대소문자 및 해당 문자 일치 여부 확인하여 일치하는 경우 count변수에 1씩 더함삼항연산자로 true / false 리턴 class Solution {     boolean solution(String s) {         boolean answer = true;      ..
2024.04.24
no image
자바 2차원 배열 사용
2차원 배열 구조, 특징 행과 열로 구성된 데이터 구조 구조 : 타입 [행] [열] 변수명; 2차원 배열 선언 방법 ▶ 배열 선언 후 배열 생성 int [ ][ ] arr; arr = new int [2][3]; ▶ 배열 선언 및 생성 int [ ][ ] arr = new int [2][3]; ▶ 초기값을 지정하여 배열 선언 int [ ][ ] arr = { {1, 2, 3}, {4, 5, 6} }; ※ 배열 선언 시, 열의 크기를 행마다 다르게 선언할 수 있다! int[][] arr = { {10, 20}, {10, 20, 30, 40}, {10} }; 2차원 배열 행, 열 개수 확인 1차원 배열에서 사용하는 length메서드를 2차원 배열에서 사용할 경우, 행의 개수가 반환된다. 열의 개수를 확인하려..
2024.04.22
자바 Integer 클래스 메서드 정리
Integer 클래스란? Java에서 정수와 관련된 유틸리티 메서드를 모아둔 클래스. int 타입의 데이터를 객체로 래핑하여 유용한 기능들을 제공함 String 클래스 메서드 종류 parseInt(String s): 문자열을 정수로 변환 String numStr = "123"; int num = Integer.parseInt(numStr); System.out.println(num); // 출력: 123 toString(int i): 정수를 문자열로 변환 int num = 123; String numStr = Integer.toString(num); System.out.println(numStr); // 출력: "123" int1.compareTo(int2): int1와 int2의 값을 비교 (int1 ..
2024.04.20
프로그래머스: 배열 만들기 2 (자바, Java)
[프로그래머스] 배열 만들기 2 문제 정수 l과 r이 주어졌을 때, l 이상 r이하의 정수 중에서 숫자 "0"과 "5"로만 이루어진 모든 정수를 오름차순으로 저장한 배열을 return 하는 solution 메서드를 완성하시오 만약 그러한 정수가 없다면, -1이 담긴 배열을 return 하시오 나의 답안 문제를 처음 보고 가장 먼저 생각한 구조는 아래와 같다. 1. l부터 r까지 숫자를 문자열로 형변환 2. 각 자리수가 5 혹은 0으로 이루어졌는지 체크 3. 해당 숫자만 리스트에 저장 4. 리스트를 배열로 변환하여 return 그러나 좀 더 괜찮은 방법이 없을까 아주 긴 시간 고민했다. (5로 나누고 10으로 나눴을 때 나머지가 0 또는 1이고 등등...) 그러다 생각해낸 것이 1. 숫자를 5로 나눴을 때..
2024.04.19
프로그래머스: 수 조작하기 2 (자바, Java)
[프로그래머스] 수 조작하기 2 문제 정수 배열 numLog가 주어집니다. 처음에 numLog[0]에서 부터 시작해 "w", "a", "s", "d"로 이루어진 문자열을 입력으로 받아 순서대로 다음과 같은 조작을 했다. "w" : 수에 1을 더한다. "s" : 수에 1을 뺀다. "d" : 수에 10을 더한다. "a" : 수에 10을 뺀다. 그리고 매번 조작을 할 때마다 결괏값을 기록한 정수 배열이 numLog 이다. 즉, numLog[i]는 numLog[0]로부터 총 i번의 조작을 가한 결과가 저장되어 있다. 주어진 정수 배열 numLog에 대해 조작을 위해 입력받은 문자열을 return 하는 solution 메서드를 완성하라 나의 답안 StringBulider 선언 발생할 수 있는 경우의 수가 4가지 ..
2024.04.17

배열 내용 출력하는 방법

배열은 단순 System.out.println으로 출력 시 아래와 같이 원하는 값으로 출력되지 않는다.

 

        int[] arr = {0, 1, 2, 4, 3};
        
        System.out.println(arr);
        // 출력: [I@b4c966a

 

 

따라서 배열의 요소들을 확인하고 싶을 경우

 

다른 추가적인 방법을 사용해야 하는데,

 

배열 내용을 출력하는 방법 중 가장 많이 사용되는 것은 2가지가 있다.

 

 

  1. 반복문을 이용한 출력
    for문, while문 등을 통해 배열의 인덱스 하나 하나 들어가 요솟값을 출력한다.

  2. 형변환을 이용한 출력
    Arrays 메서드인 toString()를 사용하여 문자형으로 형변환하여 출력한다.

 

 

 

1. 반복문을 이용한 출력

 

for문, while문 등 반복문을 통해 각 인덱스 값에 들어가 그 값을 하나씩 출력하는 방식이다.

 

       int[] arr = {0, 1, 2, 4, 3};

        for(int i=0; i<arr.length; i++) {
            System.out.print(arr[i]+" ");
        }    // 출력: 0 1 2 4 3
        
        
        int i = 0;
        while (i<arr.length) {
            System.out.print(arr[i++]+" ");
        }  // 출력: 0 1 2 4 3

 

 

 

 

 

 

 

2.  형변환을 이용한 출력

 

Arrays.toString(배열) 형식의 메서드를 사용하면, 간편하고 아름답게(?) 출력이 가능하다.

 

다만 Arrays 메서드이므로 import java.util.Arrays 해주어야 함.

 

        int[] arr = {0, 1, 2, 4, 3};

        System.out.println(Arrays.toString(arr));
        //출력: [0, 1, 2, 4, 3]

[프로그래머스] 큰 수 만들기 (Lv.2)

https://school.programmers.co.kr/learn/courses/30/lessons/42883

 

 

문제

어떤 숫자에서 k개의 수를 제거했을 때 얻을 수 있는 가장 큰 숫자를 구하려 한다.
예를 들어, 숫자 1924에서 수 두 개를 제거하면 [19, 12, 14, 92, 94, 24] 를 만들 수 있으며, 이 중 가장 큰 숫자는 94이다.
문자열 형식으로 숫자 number와 제거할 수의 개수 k가 solution 함수의 매개변수로 주어진다.  number에서 k 개의 수를 제거했을 때 만들 수 있는 수 중 가장 큰 숫자를 문자열 형태로 return 하도록 solution 함수를 완성하라.

 

 

 

나의 답안(오답)

내가 생각한 구조는 다음과 같다.

 

 

  1. 가장 큰 수가 되기 위해, 주어진 수의 맨 앞에서 k+1번째까지 숫자 중 가장 큰 수가 가장 앞에 놓여야 한다.
  2. 가장 앞에 놓일 수가 정해지고 나면, 그 뒤부턴 그 다음 자리의 숫자와 비교하여 더 작을 경우 하나씩 제거한다.
  3. k개만큼 제거되면 남은 숫자가 답이 된다!

 

 

이를 코딩으로 짜보았으나, 테스트케이스는 통과됐으나 오답으로 처리되었다.

다시 확인해보니 예외가 많았다.

 

다른 풀이법을 찾아보니, 굳이 k+1번째 자리에서 가장 큰 수를 찾을 필요 없이, 맨 앞자리부터 다음 숫자와 비교하여 더 작을 경우, 하나씩 제거해나가면 되는 문제였다..

 

 

<오답입니다>

class Solution {
    public String solution(String number, int k) {
        char[] num_char = number.toCharArray();
        char[] answer = new char[number.length()-k];
        int count = 0;
        answer[0] = num_char[0];

        for (int i=1; i<=k; i++) {
            if (answer[0] <num_char[i]) {
                answer[0] = num_char[i];
                count++;
            }
        }

        int j = 1;
        for (int i=count+1; i<num_char.length; i++) {
            if (count < k) {
                if (i != num_char.length-1 && num_char[i] < num_char[i+1]) {
                    count++;
                } else {
                    answer[j] = num_char[i];
                    j++;
                }
            } else {
                answer[j] = num_char[i];
                j++;
            }
        }

        return String.valueOf(answer);
    }
}

 

모범 답안

  1. 스택 타입의 변수 생성
  2. 다음 자리의 수와 비교하며 현재 숫자가 더 작을 경우 stack에서 제거 후 k값 1 감소
  3. k가 0이 되면 result값을 문자열로 변환하여 반환
import java.util.Stack;

class Solution {
    public String solution(String number, int k) {
        char[] result = new char[number.length() - k];
        Stack<Character> stack = new Stack<>();

        for (int i=0; i<number.length(); i++) {
            char c = number.charAt(i);
            while (!stack.isEmpty() && stack.peek() < c && k-- > 0) {
                stack.pop();
            }
            stack.push(c);
        }
        for (int i=0; i<result.length; i++) {
            result[i] = stack.get(i);
        }
        return new String(result);
    }
}

 

 

<테스트10 통과 X>
class Solution {

    public String solution(String number, int k) {
        StringBuilder sb = new StringBuilder(number);
        for (int i = 0; i+1 < sb.length() && k>0; i++) {
            if(sb.charAt(i) < sb.charAt(i+1)) {
                sb.deleteCharAt(i);
                i=-1;
                k--;
            }
        }
        if(k!=0)
            sb.delete(sb.length()-k, sb.length());
        return sb.toString();
    }
}

 

 

 

그냥 앞에서부터 1개씩 비교해가면 되는 것이었는데 굳이 어렵게 생각하여 풀지 못했다.

 

stack 타입을 이용하여 숫자를 앞에서부터 비교한다는 점이 포인트이다.

 

이런건 대체 어떻게 생각해내는 건지 참 신기하다.

 

나도 언젠간 이렇게 될 수 있겠지..?

 

 

 

 

 

 

복습

1. 문자열 -> 문자배열 : toCharArray()

String str = "abcde"
char[] arr = str.toCharArray();

for (char a: arr ) {
    System.out.println(a);
}     // 출력: a b c d e


2. 문자배열 > 문자열: String.valueOf(객체) / new String(객체)

String str = "abcde";
char[] arr = str.toCharArray();
String result = new String(arr);

System.out.println(String.valueOf(arr));
System.out.println(result);
    // 출력: abcde abcde

 

프로그래머스: 구명보트 (자바, Java)

친환경 개발자
|2024. 4. 27. 22:12

[프로그래머스] 구명보트 (Lv.2)

https://school.programmers.co.kr/learn/courses/30/lessons/42885

 

 

문제

사람들을 구명보트를 이용하여 구출하려고 한다. 구명보트는 한 번에 최대 2명까지만 탈 수 있고, 무게 제한도 있다.
예를 들어, 사람들의 몸무게가 [70kg, 50kg, 80kg, 50kg]이고 구명보트의 무게 제한이 100kg이라면 2번째 사람과 4번째 사람은 같이 탈 수 있지만 1번째 사람과 3번째 사람의 무게의 합은 150kg이므로 구명보트의 무게 제한을 초과하여 같이 탈 수 없다.


구명보트를 최대한 적게 사용하여 모든 사람을 구출하려 하며, 사람들의 몸무게를 담은 배열 people과 구명보트의 무게 제한 limit가 매개변수로 주어질 때, 모든 사람을 구출하기 위해 필요한 구명보트 개수의 최솟값을 return 하도록 solution 함수를 작성하라

 

 

 

나의 답안(오답)

문제를 풀 때 최대 인원 제한이 2명이라는 것을 미처 생각지 못했다...

 

최대한 limit에 딱 맞게 태우면 최소한으로 배를 사용할 수 있겠다는 생각에

각 인덱스값에 limit을 나눠보기도 하고, 더했을 때 limit에 딱 맞는 사람 먼저 태워 보내는 것 등

여러 알고리즘을 생각해 봤지만 딱 맞는 알고리즘을 생각해내지 못했다.

 

그래서 오름차순으로 정렬 후 가벼운 사람들 먼저 태우자는 생각을 하여

코드를 작성했지만 답이 계속 틀렸고,

 

뒤늦게 인원제한이 있다는 것을 깨닫고 코드를 다시 짰다 ㅠㅠ

 

  1.  오름차순으로 정렬
  2. 무게 제한에서 해당 인덱스 무게를 빼가며 무게제한을 초과하지 않을 때까지 연산
  3. 무게제한 초과 시 count변수에 1을 더함
  4. 마지막 인원까지 태워 count+1을 return

 

 

<오답입니다>

import java.util.Arrays;

class Solution {
    public int solution(int[] people, int limit) {
        int count = 0;        
        int limitcheck = limit;
        
        Arrays.sort(people);
        
        for (int i=0; i<people.length; i++) {
            if (limitcheck - people[i] >= 0) {
                limitcheck -= people[i];
            } else if (limitcheck - people[i] < 0) {
                count++;
                limitcheck = limit;
                
                
        }
        
        return count+1;
    }
}

 

 

모범 답안

  1. 오름차순 정렬
  2. 좌우 동시 비교를 위한 인덱스 변수(i, j) 생성
  3. 가장 무거운 사람과 가벼운 사람의 합이 limit을 넘지 않으면 2명을 태우고(++i), 넘을 경우 무거운 사람만 태움
import java.util.Arrays;

class Solution {
    public int solution(int[] people, int limit) {
        Arrays.sort(people);

        int i = 0, j = people.length - 1;
        for (; i < j; --j) {
            if (people[i] + people[j] <= limit)
                ++i;
        }
        return people.length - i;
    }
}

 

  • 따로 count변수를 생성하지 않고 people.length-i로 값을 return한 것이 인상적이다.
    전부 1명씩만 태우면 people.length만큼 태웠을 것이고, 2명을 태웠다면 그 수만큼 i값을 올려 굳이 변수를 선언하지 않아도 결과값을 리턴할 수가 있는 것이다. 

 

 

 

복습

      for문의 예외형식

1. 초기값 생략 가능

int i=0;
for ( ; i<5; i++) {
    System.out.println(i);
}     // 출력: 0 1 2 3 4

 


2. 초기, 증감 생략 가능

int i=0;
for ( ; i<5; ) {
    System.out.println(i);
    i++;
}     // 출력: 0 1 2 3 4

 

 

3. 초기, 증감 여러 개 포함 가능

for (int i=0, j=0; i+j<6; i++, j+=2) {
    System.out.println(i+j);
}     // 출력: 0 3

 

프로그래머스: 체육복 (자바, Java)

친환경 개발자
|2024. 4. 26. 19:35

[프로그래머스] 체육복 (Lv.1)

 

 

 

문제

 점심시간에 도둑이 들어 일부 학생이 체육복을 도난당했다.

 다행히 여벌 체육복이 있는 학생이 이들에게 체육복을 빌려주려 한다. 학생들의 번호는 체격 순으로 매겨져 있어, 바로  앞번호의 학생이나 바로 뒷번호의 학생에게만 체육복을 빌려줄 수 있다.

 예를 들어, 3번 학생은 2번 학생이나 4번 학생에게만 체육복을 빌려줄 수 있다. 체육복이 없으면 수업을 들을 수 없으므로 체육복을 적절히 빌려 최대한 많은 학생이 체육수업을 들을 수 있도록 해야 한다.

전체 학생의 수 n, 체육복을 도난당한 학생들의 번호가 담긴 배열 lost, 여벌의 체육복을 가져온 학생들의 번호가 담긴 배열 reserve가 매개변수로 주어질 때, 체육수업을 들을 수 있는 학생의 최댓값을 return 하도록 solution 함수를 작성하라.

 

 

   단,

  • 전체 학생의 수는 2명 이상 30명 이하
  • 체육복을 도난당한 학생의 수는 1명 이상 n명 이하, 중복되는 번호 없음
  • 여벌의 체육복을 가져온 학생의 수는 1명 이상 n명 이하, 중복되는 번호 없음
  • 여벌 체육복이 있는 학생만 다른 학생에게 체육복을 빌려줄 수 있음
  • 여벌 체육복을 가져온 학생이 체육복을 도난당했을 수 있음. 이때 이 학생은 체육복을 하나만 도난당했다고 가정하며, 남은 체육복이 하나이므로 다른 학생에게는 체육복을 빌려줄 수 없음

 

 

 

나의 답안

 

  1.  lost배열 및 reserve배열 오름차순 정렬

  2. 수업을 들을 수 없는 학생을 세기 위한 count 변수 생성

  3. 도난당한 학생 중 여벌 체육복이 있는 경우, 본인 체육복을 입도록 우선 제거
    이후 해당 학생 번호를 -1로 변경하여 중복 방지

  4. 잃어버린 학생 번호의 앞 뒤 번호 학생 중 여벌 옷을 가져온 학생이 있을 경우
    count변수 1 감소 및 빌려준 학생 번호를 -1로 변경

 

import java.util.*;

class Solution {
    public int solution(int n, int[] lost, int[] reserve) {
        
        Arrays.sort(lost);
        Arrays.sort(reserve);

        int count = lost.length;
        for (int i=0; i<lost.length; i++) {
            int a = lost[i];

            for (int j = 0; j < reserve.length; j++) {
                if (reserve[j] == a) {
                    reserve[j] = -1;
                    lost[i] = -1;
                    count--;
                    break;
                }
            }
        }

        for (int i=0; i<lost.length; i++) {
            int a = lost[i];

            for (int j=0; j<reserve.length; j++) {
                if (reserve[j] == a-1) {
                    reserve[j] = -1;
                    count--;
                    break;
                } else if (reserve[j] == a+1) {
                    reserve[j] = -1;
                    count--;
                    break;
                }
            }
        }

        return n-count;
    }
}

 

 

모범 답안

  1. 크기가 n인 people변수 생성 (인덱스 0부터 학생 1번에 해당)

  2. 도난당한 학생 및 여벌 옷 있는 학생 번호에 해당하는 people 인덱스 값에 각각  -1, +1 해줌 
    (위 과정에서 여벌옷이 있으면서 도난당한 학생은 자동으로 처리됨)

  3. 1번 학생(people[0])부터, 앞 뒤 번호에 여벌옷이 있는 경우 즉, +1값인 경우 옷을 빌림

  4. 해당하지 않으면 answer -1
class Solution {
    public int solution(int n, int[] lost, int[] reserve) {
        int[] people = new int[n];      //크기가 n인 people변수 생성 (인덱스 0부터 학생 1번에 해당)

        int answer = n;

        for (int l : lost) 
            people[l-1]--;     //도난당한 학생 위치의 값 -1
        for (int r : reserve) 
            people[r-1]++;   //여벌 옷 있는 학생 위치의 값 +1

        for (int i = 0; i < people.length; i++) {
            if(people[i] == -1) {
                if(i-1>=0 && people[i-1] == 1) {
                    people[i]++;
                    people[i-1]--;
                }else if(i+1< people.length && people[i+1] == 1) {
                    people[i]++;
                    people[i+1]--;    // 앞 뒤 학생 중 여벌 옷이 있을 경우 빌림
                }else 
                    answer--;    // 없을 경우 수업을 들을 수 없으므로 answer -1
            }
        }
        return answer;
    }
}

 

  • 변수를 새로 생성해줌으로써 도난당한 학생 중 여벌 옷이 있는 학생을 거를 수 있음
  • 그에 더하여 for문을 간소화하고 이중 for문 사용을 하지 않아 훨씬 효율적이다.

 

 

 

복습

      ★크기를 지정하여 정수 배열을 선언할 경우, 기본 값은 0

 

        int[] arr = new int[5];
        for (int a : arr)
        System.out.print(a);     // 출력 : 00000

[프로그래머스] 정수 삼각형 (Lv.3)

 

 

 

문제

        7

      3  8

    8  1  0

  2  7  4  4

4  5  2  6  5

 

 위와 같은 삼각형 배열의 꼭대기에서 바닥까지 경로 중 거쳐간 숫자의 합이 가장 큰 경우를 찾아보려고 한다. 아래 칸으로 이동할 때는 대각선 방향으로 한 칸 오른쪽 또는 왼쪽으로만 이동 가능하다. 예를 들어 3에서는 그 아래칸의 8 또는 1로만 이동이 가능하다.

 삼각형의 정수들이 담긴 배열 triangle이 매개변수로 주어질 때 거쳐간 숫자의 최댓값을 return 하는 메서드를 완성하라.

 

 

 

나의 답안

최근 싸피 준비를 하며 알고리즘 공부를 하고 있다.

 

 

 

우선 종이로 풀어봤을 때,

 

상단 좌 우 칸의 누적값 중 더 큰 값과 더했을 때 최대값이 될 것이다.

 

빨간 펜이 최대 누적값임.

 

 

class Solution {
    public int solution(int[][] triangle) {
        int[][] dt = new int[triangle.length][];
        dt[0] = new int[]{triangle[0][0]};
        int answer = 0;

        for (int i=1; i<triangle.length; i++) {
            dt[i] = new int[i + 1];

            for (int j=0; j<=i; j++) {
                int base = triangle[i][j];
                int l = j-1 >= 0 ? dt[i-1][j-1] : 0;
                int r = j!=i ? dt[i-1][j] : 0;

                dt[i][j] = Math.max(base + l, base + r);


                if (answer < dt[i][j]) {
                    answer = dt[i][j];
                }
            }
        }
        return answer;
    }
}

 

 

 

모범 답안

 

import java.util.*;

class Solution {
    public int solution(int[][] triangle) {
        for (int i = 1; i < triangle.length; i++) {
            triangle[i][0] += triangle[i-1][0];
            triangle[i][i] += triangle[i-1][i-1];
            for (int j = 1; j < i; j++) 
                triangle[i][j] += Math.max(triangle[i-1][j-1], triangle[i-1][j]);
        }

        return Arrays.stream(triangle[triangle.length-1]).max().getAsInt();
    }
}
  • 별도의 누적합을 담는 배열을 별도로 생성하지 않고, triangle 배열에 누적합으로 수정 입력
  • 삼각형 모서리 부분 누적합을 먼저 처리하여 불필요한 삼항연산자 사용 방지

 

내 답안과 구조는 비슷했지만, 

훨씬 더 효율적이고 가독성이 좋은 답안이었다.

이런 아이디어를 만드는 것에 더 신경써야겠다.

 

 

 

 

복습

       2차원배열 선언 시에는 각 행에 대해 배열을 각각 초기화해주어야 한다!

    int[][] dt = new int[3][];
    dt[0] = new int[]{2};  // 각 행의 크기를 적절히 초기화
    dt[1] = new int[]{2,3};
    dt[2] = new int[]{2,3,4};

[프로그래머스] 문자열 내 p와 y의 개수

 

 

 

문제

정수 l과 r이 주어졌을 때, l 이상 r이하의 정수 중에서 숫자 "0"과 "5"로만 이루어진 모든 정수를 오름차순으로 저장한 배열을 return 하는 solution 메서드를 완성하시오

만약 그러한 정수가 없다면, -1이 담긴 배열을 return 하시오

 

 

 

나의 답안

 

  1. p와 y를 count 할 변수를 각각 1개씩 생성

  2. for문과 if문을 사용해 한 글자씩 대소문자 및 해당 문자 일치 여부 확인하여
    일치하는 경우 count변수에 1씩 더함

  3. 삼항연산자로 true / false 리턴

 

class Solution {
    boolean solution(String s) {
        boolean answer = true;
        int countP = 0;
        int countY = 0;
        
        for (int i=0; i<s.length(); i++) {
            if (s.charAt(i) == 'p' || s.charAt(i) == 'P') {
                countP++;
            } else if(s.charAt(i) == 'y' || s.charAt(i) == 'Y') {
                countY++;
            }
        }
        
        return countP==countY ? true : false;
    }
}

 

 

모범 답안

 

class Solution {
    boolean solution(String s) {
        s = s.toLowerCase();
        int count = 0;

        for (int i = 0; i < s.length(); i++) {

            if (s.charAt(i) == 'p')
                count++;
            else if (s.charAt(i) == 'y')
                count--;
        }

       return count==0;
    }
}

 

    배운 점

  • toLowerCase() 메서드를 통해 모두 소문자로 통일시킴
  • count변수를 1개만 생성해도 증감연산자(++,--)를 활용하여 p와 y 개수 비교 가능
  • count==0 을 리턴하면 삼항연산자 사용할 필요 없이 true / false를 반환할 수 있다

 

 

 

위 세가지 모두 아이디어가 좋아 배워야 할 점이다.

무언가 만들 때 어떻게 하면 효율적이고 간결할지,

좀 더 다른 방향으로 생각해야 한다는 것을 또 한 번 느꼈다.

 

자바 2차원 배열 사용

친환경 개발자
|2024. 4. 22. 23:07

2차원 배열 구조, 특징 

 

  • 행과 열로 구성된 데이터 구조

  • 구조   :   타입 [행] [열]   변수명;

 

 

 

 

2차원 배열 선언 방법

 

▶ 배열 선언 후 배열 생성
      int [ ][ ] arr;
      arr = new int [2][3];


  배열 선언 및 생성
       int [ ][ ] arr = new int [2][3];

 

  초기값을 지정하여 배열 선언

        int [ ][ ] arr = { {1, 2, 3}, {4, 5, 6} };

 

 

 

   ※ 배열 선언 시, 열의 크기를 행마다 다르게 선언할 수 있다!

          int[][] arr = {
               {10, 20},
               {10, 20, 30, 40},
               {10}
               };

 

 

2차원 배열 행, 열 개수 확인

 

1차원 배열에서 사용하는 length메서드를 2차원 배열에서 사용할 경우, 행의 개수가 반환된다.
열의 개수를 확인하려면, 확인하고자 하는 행의 인덱스를 넣어야 함

int rows = array.length; // 행의 개수
int cols = array[0].length; // 첫 번째 행의 열의 개수

 

자바 Integer 클래스 메서드 정리

친환경 개발자
|2024. 4. 20. 22:10

Integer 클래스란?

Java에서 정수와 관련된 유틸리티 메서드를 모아둔 클래스.

int 타입의 데이터를 객체로 래핑하여 유용한 기능들을 제공함

 

 

 

 

String 클래스 메서드 종류

  1. parseInt(String s): 문자열을 정수로 변환

    String numStr = "123";
    int num = Integer.parseInt(numStr);
    System.out.println(num); // 출력: 123


  2. toString(int i): 정수를 문자열로 변환

    int num = 123;
    String numStr = Integer.toString(num);
    System.out.println(numStr); // 출력: "123"


  3. int1.compareTo(int2): int1와 int2의 값을 비교 (int1 > int2: 1 / int1 < int2: -1 / int == int2: 0)

    Integer num1 = 100;
    Integer num2 = 200;
    int result = num1.compareTo(num2);
    System.out.println(result); // 출력: -1


  4. intValue(): Integer 객체의 값을 int형으로 반환

    Integer num = 123;
    int intValue = num.intValue();
    System.out.println(intValue); // 출력: 123


  5. valueOf(int i): 주어진 int 값을 Integer 객체로 변환하여 반환

    int num = 123;
    Integer integerObj = Integer.valueOf(num);
    System.out.println(integerObj); // 출력: 123

  6. toBinaryString(int n): 정수를 2진수 문자열로 변환

     
  7. bitCount(int n): 정수의 2진수 표현에서 1의 개수 반환

    int num = 10; // 이진수: 1010 (2진수로 1의 개수)
    int count = Integer.bitCount(num);
    System.out.println(count); // 출력: 2


  8. reverse(int i): 정수의 비트를 역순으로 뒤집은 값 반환

    int num = 12345;
    int reversedNum = Integer.reverse(num);
    System.out.println(reversedNum); // 출력: 1260388352

 

 

 

 

 

관련 문제

 

[프로그래머스 문제]

정수 l과 r이 주어졌을 때, l 이상 r이하의 정수 중에서 숫자 "0"과 "5"로만 이루어진 모든 정수를 오름차순으로 저장한 배열을 return 하는 solution 메서드를 완성하시오

만약 그러한 정수가 없다면, -1이 담긴 배열을 return 하시오

 

 

 

 

<모범 답안>

import java.util.ArrayList;

class Solution {
    public int[] solution(int l, int r) {

        ArrayList<Integer> list = new ArrayList<>();

        for (int i = 1; i < 64; i++) {
            int num = Integer.parseInt(Integer.toBinaryString(i)) * 5;
            if (l <= num && num <= r)
                list.add(num);
        }

        return list.isEmpty() ? new int[] { -1 } : list.stream().mapToInt(i -> i).toArray();
    }
}

 

[프로그래머스] 배열 만들기 2

 

 

 

문제

정수 l과 r이 주어졌을 때, l 이상 r이하의 정수 중에서 숫자 "0"과 "5"로만 이루어진 모든 정수를 오름차순으로 저장한 배열을 return 하는 solution 메서드를 완성하시오

만약 그러한 정수가 없다면, -1이 담긴 배열을 return 하시오

 

 

 

나의 답안

문제를 처음 보고 가장 먼저 생각한 구조는 아래와 같다.

 

1. l부터 r까지 숫자를 문자열로 형변환

2. 각 자리수가 5 혹은 0으로 이루어졌는지 체크

3. 해당 숫자만 리스트에 저장

4. 리스트를 배열로 변환하여 return

 

 

 

그러나 좀 더 괜찮은 방법이 없을까 아주 긴 시간 고민했다.

(5로 나누고 10으로 나눴을 때 나머지가 0 또는 1이고 등등...)

 

그러다 생각해낸 것이

 

1. 숫자를 5로 나눴을 때, 1 혹은 0으로 이루어진다.

2. [5, 50, 55, 500, 505, 550 .... ] 각 숫자를 5로 나누면 

    [1, 10, 11, 100, 101, 110 ...] 이고, 이진수로 생각하면 [1, 2, 3, 4, 5...] 와 같네?

3. l, r 까지 숫자 범위 내까지 이진수를 십진수로 바꿔 5를 곱한 값들을 배열에 넣으면 완성

 

 

그러나, 이것을 코드로 구현하는 것은 내 코딩 지식으로 도저히 이루어지지 않아.

결국 며칠을 고민하다 원래 생각했던 구조대로 작성하였다..

 

<완전 오답입니다>
static int[] solution(int l, int r) {
        ArrayList<Integer> arr = new ArrayList<>();

        for (int i=l; i<=r; i++) {
            if (i % 5 == 0) {
                int n = i / 5;
                if (n % 10 == 0 || n % 10 == 1) {
                    arr.add(i);
                }
            }
        }

        int[] result = new int[arr.size()];
        for (int i=0; i<arr.size(); i++) {
            result[i] = arr.get(i);
        }

        return result;
    }

 

 

모범 답안

import java.util.ArrayList;

class Solution {
    public int[] solution(int l, int r) {

        ArrayList<Integer> list = new ArrayList<>();

        for (int i = 1; i < 64; i++) {
            int num = Integer.parseInt(Integer.toBinaryString(i)) * 5;
            if (l <= num && num <= r)
                list.add(num);
        }

        return list.isEmpty() ? new int[] { -1 } : list.stream().mapToInt(i -> i).toArray();
    }
}

 

  • 1 <= l <=  r <= 1,000,000 조건이 있으므로, 1부터 64까지 숫자를 이진수로 변환 (1 ~ 1000000)
  • 변환한 이진수 문자열을 정수로 변환한 후 5를 곱하여 num 변수에 저장
  • 해당 숫자(num)가 l, r 사이의 값인 경우에만 리스트에 추가

 

 

내가 몇시간씩 고민했지만 결국 실패한 코드가 이렇게 간단히 적히다니...

아직 너무 부족함을 느낀다. 열심히 공부해야겠다.

 

 

 

 

복습

       Integer 클래스 메서드

  • Integer.parseInt(String s) :문자열을 int형으로 변환
  • Integer.parseInt(String s, int radix) : 다른 진수의 값 → 10진수로 변환
  • Integer.toBinaryString(int i) : 정수를 이진수로 변환

[프로그래머스] 수 조작하기 2

 

 

 

문제

정수 배열 numLog가 주어집니다. 처음에 numLog[0]에서 부터 시작해 "w", "a", "s", "d"로 이루어진 문자열을 입력으로 받아 순서대로 다음과 같은 조작을 했다.

  • "w" : 수에 1을 더한다.
  • "s" : 수에 1을 뺀다.
  • "d" : 수에 10을 더한다.
  • "a" : 수에 10을 뺀다.

그리고 매번 조작을 할 때마다 결괏값을 기록한 정수 배열이 numLog 이다. 즉, numLog[i]는 numLog[0]로부터 총 i번의 조작을 가한 결과가 저장되어 있다.

주어진 정수 배열 numLog에 대해 조작을 위해 입력받은 문자열을 return 하는 solution 메서드를 완성하라

 

 

 

 

나의 답안

 

  1. StringBulider 선언

  2. 발생할 수 있는 경우의 수가 4가지 (1, -1, 10, -10) 이므로 switch 문을 사용
  3. numLog[i]의 값은 numLog[i-1] 값을 w, a, s, d에 따라 조정한 숫자이므로,
    numLog[i] - numLog[i-1] 값을 통해 w, a, s, d 여부를 판단하여
    sb에 순서대로 저장했다.

 

 

class Solution {
    public String solution(int[] numLog) {
        StringBuilder sb = new StringBuilder();
        
        for (int i=1; i<numLog.length; i++) {
            switch (numLog[i] - numLog[i-1]) {
                case 1: sb.append("w");
                    break;
                case -1: sb.append("s");
                    break;
                case 10: sb.append("d");
                    break;
                case -10: sb.append("a");
                    break;
                default: break;
            }
        }
            
            return sb.toString();
    }
}

 

 

 

 

모범 답안

class Solution {
    public String solution(int[] numLog) {
        String answer = "";
        for(int i=1; i<numLog.length; i++){
            int j = numLog[i-1] - numLog[i];
            switch(j){
                case -1 : answer+='w'; break;
                case 1 : answer+='s'; break;
                case -10 : answer+='d'; break;
                case 10 : answer+='a'; break;
            }
        }
        return answer;
    }
}

 

  • StringBuilder 대신 String을 선언하여 문자를 추가했다.
  • String을 통해 값을 추가할 경우, 추가할 때마다 프로그램 내부적으로 매번 변수 선언을 반복하여
    비효율적일 수 있어 StringBuilder 사용함.  (책에서 봤음)
  • switch문 마지막에 default는 생략해도 무방하다는 것을 깨달았다.

 

복습

       switch문 구조

  • switch (입력 변수) {
        case 입력값 1: 수행할 문장 1;
            break;
        case 입력값 2: 수행할 문장 2;
            break;


        ....


        default: 수행할 문장 n;
            break;
    }

  • 입력 변수의 값이 각 case의 입력값과 같을 경우 해당 case의 수행할 문장을 수행한다.