[프로그래머스] 가장 긴 펠린드롬 (java) String

2020-03-06

가장 긴 펠린드롬 (프로그래머스 > String)

문제 링크

문제설명

앞뒤를 뒤집어도 똑같은 문자열을 팰린드롬(palindrome)이라고 합니다. 문자열 s가 주어질 때, s의 부분문자열(Substring)중 가장 긴 팰린드롬의 길이를 return 하는 solution 함수를 완성해 주세요.

예를들면, 문자열 s가 abcdcba이면 7을 return하고 abacde이면 3을 return합니다.

제한사항
  • 문자열 s의 길이 : 2,500 이하의 자연수
  • 문자열 s는 알파벳 소문자로만 구성

입출력 예
s answer
abcdcba 7
abacde 3
입출력 예 설명

입출력 예 #1 4번째자리 ‘d’를 기준으로 문자열 s 전체가 팰린드롬이 되므로 7을 return합니다.

입출력 예 #2 2번째자리 ‘b’를 기준으로 aba가 팰린드롬이 되므로 3을 return합니다.


풀이

package String;

//40min
public class prog_3_가장긴펠린드롬 {

    static public int solution(String s){
        int answer = 0;

        if(s.length() == 1)
        	return 1;

        if(s.length() == 0)
        	return 0;

        //홀수라고 가정
        for(int i=1; i<s.length()-1; i++) {
        	int len = 0;
        	int front = i-1;
        	int back = i+1;
            int ck=0;
        	
        	while(true) {
	        	if(front >=0 && back<s.length()) { //조건 걸어주고
	        		if(s.charAt(front) == s.charAt(back)) {
	        			if(ck==0) {
	        				len = 1;
	        				ck++;
	        			}
	        			len = len+2;
	        			front--; back++;
	        		}
	        		else
	        			break;
	        	}
	        	else 
	        		break;
        	}//while
        	
        	answer = Math.max(answer,len);
        }
        
        //짝수라고 가정
        for(int i=1; i<s.length(); i++) {
        	int len = 0;
        	int front = i-1;
        	int back = i;
        	
        	while(true) {
	        	if(front >=0 && back<s.length()) { //조건 걸어주고
	        		if(s.charAt(front) == s.charAt(back)) {
	        			len = len+2;
	        			front--; back++;
	        		}
	        		else
	        			break;
	        	}
	        	else 
	        		break;
        	}//while
        	
        	answer = Math.max(answer,len);
        }
        
        return answer;
    }
	
	
	public static void main(String[] args) {
		System.out.println(solution("bbbbaaaaabbbb"));
	}
}

후기 (40min)

처음에는 aba aabaa 같은 홀수의 경우만 생각해서 풀어서 절반만 맞았다.. 이후에 aa나 abba 같은 짝수의 개수를 푸는 법을 생각해내서 풀었고 조금 더럽게 푼거같…다..

Read More

[프로그래머스] 문자열 압축 (java) String

2020-03-04

문자열 압축 (프로그래머스> String)

문제 링크

문제설명

데이터 처리 전문가가 되고 싶은 어피치는 문자열을 압축하는 방법에 대해 공부를 하고 있습니다. 최근에 대량의 데이터 처리를 위한 간단한 비손실 압축 방법에 대해 공부를 하고 있는데, 문자열에서 같은 값이 연속해서 나타나는 것을 그 문자의 개수와 반복되는 값으로 표현하여 더 짧은 문자열로 줄여서 표현하는 알고리즘을 공부하고 있습니다. 간단한 예로 aabbaccc의 경우 2a2ba3c(문자가 반복되지 않아 한번만 나타난 경우 1은 생략함)와 같이 표현할 수 있는데, 이러한 방식은 반복되는 문자가 적은 경우 압축률이 낮다는 단점이 있습니다. 예를 들면, abcabcdede와 같은 문자열은 전혀 압축되지 않습니다. 어피치는 이러한 단점을 해결하기 위해 문자열을 1개 이상의 단위로 잘라서 압축하여 더 짧은 문자열로 표현할 수 있는지 방법을 찾아보려고 합니다.

