[프로그래머스] 행렬의 곱셈 (java) Number_Change

2020-01-16

행렬의 곱셈 (programers > lev2 > Number_Change)

문제 링크

문제설명

2차원 행렬 arr1과 arr2를 입력받아, arr1에 arr2를 곱한 결과를 반환하는 함수, solution을 완성해주세요.

제한 조건
  • 행렬 arr1, arr2의 행과 열의 길이는 2 이상 100 이하입니다.
  • 행렬 arr1, arr2의 원소는 -10 이상 20 이하인 자연수입니다.
  • 곱할 수 있는 배열만 주어집니다.
입출력 예
arr1 arr2 return
[[1, 4], [3, 2], [4, 1]] [[3, 3], [3, 3]] [[15, 15], [15, 15], [15, 15]]
[[2, 3, 2], [4, 2, 4], [3, 1, 4]] [[5, 4, 3], [2, 4, 1], [3, 1, 1]] [[22, 22, 11], [36, 28, 18], [2


풀이

    static public int[][] solution(int[][] arr1, int[][] arr2) {
        int[][] answer = new int [arr1.length][arr2[0].length];
        
        //행렬 i*j 와 행렬 j*k 는 항상 j가 같아야 계산 할 수 있다.
        for(int i=0; i<arr1.length; i++) {
        	for(int j=0; j<arr1[0].length; j++) {
        		for(int k=0; k<arr2[0].length; k++) {
        			answer[i][k] += arr1[i][j] * arr2[j][k];
        		}
        	}
        }

        return answer;
    }


후기 (1h)

행렬 A와 B를 곱할 수 있는 조건은 (I,J) (J,K)로 J 부분이 같은 크기여야 한다.

answer의 사이즈에서 계속 BounderyInedx 에러가 났다.. 처음에는 for문을 두개 돌릴 생각만 하느라고 시간이 오래걸렸는데 for문을 돌리는 변수를 i, j, k로 두면 해결 할 수 있는 일이었다!

i보다 j가 크다고 혹은 i보다 k의 사이즈카 커서 안돌아갈까라는 생각을 했는데 조건만 잘 걸어주면 아무 문제 없었다!



tip

  1. for문을 돌릴 때, 어떤 변수를 쓰면 문제를 쉽게 해결할 수 있을지에 대해 생각하면 좋은 코드가 될 것 같다


Read More

[프로그래머스] JadenCase 문자열 만들기 (java) 문자열_String

2020-01-15

JadenCase 문자열 만들기 (programers > lev2 > 문자열_String)

문제 링크

문제설명

JadenCase란 모든 단어의 첫 문자가 대문자이고, 그 외의 알파벳은 소문자인 문자열입니다. 문자열 s가 주어졌을 때, s를 JadenCase로 바꾼 문자열을 리턴하는 함수, solution을 완성해주세요.

제한 조건
  • s는 길이 1 이상인 문자열입니다.
  • s는 알파벳과 공백문자(“ “)로 이루어져 있습니다.
  • 첫 문자가 영문이 아닐때에는 이어지는 영문은 소문자로 씁니다. ( 첫번째 입출력 예 참고 )
입출력 예
s return
3people unFollowed me 3people Unfollowed Me
for the last week For The Last Week


풀이

    	static public String solution(String s) {
		String a = "";  
		s = s.toLowerCase();
		
		boolean check = false; // i+1이 문자가 아니라는 뜻
		
		for(int i=0;i<s.length()-1;i++) {
			if(s.charAt(i) == ' ') {
				if(i==0)
					a = a + " ";
				//i+1 추가
				if(s.charAt(i+1) != ' ' && check==false) {
					a = a + String.valueOf(s.charAt(i+1)).toUpperCase();
					check=true; //문자가 시작되었다는 뜻
				}
				else if(s.charAt(i+1) == ' ')
					a = a + " ";
			}
			
			else{ // 문자인 경우
				if(i==0)
					a = a + String.valueOf(s.charAt(i)).toUpperCase();
				
				if(s.charAt(i+1) == ' ') {
					a = a + " ";
					check=false; //다시 첫 문자가 시작될때까지 
				}
				else //다음 글자도 문자인 경우
					a = a + String.valueOf(s.charAt(i+1));
				
				
			}
		}//for
		
	    return a;
	}


후기 (1h)

처음에는 문자열이 공백으로 시작하는 예제를 생각하지 않고 20분만에 풀었다…만.. 오류!!
그래서 공백으로 시작하는 것까지 체크하려면

  1. 전부 toLowerCase로 만들어놓고
  2. i와 i+1을 계속 비교해주는 방식으로
  3. i(현재)가 공백이면 i+1이 1)공백인지 2)공백이 아닌지
  4. i(현재)가 공백이 아니라면 i+1이 1)공백인지 2)공백이 아닌지
  5. 총 4가지 if로 구분해주었고 문자가 시작되어 끝나는 것까지 체크해주는 boolean 변수로 마무리!



