Open jaeyyyyy opened 11 months ago
행렬의 덧셈(https://school.programmers.co.kr/learn/courses/30/lessons/12950)
arr1 | arr2 | return |
---|---|---|
[[1,2],[2,3]] | [[3,4],[5,6]] | [[4,6],[7,9]] |
[[1],[2]] | [[3],[4]] | [[4],[6]] |
2차원 배열을 이용해야하는 문제다. 2차원 배열을 사용해서 문제를 풀어본 적이 있지만 오랜만에 보니 헷갈려서 기록한다. 2차원 배열의 대략적인 모습은 위 그림과 같다.(3행 5열의 2차원 배열) 2차원 배열은 아래처럼 선언할 수 있다.
int[][] = new int [n][m]; // n은 행, m은 열
입출력예 에서 주어진 arr1은 [[1,2],[2,3]]이므로 2행 2열이다. arr2은 [[1],[2]]이므로 2행 1열이다.
int[][] arr1 = new int [2][2];
arr1 = {{1,2},
{2,3}};
int[][] arr2 = new int[][];
arr2 = {{1},
{2}};
arr1과 arr2의 행과 열의 길이는 고정되어 있지 않다. 2차원 배열에서 행과 열의 길이를 구하는 방법은 다음과 같다. 행의 길이 : 배열의 길이와 같다. 열의 길이 : 각 행마다 들어있는 열의 갯수가 다르다면(가변길이배열) 각 행의 길이, 각 행 별 원소의 길이를 구해야한다. 이 문제의 경우 가변배열이 아니므로 arr1[0].length이 arr1배열의 열의 길이가 된다. (0부터 마지막 행까지의 숫자를 넣어도 똑같다는 뜻)
class Solution {
public int[][] solution(int[][] arr1, int[][] arr2) {
int row = arr1.length; // 행
int column = arr1[0].length; // 열
int[][] answer = new int[row][column]; //answer은 arr1이나 arr2과 같은 크기
for(int i = 0; i < row; i++) {
for(int j = 0; j < column; j++) {
answer[i][j] = arr1[i][j] + arr2[i][j];
}
}
return answer;
}
}
제대로 작성했는데 이중반복문에 같은 변수명을 적는 바람에 계속 오류가 났던 문제.. 이중반복문을 작성할 때는 다른 변수명으로 제대로 적자.
이제까지 뭐가 행인지 뭐가 열인지 모르고 걍 살아왔는데(비설 오픈) 더 이상 그렇게 살 수 없게 됨 모르면 배열 문제는 죄다 못 풀게 된다.. 지금이라도 외워라.
같은 숫자는 싫어(https://school.programmers.co.kr/learn/courses/30/lessons/12906) 배열 arr가 주어집니다. 배열 arr의 각 원소는 숫자 0부터 9까지로 이루어져 있습니다. 이때, 배열 arr에서 연속적으로 나타나는 숫자는 하나만 남기고 전부 제거하려고 합니다. 단, 제거된 후 남은 수들을 반환할 때는 배열 arr의 원소들의 순서를 유지해야 합니다. 예를 들면,
배열 arr에서 연속적으로 나타나는 숫자는 제거하고 남은 수들을 return 하는 solution 함수를 완성해 주세요.
arr | answer |
---|---|
[1,1,3,3,0,1,1] | [1,3,0,1] |
[4,4,4,3,3] | [4,3] |
처음에 아래처럼 작성했는데 틀려서 다시 보니 붙어있는 중복 원소들을 제거하는 것이었다..
import java.util.Arrays;
import java.util.LinkedHashSet;
public class Solution {
public int[] solution(int []arr) {
// Integer를 담는 LinkedHashSet 선언
LinkedHashSet<Integer> linkedhashSet = new LinkedHashSet<>();
for(int n : arr) { // for문을 돌면서 arr의 원소를 linkedhashSet에 추가
linkedhashSet.add(n);
}
int[] answer = new int[linkedhashSet.size()]; // linkedhashSet의 길이만큼 answer 배열 생성
int index = 0; // 인덱스
for(int n: linkedhashSet) {
answer[index++] = n; // linkedhashSet의 값을 answer 배열에 넣음
}
// [실행] 버튼을 누르면 출력 값을 볼 수 있습니다.
System.out.println(Arrays.toString(answer));
return answer;
}
}
이렇게 작성하면 모든 중복 원소들을 제거하게 된다. 문제 카테고리가 스택이니 스택을 사용해보자.. 스택은 맨 마지막에 추가된 요소가 먼저 꺼내지는 구조다.
스택 관련 메서드
push(E item) 해당 item을 Stack의 top에 삽입
pop() Stack의 top에 있는 item을 삭제하고 해당 item을 반환
peek() Stack의 top에 있는 item을 삭제하지않고 해당 item을 반환
스택에 값을 하나씩 넣되, 스택의 최상단 값이 arr[i]와 동일하다면 스택에 값을 추가하지 않고, 동일하지 않은 경우(즉, 중복값이 아닌 경우에만) 스택에 값을 추가한다.
import java.util.Stack;
import java.util.Arrays;
public class Solution {
public int[] solution(int []arr) {
// Integer를 담는 Stack 선언
Stack<Integer> stack = new Stack<>();
// arr의 길이만큼 반복문을 돌면서
for(int i =0; i < arr.length; i++) {
// 배열 첫번째 숫자를 stack에 넣고
if(i == 0){
stack.push(arr[i]);
// 인덱스 1부터는 stack의 최상단 값이 arr[i]의 값과 일치하지 않을 경우에만 stack에 해당 값 push
} else if (stack.peek() != arr[i]) {
stack.push(arr[i]);
}
}
// stack의 사이즈만큼 answer 배열 생성
int[] answer = new int[stack.size()];
// 스택은 제일 나중에 추가한 값부터 꺼낼 수 있으므로 i값을 마이너스 해가며 뽑는다.
for(int i = stack.size()-1; i>=0; i--) {
answer[i] = stack.pop();
}
// [실행] 버튼을 누르면 출력 값을 볼 수 있습니다.
System.out.println(Arrays.toString(answer));
return answer;
}
}
스택...어렵다... 많이 써봐야겠다. 아직 감이 안 잡힌다
문제 1
문제
최대공약수와 최소공배수(https://school.programmers.co.kr/learn/courses/30/lessons/12940)
입출력 예
입출력 예 1
입출력 예 2
문제 풀이
어떻게 구해야할지 막연해서 찾아봤다..
방법 1. 1부터 n까지, 그리고 1부터 m까지 자연수 중 하나를 a라고 한다면, n과 m을 a로 나눈 나머지가 0이어야 a가 최대공약수가된다. 최소공배수는 n과 m을 곱한 값을 최대공약수로 나누면 된다.
for문을 사용해서 i가 1부터 n까지 그리고 1부터 m까지 두 가지 조건을 모두 만족하도록 했다.
방법 2. 유클리드 호제법을 이용한다. 이 방식은 큰 수를 작은 수로 나눈 나머지를 반복적으로 취하여 나머지가 0이 될때까지 작동하여 최대공약수를 구하는 방식이다.
최대공약수(Greatest Common Divisor, GCD)
방법 3. 자바의 BigInteger 내장함수를 사용한다. 자바에서는 BigInteger 클래스에 최대공약수를 구할 수 있는 gcd() 메서드를 제공한다.
회고
문제를 푸는 데 정말 많은 방법이 있다는 걸 새삼 깨달았던 문제. 그러나 그 방법을 생각해내는 게 어려웠다. 한 번만 풀어보는 걸로는 기억에 남지 않을테니 최대한 많이 보고 정리해봐야겠다...