예를 들어, ababcdcdababcdcd의 경우 문자를 1개 단위로 자르면 전혀 압축되지 않지만, 2개 단위로 잘라서 압축한다면 2ab2cd2ab2cd로 표현할 수 있습니다. 다른 방법으로 8개 단위로 잘라서 압축한다면 2ababcdcd로 표현할 수 있으며, 이때가 가장 짧게 압축하여 표현할 수 있는 방법입니다.

다른 예로, abcabcdede와 같은 경우, 문자를 2개 단위로 잘라서 압축하면 abcabc2de가 되지만, 3개 단위로 자른다면 2abcdede가 되어 3개 단위가 가장 짧은 압축 방법이 됩니다. 이때 3개 단위로 자르고 마지막에 남는 문자열은 그대로 붙여주면 됩니다.

압축할 문자열 s가 매개변수로 주어질 때, 위에 설명한 방법으로 1개 이상 단위로 문자열을 잘라 압축하여 표현한 문자열 중 가장 짧은 것의 길이를 return 하도록 solution 함수를 완성해주세요.

제한사항

  • s의 길이는 1 이상 1,000 이하입니다.
  • s는 알파벳 소문자로만 이루어져 있습니다.
입출력 예
s result
"aabbaccc" 7
"ababcdcdababcdcd" 9
"abcabcdede" 8
"abcabcabcabcdededededede" 14
"xababcdcdababcdcd" 17


풀이

package String;

public class prog_2_문자열압축 {

	static int solution(String s) {
 		int out_len = s.length()/2;
        
        int real = 10000;
        
        if(s.length() ==1)
        	return 1;
        
        for(int i=1; i<=out_len; i++) {//1개부터, s/2까지 돌려볼 수 있다
        	String result = "";
        	int count = 1;
        	
        	String tmp = s.substring(0, i);
        	
        	boolean chk= false; int idx = 0;
        	for(int j=i; j<s.length(); j=j+i) {
        		if(j+i>s.length()) {
        			idx=j;
        			chk= true;
        			break;
        		}
            	
        		if(tmp.equals(s.substring(j, j+i))) {
        			count++;
        		}
        		else {
        			if(count == 1) 
        				result += tmp;
        			else
        				result += count+tmp;
        			
        			count = 1;
        			tmp = s.substring(j,j+i); // 아이씨...
        			
        		}
        	}
        	       	
			if(count == 1) 
				result += tmp;
			else
				result += count +tmp;

			if(chk == true) // !!!!!!!!끝까지 간게 아니라면
				result = result + s.substring(idx, s.length());
			
			
        	if(real > result.length())
        		real = result.length();

        }
        return real;
    }
    
    public static void main(String[] args) {
		System.out.println(solution("abcabcdede"));
	}
	
}

후기 (1h)

다 풀어놓고 뭐가 문젠가 했는데 끝까지 도달하지 못하고 나왔다면 그만큼을 배열에 추가해줘야했다! 으아 엄청 헤맸네…

			if(chk == true) // !!!!!!!!끝까지 간게 아니라면
				result = result + s.substring(idx, s.length());

이 부분!! 다른 방법으로 푼 사람들도 있었는데 일단은 이게 최선이었당

Read More

[백준] 경로 찾기 (java) Bfs

2020-03-03

경로 찾기 (백준> Dfs_Bfs)

문제 링크

문제설명

가중치 없는 방향 그래프 G가 주어졌을 때, 모든 정점 (i, j)에 대해서, i에서 j로 가는 경로가 있는지 없는지 구하는 프로그램을 작성하시오.

입력

첫째 줄에 정점의 개수 N (1 ≤ N ≤ 100)이 주어진다. 둘째 줄부터 N개 줄에는 그래프의 인접 행렬이 주어진다. i번째 줄의 j번째 숫자가 1인 경우에는 i에서 j로 가는 간선이 존재한다는 뜻이고, 0인 경우는 없다는 뜻이다. i번째 줄의 i번째 숫자는 항상 0이다.

출력

총 N개의 줄에 걸쳐서 문제의 정답을 인접행렬 형식으로 출력한다. 정점 i에서 j로 가는 경로가 있으면 i번째 줄의 j번째 숫자를 1로, 없으면 0으로 출력해야 한다.

예제 입력 1 복사

3
0 1 0
0 0 1
1 0 0

예제 출력 1 복사

1 1 1
1 1 1
1 1 1


풀이

