코드 저장소

공부에는 끝이 없다!

JAVA/코딩 테스트

백준 문제 풀이 - 1차원 배열 단계 - 10811번 바구니 뒤집기

VarcharC2K 2023. 8. 12. 22:37

브론즈 2단계의 배역 역순 문제이다.

특정 인덱스의 시작과 끝값이 들어오면 배열의 해당 인덱스 값을 역순으로 뒤집는 간단한 문제였다.

다 풀고 확인해보니 다른 분들은 다 배열로 풀었는데 나는 ArrayList를 사용하여 풀어서 코드가 좀 많이 달랐다. (솔직히 for문 쓰는게 조금 귀찮아서 ArrayList로 한것도 있다.)

 

대부분의 분들은 아래 코드처럼 푸셨는데

import java.util.Arrays;
import java.util.Scanner;

public class Main {
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		int N = sc.nextInt();
		int M = sc.nextInt();

		int[] basket = new int[N + 1];
		for (int i = 1; i <= N; i++) {
			basket[i] = i;
		} // N개의 바구니가 있다.

		for (int i = 0; i < M; i++) {
			int a = sc.nextInt();
			int b = sc.nextInt();
			for (int j = a; j <= b; j++) {
				int ab = b--; // 역순으로 만들어주기

				int tmp = basket[j];
				basket[j] = basket[ab];
				basket[ab] = tmp;

			}
		}
		
		for(int i=1;i<=N;i++) {
			System.out.print(basket[i]+" ");
		}

	}
}

바꿀 인덱스의 시작 부터 끝까지 반복문을 돌리면서 인덱스의 값을 임시변수에 담아주고, 다른 인덱스 값은 끝값부터 역순으로 내려오면서 해당 인덱스의 값을 바꿔주는 형태이다.

예를 들어 1부터 4까지 역순으로 해라라는 입력이 들어오면 처음에는 배열의 첫번째 값을 임시변수에 담고, 4번째 인덱스의 값을 넣은 후, 4번째 인덱스에는 임시변수의 값을 담는 것!

 

근데 사실 반복문을 사용안해도 2개의 메서드만 사용하면 역순의 배열을 만들 수 있다,

나는 애시당초 이것을 알고 있었기 때문에 배열이 아닌 ArrayList를 이용하여 코드를 구현하였다.

 

import java.util.*;
import java.io.*;

class Main{
    public static int n,m,start,end;
    
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st = new StringTokenizer(br.readLine());
        
        n = Integer.parseInt(st.nextToken());
        m = Integer.parseInt(st.nextToken());
        
        ArrayList<Integer> arr = new ArrayList<>();
        
        for(int i =0; i<n; i++){
            arr.add(i+1);
        }
        
        for(int j=0;j<m;j++){
            st = new StringTokenizer(br.readLine());
            start = Integer.parseInt(st.nextToken());
            end = Integer.parseInt(st.nextToken());
            
            Collections.reverse(arr.subList(start-1, end));
        }
        
        br.close();
        StringBuilder sb = new StringBuilder();
        
        for(int num : arr){
            sb.append(Integer.toString(num)).append(" ");
        }
        
        System.out.println(sb.toString());
       
    }
}

잘 보면 아까 반복문을 사용하여 구현하였던 부분이 

Collections.reverse(arr.subList(start-1, end));

단 한줄로 끝난것을 볼 수 있다.

 

우선 subList부터 알아보자.

ArrayListsubList() 메서드는 원본 리스트에서 지정한 범위에 해당하는 부분 리스트를 반환하는 메서드인데 이를 통해 원본 리스트의 일부분에 접근하거나 조작할 수 있다.

즉, 원본의 특정 부분을 떼와서 조작 할 수 있고, 이 조작을 마치면 원본 리스트도 똑같이 변경되는 것이 핵심이다.

사용은 간단한데, 그냥 인자로 시작과 끝낼 인덱스만 넣어주면 된다.

 

그다음은 reverse 메서드 인데, Collections 클래스의 메서드로 List 인터페이스를 구현한 컬렉션에만 적용이 가능하다.

즉, 배열에는 사용할 수가 없고, 배열을 Arrays.asList() 메서드를 사용하여 List 인터페이스로 바꾸어 주어야 사용이 가능하다.

기능은 인자로 받은 List를 역순으로 바꿔준다.

 

정리해보면, SubList() 메서드를 통하여 역순으로 바꿔줄 서브 List를 구성하고, 해당 리스트를 reverse() 메서드를 통하여 역순으로 바꿔주면서 원본 ArrayList의 순서도 자동으로 바뀌는 것.

이렇게 하면 굳이 반복문을 사용하지 않더라도 간단하게 역순의 배열을 만드는 것이 가능하다.