문제
https://school.programmers.co.kr/learn/courses/30/lessons/147354
풀이(20분)
import java.util.*;
class Solution {
public int solution(int[][] data, int col, int row_begin, int row_end) {
int answer = 0;
ArrayList<Point> pointList = new ArrayList<>();
for(int i = 0; i < data.length; i++){
pointList.add(new Point(i, data[i][0], data[i][col-1]));
}
Collections.sort(pointList, (o1, o2) ->{
int o1Id = o1.id;
int o2Id = o2.id;
int o1Col = o1.col;
int o2Col = o2.col;
if(o1Col != o2Col){
return o1Col - o2Col;
}
return o2Id - o1Id;
} );
int sum = 0;
for(int i = row_begin; i <= row_end; i++){
Point tempPoint = pointList.get(i-1);
int tempSum = 0;
for(int j = 0; j < data[0].length; j++){
tempSum += data[tempPoint.idx][j] % i;
}
sum = sum ^ tempSum;
}
answer = sum;
return answer;
}
public static class Point{
int idx;
int id;
int col;
public Point(int idx, int id, int col){
this.idx = idx;
this.id = id;
this.col = col;
}
}
}
일단 풀이를 시작하기 앞서 알아둬야 할 두 가지에 대해 먼저 정리하자.
1. Collections.sort()
일반적으로 Collections.sort(list) 같이 써서 오름차순 정렬을 하거나, Collections.sort(list, Comparator.reverseOrder()); 같은 내림차순 정렬을 쓸 수 있다.
하지만 옆에 식을 적어줌으로써 내가 원하는 방식의 정렬을 할 수 있다.
예를 들어 오름차순의 경우 Collections.sort(list, (o1, o2) -> {return o1 - o2})를 하면 오름차순이 되고, o2-o1을 하면 내림차순이 된다.
여기서 알아두어야 할 것은 음수일 경우 현재 o1과 o2를 유지하고, 양수일 경우 o2와 o1의 순서를 바꾼다고 생각하면 된다.
따라서 풀이에 나온 코드는 다음과 같다.
Collections.sort(pointList, (o1, o2) ->{
int o1Id = o1.id;
int o2Id = o2.id;
int o1Col = o1.col;
int o2Col = o2.col;
if(o1Col != o2Col){
return o1Col - o2Col;
}
return o2Id - o1Id;
} );
여기서 PointList는 point를 가지는 리스트이며 idx(원래 data용 인덱스), id, col에 대한 값을 가진다. 이때 문제에서 아래와 같은 조건을 주었다. 테이블의 튜플을 col번째 컬럼의 값을 기준으로 오름차순 정렬을 하되, 만약 그 값이 동일하면 기본키인 첫 번째 컬럼의 값을 기준으로 내림차순 정렬합니다. 따라서, col에 대한 값이 다르다면 o1Col- o2Col을 통해 col 값을 이용한 오름차순 정렬을 해준다. 만약 같다면, o2Id - o1Id를 하여 id 값을 이용한 내림차순 정렬을 해주면 되는 것이다.
2. 비트연산자
사실 & | 연산은 알고 있었어도 XOR연산을 지원하는지 처음 알게 되었다.
java에서 제공하는 비트 연산은 대략 다음과 같다.
& (And)
| (Or)
^ (Xor)
<< (Left Shift) : 비트를 왼쪽으로 밀고, 오른쪽에 0을 채운다.
>> (Right Shift) : 비트를 오른쪽으로 밀고, 오른쪽에 부호비트를 채운다.
>>> (Unsigned Right Shift) : 비트를 오른쪽으로 밀고, 부호와 관계없이 왼쪽에 0을 채운다.
이제 문제의 로직을 살펴보자.
먼저 정렬을 해준 뒤 정렬해준 것의 row_begin 부터 row_end까지의 idx를 꺼내와야 한다.(data는 정렬이 안 되어있으므로)
이후, tempSum에 먼저 mod 연산을 한 합을 구해준 뒤 sum과 XOR 연산을 진행해주면 된다.
'문제 풀이 > 프로그래머스' 카테고리의 다른 글
[프로그래머스] 연속 부분 수열 합의 개수(JAVA) (0) | 2025.01.25 |
---|---|
[프로그래머스] 디펜스 게임(JAVA) (0) | 2025.01.24 |
[프로그래머스] 마법의 엘레베이터(JAVA) (0) | 2025.01.21 |
[프로그래머스] 숫자 변환하기(JAVA) (0) | 2025.01.19 |
[프로그래머스] 뒤에 있는 큰 수 찾기(JAVA) (0) | 2025.01.15 |