tip

  1. 8점이나 받은 문제…! 화우
  2. Lowercase 와 UpperCase 사용법도 익혀놓자!


Read More

[프로그래머스] 카펫 (java) 완전탐색

2020-01-15

카펫 (programers > lev2 > 완전탐색)

문제 링크

문제설명

Leo는 카펫을 사러 갔다가 아래 그림과 같이 중앙에는 빨간색으로 칠해져 있고 모서리는 갈색으로 칠해져 있는 격자 모양 카펫을 봤습니다.

image.png

Leo는 집으로 돌아와서 아까 본 카펫의 빨간색과 갈색으로 색칠된 격자의 개수는 기억했지만, 전체 카펫의 크기는 기억하지 못했습니다.

Leo가 본 카펫에서 갈색 격자의 수 brown, 빨간색 격자의 수 red가 매개변수로 주어질 때 카펫의 가로, 세로 크기를 순서대로 배열에 담아 return 하도록 solution 함수를 작성해주세요.

제한사항
  • 갈색 격자의 수 brown은 8 이상 5,000 이하인 자연수입니다.
  • 빨간색 격자의 수 red는 1 이상 2,000,000 이하인 자연수입니다.
  • 카펫의 가로 길이는 세로 길이와 같거나, 세로 길이보다 깁니다.
입출력 예
brown red return
10 2 [4, 3]
8 1 [3, 3]
24 24 [8, 6]


풀이

   static public int[] solution(int brown, int red) {
        int[] answer = new int[2];
        
        int sum = brown + red;
        
        for(int i=1; i< (sum/2) ; i++) {
        	if(sum%i == 0) {
        		int p = sum/i;
        		if((p-2)*(i-2) == red) {
        			answer[0] = Math.max(p, i);
        			answer[1] = Math.min(p, i);;
        		}
        		
        	}
        }
   
        return answer;
    }


후기 (1h)

처음에는 red를 중심으로 잡고 brown을 가로x2 + 세로x2 + 4 이런 식으로 생각했는데

red가 4 혹은 6.. 이런식이 될때는 사각형의 방향을 어떻게 잡아줘야 할지 모르겠어서 고민을 했다.

조금 생각해보니 red x brown 은 사각형의 사이즈고 나올 수 있는 (x,y)조합을 찾아준 후,

x-2 * y-2는 red의 개수일때까지 for문으로 반복해주면 되었다.

또 3x4 4x3 등 반복되는 수가 있기 때문에 for문은 절반만 돌려주었다.

식을 생각해내면 금방푸는데 늘 그렇듯 생각하는 게 오래 걸렸다..!^^



tip

  1. 두개의 숫자가 나왔을때 대소비교를 해야하는 상황에서 max(a,b) min(a,b)를 해주면 되는 꼼수를 깨닫게 되었다.


Read More

[프로그래머스] 올바른 괄호 (java) Stack

2020-01-15

올바른 괄호 (programers > lev2 > Stack_Queue)

문제 링크

문제설명