package Dfs_Bfs;

import java.util.*;

public class beak_경로찾기 {
	
	public static void main(String[] args) {
		Scanner sc  = new Scanner(System.in);
		
		int n = sc.nextInt();
		
		int arr[][] = new int[n][n];
		Queue<Integer> q = new LinkedList<Integer>();
			
		for(int i=0; i<n; i++) {
			for(int j=0; j<n; j++)
				arr[i][j] = sc.nextInt();
		}
		
		
		for(int i=0;i<n; i++) {
			for(int j=0; j<n; j++) {
				if(arr[i][j] == 1) {//i행부터 갈 수 있는 길들을 큐에 추가 
					q.add(j);
				}
			}
			
			//bfs -> i층인 동안 1로 연결된 곳 다 찾아들어가서 1로 만들어준다!
			while(!q.isEmpty()) {
				int temp = q.poll();
				
				arr[i][temp] =1;	//i에서 tmp는 갈 수 있으므로 1로 변경
				for(int j=0; j<arr.length; j++) {
					if(arr[temp][j] ==1 && arr[i][j] !=1) //arr[i][j]==1인데 큐에 넣으면 무한루프를 돌게 될 수 있으므로 조건 추가
						q.add(j);
				}
				
			}
		}//out for
		

		for(int i=0; i<n; i++) {
			for(int j=0; j<n; j++)
				System.out.print(arr[i][j]+ " ");
			System.out.println(); // println.(" ") -> 이거했다고 출력형식이 잘못됐다고 뜸...;
		}
		
	}

}

후기 (1h)

처음에는 밑에처럼 DFS로 풀려고했는데, 그렇게 하다보니 X와 Y가 꼬이고 배열을 새로 만들면서 문제가 발생했다… BFS로 풀면서도 X Y를 잘 설정해줬어야 했는데 한번 이해하고 보니 다시 풀 수 있을 것 같았다!!

새로운 DFS/BFS 문제에 얼탈뻔했다..

원래 풀려던 방식


	//그 값으로 돌아오면 1, 못돌아오면  0을 return 한다
	//x행이 y랑 연결돼있으면 타고 넘어가
	
	static int dfs(int arr[][], int x, int y) {
//		System.out.println("arr[" +x +"][" + y+ "] =" + arr[x][y] + "y" + y);
		
		if(arr[x][y] == y)
			return y;
		
		else {
			for(int i=0; i<arr.length; i++) {
				if(arr[x][i] != -1)
					dfs(arr,i,y);
			}			
			return 0;
		}
		
	}
	
	public static void main(String[] args) {
		Scanner sc  = new Scanner(System.in);
		
		int n = sc.nextInt();
		
		int arr[][] = new int[n][n];
		
		for(int i=0; i<n; i++) {
			for(int j=0; j<n; j++)
				arr[i][j] = sc.nextInt();
		}
		
		for(int i=0; i<n; i++) {
			for(int j=0; j<n; j++)
				if(arr[i][j] == 1)
					arr[i][j] = j;
				else
					arr[i][j] = -1;
		}
		
		
		int ans[][] = new int[n][n];
		
		for(int i=0; i<n; i++) {
			for(int j=0; j<n; j++) {
				System.out.println("??" + dfs(arr,i,j));
				ans[i][j] = dfs(arr,i,j);
			}
		}

		for(int i=0; i<n; i++) {
			for(int j=0; j<n; j++) {
				System.out.print(ans[i][j] + " ");
			}
			System.out.println(" ");
		}
		
	}
Read More

[백준] RGB거리 (java) Dynamic_programming

2020-03-03

RGB거리 (백준> Dynamic_programming)

문제 링크

문제설명

RGB거리에 사는 사람들은 집을 빨강, 초록, 파랑중에 하나로 칠하려고 한다. 또한, 그들은 모든 이웃은 같은 색으로 칠할 수 없다는 규칙도 정했다. 집 i의 이웃은 집 i-1과 집 i+1이고, 첫 집과 마지막 집은 이웃이 아니다.

각 집을 빨강으로 칠할 때 드는 비용, 초록으로 칠할 때 드는 비용, 파랑으로 드는 비용이 주어질 때, 모든 집을 칠하는 비용의 최솟값을 구하는 프로그램을 작성하시오.

