프로그래머스 Lv.1 (9)

nn1co1·2022년 2월 3일
0

프로그래머스 Lv.1

목록 보기
9/13

22.02.03 ~ 22.02.10

📌 폰켓몬


https://programmers.co.kr/learn/courses/30/lessons/1845
문제 풀러 가기

초기 코드

class Solution {
    public int solution(int[] nums) {
        int answer = 0;
        return answer;
    }
}

내가 작성한 코드

import java.util.Arrays;
class Solution {
    public int solution(int[] nums) {
        int answer = 1;
        // answer <= (nums.length / 2)이라는 제한
        // answer는 종류의 수 (마리 수 아님)
        // 배열 오름차정렬, 앞원소 =/= 뒤원소인 순간 뒤원소를 종류의 수로 카운트.
        Arrays.sort(nums);
        //System.out.print(Arrays.toString(nums));
        
        for (int i = 0; i < nums.length-1 ; i++) {
            if (nums[i] != nums[i+1]) {
                answer++;
            }
            if (answer >= nums.length / 2) {
                break;
            }
        } 
        return answer;
    }
}

테스트케이스 12개 중 테스트케이스 1에서 오류가 났었다. 다른 케이스는 통과한 걸 보면 큰 틀에서의 흐름은 정답이었지만 특이한 경우에는 옳지 않다는 뜻이라고 생각했다. 조금 고민하다가 떠오른 게 answer의 크기를 기준으로 비교하는 두번째 조건문이 앞에서 실행되어야 한다는 것. answer의 초기값을 1로 두었기 때문에, 무턱대고 answer++;를 시행했다가는 nums.length / 2를 초과하는 경우가 생길지도 모른다고 생각해서 순서를 바꿔줬다.

수정한 코드

import java.util.Arrays;
class Solution {
    public int solution(int[] nums) {
        int answer = 1;
        // answer <= (nums.length / 2)이라는 제한
        // answer는 종류의 수 (마리 수 아님)
        // 배열 오름차정렬, 앞원소 =/= 뒤원소인 순간 뒤원소를 종류의 수로 카운트.
        Arrays.sort(nums);
        for (int i = 0; i < nums.length-1 ; i++) {
            if (answer >= nums.length / 2) {
                break;
            }
            if (nums[i] != nums[i+1]) {
                answer++;
            }
        } 
        return answer;
    }
}

아마 answer = 1인 테스트 케이스가 있어서 통과하지 못했었나보다. 결과적으로는 12개 모두 성공!

다른 사람의 풀이

import java.util.*;
class Solution {
    public int solution(int[] nums) {
        //1. 기존 length를 구한다.
        //2. 중복값을 제거한 length를 구한다.
        //3. 두 값중 최소값이 정답.
        List<Integer> list = new ArrayList<Integer>();
        for(int i = 0 ; i < nums.length; i++){
            if(!list.contains(nums[i])){
                list.add(nums[i]);
            }
        }
        return nums.length/2 > list.size()?list.size():nums.length/2; //(1)
    }
}

주석까지 친절하게 달려 있고, 제일 신선해서 가져와본 풀이. 어차피 최대 마리 수는 nums.length/2라는 점을 잘 활용한 것 같다. 나도 풀 때 '중복값을 제거해볼까?'라고 생각했었는데, 그걸 풀이에 list를 만들어서 적용할 수 있구나!
(1)맨 마지막에 리턴할 때, Math.max() 함수를 쓸 수도 있을 것 같아서 메모해둔다. 삼항연산자보다는 직관적일 것 같다.


📌 음양 더하기

초기 코드

class Solution {
    public int solution(int[] absolutes, boolean[] signs) {
        int answer = 0;
        return answer;
    }
}

내가 작성한 코드

class Solution {
    public int solution(int[] absolutes, boolean[] signs) {
        int answer = 0;
        for (int i = 0; i < absolutes.length; i++) {
            answer = signs[i]? answer + absolutes [i] : answer - absolutes[i];
        }
        return answer;
    }
}

부호에 따라 더할지 뺄지가 달라지니까 삼항연산을 활용했다. 다른 사람의 풀이를 보고 나니

answer += signs[i]? absolutes[i]: -absolutes[i];

이렇게도 할 수 있는 걸 알았다! +=를 쓸지 그냥 =를 쓸지 고민했는데 저렇게 써볼 걸 그랬다.


📌 최소 직사각형

초기 코드

class Solution {
    public int solution(int[][] sizes) {
        int answ er = 0;
        return answer;
    }
}

내가 작성한 코드

class Solution {
    public int solution(int[][] sizes) {
        int answ er = 0;
        /*
        1. 가로의 max, 세로의 max 구해두기
        각 명함을 회전해도 되는지 안되는지 구별?
        2. 가로 중 max를 구하고 모든 원소를 돌아가면서 Math.max(가로,세로)를 가로로 만들기
        --> 테스트 2를 통과 못함. 가로 세로 모두 따져서 max를 찾는 게 맞을듯
        --> 그럼 그게 가로인지 세로인지 인덱스로 구분해야하는데 이미 찾은 max의 인덱스는 어떻게 알지..?
        그럼 다른 한 쪽인 세로 중에서 max값이 지갑의 최적화된 세로사이즈
        */
        int max1 = 0;
        for (int i = 0; i < sizes.length; i++) {
            //가로 세로 인덱스를 어떻게 정해야 할지 고민
        }
        for (int i = 0; i < sizes.length; i++) {
            //둘 다 max1 이하면 Math.max(가로,세로)를 가로로 지정
            //둘 중 하나만 max1 이하면 Math.min(가로,세로)를 가로로 지정
            int temp1= Math.max(sizes[i][0],sizes[i][1]);
            int temp2= Math.min(sizes[i][0],sizes[i][1]);
            
            if (sizes[i][0] <= max1 && sizes[i][1] <= max1) {
                sizes[i][0] = temp1;
                sizes[i][1] = temp2;
            }      
        }
        int max2 = 0;
        for (int i = 0; i < sizes.length; i++) {
            if (max2 < sizes[i][1]) 
                max2 = sizes[i][1];
        }
        System.out.println(max1);
        System.out.print(max2);
        answer = max1 * max2;
        
        return answer;
    }
}

다른 사람의 풀이 (정답 코드)

class Solution {
    public int solution(int[][] sizes) {       
        int width = 0, height = 0;

        for (int[] size : sizes) {
            width = Math.max(width, Math.max(size[0], size[1])); //(1)
            height = Math.max(height, Math.min(size[0], size[1])); //(2)
        }

        return width * height;
    }
}

난 너무 힘들게 생각했나보다 ㅎㅎ.. 왜 그랬을까 ㅋㅋ
(1) 가로 세로 중 큰 값을 가지고 max를 구하기
(2) 가로 세로 중 작은 값을 가지고 그 중 max를 구하기
각 max값을 곱해주면 되는 거였다.


0개의 댓글