괄호가 바르게 짝지어졌다는 것은 ‘(‘ 문자로 열렸으면 반드시 짝지어서 ‘)’ 문자로 닫혀야 한다는 뜻입니다. 예를 들어

  • ()() 또는 (())() 는 올바른 괄호입니다.
  • )()( 또는 (()( 는 올바르지 않은 괄호입니다.

’(‘ 또는 ‘)’ 로만 이루어진 문자열 s가 주어졌을 때, 문자열 s가 올바른 괄호이면 true를 return 하고, 올바르지 않은 괄호이면 false를 return 하는 solution 함수를 완성해 주세요.

제한사항
  • 문자열 s의 길이 : 100,000 이하의 자연수
  • 문자열 s는 ‘(‘ 또는 ‘)’ 로만 이루어져 있습니다.

입출력 예
s answer
()() true
(())() true
)()( false
(()( false
입출력 예 설명

입출력 예 #1,2,3,4 문제의 예시와 같습니다.


풀이

   static boolean solution(String s) {
        boolean answer = true;
        
        //애초에 stk에는 (밖에 없음! )는 나오는 즉시 제거할지 말지에만 관여하기때문
        Stack<Character> stk = new Stack<Character>();
        
        for(int i=0;i<s.length();i++) {
        	if(s.charAt(i) == '(')
        		stk.push('(');
        	
        	else { //들어갈 준비중인게 )
        		if(stk.isEmpty())
        			return false;
        		else
                    stk.pop();
        	}
        }
        
        if(!stk.isEmpty())
        	return false;
        
        return answer;
    }


후기 (13min but…)

풀기는 십분만에 푼거같은데 효율성에서 계속 걸렸다!! 으아 이것때문에 삼십분 잡아먹음

괄호관련 스택문제 풀 때 항상 if를 어떻게 걸어줄지를 열심히 고민하는데 이번에 효율성에서 통과하면서 확실히 느낀점은

  1. STACK에는 ‘(‘ 밖에 들어가지 않는다.
  2. ’)’는 PEEK인 (를 지우느냐 마냐 에만 관여한다는 것이다.
  3. 따라서 이 코드에 ‘)’를 push하는 함수는 없다는 것!
  4. stack에 (밖에 없고 size도 0이 아니라면 )가 할 수 있는건 pop()밖에 없다!!



tip

  1. 오랜만에 풀었는데 조건 거는 법을 자꾸 까먹는다..
  2. 효율성을 위해 조건을 깔끔하게 거는 법, 더 간단한 방법 생각하기!


Read More

[프로그래머스] 소수 찾기 (java) 완전탐색

2020-01-15

소수 찾기 (programers > lev2 > 완전탐색)

문제 링크

문제설명

한자리 숫자가 적힌 종이 조각이 흩어져있습니다. 흩어진 종이 조각을 붙여 소수를 몇 개 만들 수 있는지 알아내려 합니다.

각 종이 조각에 적힌 숫자가 적힌 문자열 numbers가 주어졌을 때, 종이 조각으로 만들 수 있는 소수가 몇 개인지 return 하도록 solution 함수를 완성해주세요.

제한사항
  • numbers는 길이 1 이상 7 이하인 문자열입니다.
  • numbers는 0~9까지 숫자만으로 이루어져 있습니다.
  • 013은 0, 1, 3 숫자가 적힌 종이 조각이 흩어져있다는 의미입니다.
입출력 예
numbers return
17 3
011 2
입출력 예 설명

예제 #1 [1, 7]으로는 소수 [7, 17, 71]를 만들 수 있습니다.

예제 #2 [0, 1, 1]으로는 소수 [11, 101]를 만들 수 있습니다.

  • 11과 011은 같은 숫자로 취급합니다.


풀이

import java.util.*;

class Solution {
    
    static ArrayList<Integer> list = new ArrayList<Integer>();
    static int answer = 0;
    static public void swap(int arr[], int depth, int i){
        int temp = arr[depth];
        arr[depth] = arr[i];
        arr[i] = temp;
        
    }
    
    static public boolean sosu(int n){
        boolean chk = true;        
        
        if(n == 1 || n ==0)
            ;
        else{
            for(int i=2;i<n;i++){
                if(n%i == 0){
                    chk=false;
                    break;
                }
            }
            if(chk==true)
                return true;
        }
        
        return false;
    }
    
    static public void perm(int arr[], int depth, int n, int r){
        
        if(depth == r){ //기저조건
            String a = "";
            for(int i=0;i<r; i++)
                a = a + arr[i];
            
            int num = Integer.parseInt(a);
            if(!list.contains(num)){
                list.add(num);
                if(sosu(num))
                    answer++;
            }
            
            return ;
        }
        
        
        for(int i=depth; i<n;i++){
            swap(arr,depth,i);
            perm(arr,depth+1,n,r);
            swap(arr,depth,i);
        }
        
    }
    
    static public int solution(String numbers) {
        int arr[] = new int[numbers.length()];

        for(int i=0; i<numbers.length(); i++)
            arr[i] = Integer.parseInt(String.valueOf(numbers.charAt(i)));
        
        for(int i=1;i<=numbers.length();i++)
            perm(arr,0,numbers.length(),i);
        
        return answer;
    }

    
    
    
    static void main(String args[]){
        System.out.println("hello world");
    }
}


후기 (2h -> 20min)

순열로 나올 수 있는 숫자를 다 만든 후에, 소수를 찾고 소수가 되면 an++ 해주면 되는 문제였는데 오랜만의 순열과 오랜만의 소수.. 문제에 머리가 깜깜해졌다…

그래도 순열 복습했고, 소수도 복습했다!

푼 후에 바로 풀어도 20분이 걸리는 매직.. 복습 철저히 해야 그나마 3,40분 컷 할 수 있지 않을까 싶다….!



tip

  1. permutation - 순열 - nPr - 중복을 허락한다. [1,1,2] 의 경우 [0,2]와

[1,2]를 다른 값으로 취급 한다.

  1. 따라서 중복되는 수들은 list.contains로 확인해 줘야 했다.
  2. 소수 - 1과 자기자신으로만 나누어 떨어지는 수.
  3. 따라서 n은 (2~n-1)까지 나누어 보며 소수가 되는지 확인해야 한다.


Read More