입력

첫째 줄에 집의 수 N이 주어진다. N은 1,000보다 작거나 같다. 둘째 줄부터 N개의 줄에 각 집을 빨강으로, 초록으로, 파랑으로 칠하는 비용이 주어진다. 비용은 1,000보다 작거나 같은 자연수이다.

출력

첫째 줄에 모든 집을 칠하는 비용의 최솟값을 출력한다.

예제 입력 1 복사

3
26 40 83
49 60 57
13 89 99

예제 출력 1 복사

96


풀이

package Dynamic_programming;

import java.util.*;


//10min
public class beak_RGB거리 {

	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		
		int n = sc.nextInt();
		sc.nextLine();
		
		int arr[][] = new int[n][3];
		
		for(int i=0;i <n; i++) {
			arr[i][0] = sc.nextInt();
			arr[i][1] = sc.nextInt();
			arr[i][2] = sc.nextInt();
		}
		
		for(int i=1; i<n; i++) {
			for(int j=0; j<3; j++) {
				if(j==0)
					arr[i][j] = Math.min(arr[i][j] + arr[i-1][1], arr[i][j] + arr[i-1][2]);
				if(j==1)
					arr[i][j] = Math.min(arr[i][j] + arr[i-1][0], arr[i][j] + arr[i-1][2]);
				if(j==2)
					arr[i][j] = Math.min(arr[i][j] + arr[i-1][0], arr[i][j] + arr[i-1][1]);
			}
		}
		
		int min = Math.min(Math.min(arr[n-1][0], arr[n-1][1]), arr[n-1][2]);
		
		System.out.println(min);
	}
}

후기 (10min)

배열의 열이 3개로 고정돼있어서 쉽게 풀 수 있었다! 풀어봤던 유형인, 쉬운 편에 속하는 dp문제였다!

Read More

[백준] Z (java) Recursion

2020-03-03

Z (백준> Recursion)

문제 링크

문제설명

한수는 2차원 배열 (항상 2^N * 2^N 크기이다)을 Z모양으로 탐색하려고 한다. 예를 들어, 2*2배열을 왼쪽 위칸, 오른쪽 위칸, 왼쪽 아래칸, 오른쪽 아래칸 순서대로 방문하면 Z모양이다.

img

만약, 2차원 배열의 크기가 2^N * 2^N라서 왼쪽 위에 있는 칸이 하나가 아니라면, 배열을 4등분 한 후에 (크기가 같은 2^(N-1)로) 재귀적으로 순서대로 방문한다.

다음 예는 2^2 * 2^2 크기의 배열을 방문한 순서이다.

img

N이 주어졌을 때, (r, c)를 몇 번째로 방문하는지 출력하는 프로그램을 작성하시오.

다음 그림은 N=3일 때의 예이다.

img

입력

첫째 줄에 N r c가 주어진다. N은 15보다 작거나 같은 자연수이고, r과 c는 0보다 크거나 같고, 2^N-1보다 작거나 같은 정수이다

출력

첫째 줄에 문제의 정답을 출력한다.

예제 입력 1 복사

2 3 1

예제 출력 1 복사

11


풀이

package Recursion;

import java.util.*;

public class beak_Z {

	static int r = 0;
	static int c = 0;
	static int answer = 0;
	
	static void recursion(int x, int y, int n) {
		if(n == 1) { //사이즈가 하나 됐을 때
			if(x==r && y==c)
				System.out.println(answer);
				
			answer++;
			return;
		}
		
		int half = n/2;
		
//		System.out.println(x +" " + y + " " + n + " " + half);
		
		recursion(x, y, half); // 1사분면
		recursion(x, y+half , half); // 2사분면
		recursion(x+half, y, half); // 3사분면
		recursion(x+half, y+half, half); // 4사분면
		
	}
	
	
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		
		int N = sc.nextInt();
		r = sc.nextInt();
		c = sc.nextInt();
		
		int pow = (int)Math.pow(2, N);
		
		recursion(0, 0, pow);
		
	}
}

후기 (40min)

이해도 못했던 문젠데 드디어 풀 수도, 이해할 수도 있었다!

굳이 배열로 만들지말고, 길이만 안다면 절반으로 줄여나가면서 기저조건을 1로 두면 풀 수 있다

Read More