int 배열과 시작, 끝, 현재 index를 사용해 풀었다. R을 할 때마다 순서를 바꾸는 것은 시간이 너무 오래 걸릴 것이라 판단했다. 배열을 그대로 두고 연산 실행 시 시작, 끝, 현재 index 연산만 하면 시간복잡도를 줄일 수 있을 거라고 생각했다.
메모리는 D를 할 때마다 조금씩 낭비될 수는 있지만 시간을 줄이는 것이 더 이득이라 생각한 결과이다.
변수들을 다음과 같이 선언했다.
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int[] list;//배열
int n = Integer.parseInt(br.readLine());//반복 횟수
String[] order;//명령
int size;//배열 크기
int start;//끝 위치
int end;//시작 위치
int now;//현재 위치
String arr;//문자열로 입력받을 배열
StringBuilder result;//결과
입력을 받은 후 입력받은 문자열을 substring과 split을 통해 배열에 넣어주고 명령 분석을 시작했다.
public static void input(int[] list, String nums)
{
//문자열의 길이가 2라면 빈 배열이므로 return
if(nums.length() == 2)
{
return;
}
String[] nlist = nums.substring(1, nums.length()-1).split(",");
for(int i = 0; i<nlist.length; i++)
{
list[i] = (Integer.parseInt(nlist[i]));
}
}
result = new StringBuilder();
order = br.readLine().split("");//명령 입력
size = Integer.parseInt(br.readLine());//배열 크기 입력
list = new int[size];//배열 초기화
arr = br.readLine();//문자열로 배열 입력
input(list, arr);//입력받은 문자열을 배열로 삽입
start = 0;//시작 위치 초기화
now = start;//현재 위치를 시작 위치로
end = size-1;//끝 위치를 배열 크기 -1 로(index 이므로)
이렇게 하면 우선 그림과 같이 설정된다.
이제 명령에 따라 index들을 연산하면 된다.
1. 명령이 R 인 경우
- now가 start라면 now를 end로 옮긴다.
- now가 end라면 now를 start로 옮긴다.
2. 명령이 D 인 경우
- now가 start라면 now++, start++를 통해 한 칸 앞으로 이동한다. (삭제와 같은 효과이지만 실제로 배열을 건드리지는 않는다.)
- now가 end라면 now--, end--를 통해 한 칸 뒤로 이동한다. (마찬가지로 배열을 건드리지는 않는다.)
이걸 이해하기 쉽게 그림으로 표현해 보겠다.
0. 입력
입력을 받은 후의 상태이다.
1. R
now가 start이므로 now가 end로 이동한다
2. D
now가 end 이므로 now--, end--를 통해 배열을 건드리지 않으면서 index만 이동한다
3. R
now가 end 이므로 now가 start로 이동한다.
4. D
now가 start 이므로 now++, start++ 로 배열을 건드리지 않으면서 index만 이동한다.
이러면 연산은 끝났다. 이제 출력만 하면 된다.
출력은 간단하다. 세 가지 조건을 따지면 된다.
1. start > end + 1인 경우
- 배열이 비어있는 상태에선 start = end + 1이다(start == end이면 원소가 한 개 있는 경우이므로)
- 따라서 start > end + 1이면 배열이 비어있는 상태에서 D 명령을 했다는 것이므로 error를 출력하면 된다.
2. now == start 인 경우
- 배열의 현재 상태가 정방향이라는 것을 의미한다.
- 따라서 start부터 end까지 출력하면 된다.
3. now == end 인 경우
- 배열의 현재 상태가 역방향이라는 것을 의미한다.
- 따라서 end부터 start까지 역방향으로 출력하면 된다.
5. 출력
여태까지 한 과정을 코드로 나타내면 이렇다.
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int[] list;//배열
int n = Integer.parseInt(br.readLine());//반복 횟수
String[] order;//명령
int size;//배열 크기
int start;//끝 위치
int end;//시작 위치
int now;//현재 위치
String arr;//문자열로 입력받을 배열
StringBuilder result;//결과
for(int i = 0; i<n; i++)
{
result = new StringBuilder();
order = br.readLine().split("");//명령 입력
size = Integer.parseInt(br.readLine());//배열 크기 입력
list = new int[size];//배열 초기화
arr = br.readLine();//문자열로 배열 입력
input(list, arr);//입력받은 문자열을 배열로 삽입
start = 0;//시작 위치 초기화
now = start;//현재 위치를 시작 위치로
end = size-1;//끝 위치를 배열 크기 -1 로(index 이므로)
//명령을 하나씩 수행
for(String o : order)
{
//R(reverse)이면 현재 위치를 바꾼다
if(o.equals("R"))
{
now = now == start ? end : start;
}
//D(delete)이면 현재 위치와 시작 혹은 끝 위치를 +1 하거나 -1 한다
else
{
if(now == start)//현재 위치가 시작 위치이면 +1
{
now++;
start++;
}
else//현재 위치가 끝 위치이면 -1
{
now--;
end--;
}
}
}
//만약 시작 위치가 끝 위치 +1 보다 크다면 배열이 비어있는 상태에서 Delete를 한 것이므로 error
if(start > end+1)
{
result.append("error");
}
//현재 위치가 시작 위치라면 시작 위치부터 끝 위치까지 출력
else if(now == start)
{
result.append("[");
for(int j = now; j<=end; j++)
{
result.append(list[j]+",");
}
if(result.length() == 1)
{
result.append("]");
}
else
{
result.replace(result.length()-1, result.length(), "]");
}
}
//현재 위치가 끝 위치라면 끝 위치부터 시작 위치까지 출력
else if(now == end)
{
result.append("[");
for(int j = now; j>=start; j--)
{
result.append(list[j]+",");
}
if(result.length() == 1)
{
result.append("]");
}
else
{
result.replace(result.length()-1, result.length(), "]");
}
}
System.out.println(result);
}
결과 코드
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.*;
public class Main
{
//배열에 문자열을 넣는 함수
public static void input(int[] list, String nums)
{
//문자열의 길이가 2라면 빈 배열이므로 return
if(nums.length() == 2)
{
return;
}
String[] nlist = nums.substring(1, nums.length()-1).split(",");
for(int i = 0; i<nlist.length; i++)
{
list[i] = (Integer.parseInt(nlist[i]));
}
}
public static void main(String[] args) throws IOException
{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int[] list;//배열
int n = Integer.parseInt(br.readLine());//반복 횟수
String[] order;//명령
int size;//배열 크기
int start;//끝 위치
int end;//시작 위치
int now;//현재 위치
String arr;//문자열로 입력받을 배열
StringBuilder result;//결과
for(int i = 0; i<n; i++)
{
result = new StringBuilder();
order = br.readLine().split("");//명령 입력
size = Integer.parseInt(br.readLine());//배열 크기 입력
list = new int[size];//배열 초기화
arr = br.readLine();//문자열로 배열 입력
input(list, arr);//입력받은 문자열을 배열로 삽입
start = 0;//시작 위치 초기화
now = start;//현재 위치를 시작 위치로
end = size-1;//끝 위치를 배열 크기 -1 로(index 이므로)
//명령을 하나씩 수행
for(String o : order)
{
//R(reverse)이면 현재 위치를 바꾼다
if(o.equals("R"))
{
now = now == start ? end : start;
}
//D(delete)이면 현재 위치와 시작 혹은 끝 위치를 +1 하거나 -1 한다
else
{
if(now == start)//현재 위치가 시작 위치이면 +1
{
now++;
start++;
}
else//현재 위치가 끝 위치이면 -1
{
now--;
end--;
}
}
}
//만약 시작 위치가 끝 위치 +1 보다 크다면 배열이 비어있는 상태에서 Delete를 한 것이므로 error
if(start > end+1)
{
result.append("error");
}
//현재 위치가 시작 위치라면 시작 위치부터 끝 위치까지 출력
else if(now == start)
{
result.append("[");
for(int j = now; j<=end; j++)
{
result.append(list[j]+",");
}
if(result.length() == 1)
{
result.append("]");
}
else
{
result.replace(result.length()-1, result.length(), "]");
}
}
//현재 위치가 끝 위치라면 끝 위치부터 시작 위치까지 출력
else if(now == end)
{
result.append("[");
for(int j = now; j>=start; j--)
{
result.append(list[j]+",");
}
if(result.length() == 1)
{
result.append("]");
}
else
{
result.replace(result.length()-1, result.length(), "]");
}
}
System.out.println(result);
}
}
}
'백준' 카테고리의 다른 글
9935번:문자열 폭발(Java) (0) | 2023.02.24 |
---|---|
5052번:전화번호 목록(Java) (1) | 2023.02.24 |
1927번:최소 힙(Java) (0) | 2023.02.20 |
11286번:절댓값 힙(Java) (0) | 2023.02.20 |
1302번: 베스트셀러(Java) (0) | 2023.02.19 |