Notice
Recent Posts
Recent Comments
Link
개발자는 기록이 답이다
자바(Java) 알고리즘 문제풀이 입문: 코딩테스트 대비(two pointers_공통 원소 구하기) 본문
알고리즘/인프런 - Java알고리즘 입문
자바(Java) 알고리즘 문제풀이 입문: 코딩테스트 대비(two pointers_공통 원소 구하기)
slow-walker 2023. 9. 27. 02:18
(위의 링크는 인프런 로그인 후, 해당 강의를 사지 않으면 접속이 되지 않습니다)
2. 공통원소 구하기
예시 입력 1
5
1 3 9 5 2
5
3 2 5 7 8
예시 출력 1
2 3 5
내가 푼 풀이(Time: 794ms Memory: 35M)
입력받은 배열 2개를 오름차순으로 정리 해준 뒤, p1이랑 p2가 같은 교집합 일경우만 list에 추가한다.
나는 무조건 정렬은 쓰면 안되는 줄 알았는데, 이 문제에서는 정렬 오름차순이 꼭 필요했다.
강의 내용도 똑같다.
package TwoPointers_SlidingWindow.공통원소구하기_two_pointers;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Scanner;
public class Main {
public ArrayList<Integer> solution(int n, int m, int[] a, int[] b) {
Arrays.sort(a);
Arrays.sort(b);
ArrayList<Integer> list = new ArrayList<>();
int p1 = 0, p2 = 0;
while (p1 < n && p2 < m) {
if(a[p1] == b[p2]) {
list.add(a[p1]);
p1++;
p2++;
} else if( a[p1] < b[p2]) {
p1++;
} else {
p2++;
}
}
return list;
}
public static void main(String[] args) {
Main T = new Main();
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int[] a = new int[n];
for (int i = 0; i < n; i++) {
a[i] = sc.nextInt();
}
int m = sc.nextInt();
int[] b = new int[m];
for (int i = 0; i < m; i++) {
b[i] = sc.nextInt();
}
for (int x : T.solution(n, m ,a, b)) {
System.out.print(x + " ");
}
}
}
강의 풀이 (Time: 761ms Memory: 35MB)
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Scanner;
public class Answer {
public ArrayList<Integer> solution(int n, int m, int[] a, int[] b) {
ArrayList<Integer> answer = new ArrayList<>();
Arrays.sort(a);
Arrays.sort(b);
int p1 = 0, p2 = 0;
while(p1 < n && p2 < m) {
if(a[p1] == b[p2]) {
answer.add(a[p1]);
p1++;
p2++;
}else if (a[p1] < b[p2]) p1 ++; // 작은 쪽을 증가 시켜라
else p2++;
}
return answer;
}
public static void main(String[] args) {
Answer T = new Answer();
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int[] a = new int[n];
for (int i = 0; i < n; i++) {
a[i] = sc.nextInt();
}
int m = sc.nextInt();
int[] b = new int[m];
for (int i = 0; i < m; i++) {
b[i] = sc.nextInt();
}
for (int x : T.solution(n, m ,a, b)) {
System.out.print(x + " ");
}
}
}
투 포인터 사용한 교집합 구하기
- 두 배열을 정렬합니다.
- 두 개의 포인터를 각 배열의 시작 부분에서 시작합니다.
- 두 포인터가 가리키는 값을 비교합니다.
- 만약 두 포인터가 가리키는 값이 같다면, 이 값을 교집합에 추가하고 두 포인터를 모두 한 칸씩 앞으로 이동합니다.
- 만약 첫 번째 배열의 포인터가 가리키는 값이 두 번째 배열의 포인터가 가리키는 값보다 작다면, 첫 번째 배열의 포인터를 한 칸 앞으로 이동합니다.
- 만약 첫 번째 배열의 포인터가 가리키는 값이 두 번째 배열의 포인터가 가리키는 값보다 크다면, 두 번째 배열의 포인터를 한 칸 앞으로 이동합니다.
- 두 포인터 중 하나라도 배열의 끝에 도달하면 교집합을 찾는 과정을 종료합니다.
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class IntersectionOfTwoArrays {
public static int[] findIntersection(int[] nums1, int[] nums2) {
Arrays.sort(nums1); // 첫 번째 배열 정렬
Arrays.sort(nums2); // 두 번째 배열 정렬
List<Integer> intersectionList = new ArrayList<>();
int pointer1 = 0; // 첫 번째 배열의 포인터
int pointer2 = 0; // 두 번째 배열의 포인터
while (pointer1 < nums1.length && pointer2 < nums2.length) {
int num1 = nums1[pointer1];
int num2 = nums2[pointer2];
if (num1 == num2) {
// 두 배열의 현재 요소가 같으면 교집합에 추가하고 두 포인터를 이동
intersectionList.add(num1);
pointer1++;
pointer2++;
} else if (num1 < num2) {
// 첫 번째 배열의 현재 요소가 작으면 첫 번째 배열의 포인터 이동
pointer1++;
} else {
// 두 번째 배열의 현재 요소가 작으면 두 번째 배열의 포인터 이동
pointer2++;
}
}
// List를 배열로 변환
int[] intersectionArray = new int[intersectionList.size()];
for (int i = 0; i < intersectionList.size(); i++) {
intersectionArray[i] = intersectionList.get(i);
}
return intersectionArray;
}
public static void main(String[] args) {
int[] nums1 = {1, 2, 2, 1};
int[] nums2 = {2, 2};
int[] intersection = findIntersection(nums1, nums2);
System.out.print("교집합: ");
for (int num : intersection) {
System.out.print(num + " ");
}
}
}
투 포인터 사용한 합집합 구하기
- 두 배열을 정렬합니다.
- 두 개의 포인터를 각 배열의 시작 부분에서 시작합니다.
- 두 포인터가 가리키는 값을 비교합니다.
- 만약 두 포인터가 가리키는 값이 같다면, 이 값을 합집합에 추가하고 두 포인터를 모두 한 칸씩 앞으로 이동합니다.
- 만약 첫 번째 배열의 포인터가 가리키는 값이 두 번째 배열의 포인터가 가리키는 값보다 작다면, 첫 번째 배열의 포인터를 한 칸 앞으로 이동합니다.
- 만약 첫 번째 배열의 포인터가 가리키는 값이 두 번째 배열의 포인터가 가리키는 값보다 크다면, 두 번째 배열의 포인터를 한 칸 앞으로 이동합니다.
- 두 포인터 중 하나라도 배열의 끝에 도달하면 합집합을 찾는 과정을 종료합니다.
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class UnionOfTwoArrays {
public static int[] findUnion(int[] nums1, int[] nums2) {
Arrays.sort(nums1); // 첫 번째 배열 정렬
Arrays.sort(nums2); // 두 번째 배열 정렬
List<Integer> unionList = new ArrayList<>();
int pointer1 = 0; // 첫 번째 배열의 포인터
int pointer2 = 0; // 두 번째 배열의 포인터
while (pointer1 < nums1.length || pointer2 < nums2.length) {
if (pointer1 < nums1.length && (pointer2 >= nums2.length || nums1[pointer1] < nums2[pointer2])) {
// 첫 번째 배열의 요소가 작거나 두 번째 배열에 요소가 없을 때
unionList.add(nums1[pointer1]);
pointer1++;
} else if (pointer2 < nums2.length && (pointer1 >= nums1.length || nums2[pointer2] < nums1[pointer1])) {
// 두 번째 배열의 요소가 작거나 첫 번째 배열에 요소가 없을 때
unionList.add(nums2[pointer2]);
pointer2++;
} else {
// 두 배열의 현재 요소가 같으면 한 번만 추가하고 두 포인터 모두 이동
unionList.add(nums1[pointer1]);
pointer1++;
pointer2++;
}
}
// List를 배열로 변환
int[] unionArray = new int[unionList.size()];
for (int i = 0; i < unionList.size
투 포인터 사용한 차집합 구하기
- 두 배열을 정렬합니다.
- 첫 번째 배열(nums1)을 순회하면서 두 번째 배열(nums2)에 없는 요소를 찾습니다.
- 두 개의 포인터를 각 배열의 시작 부분에서 시작합니다.
- 첫 번째 배열의 현재 요소와 두 번째 배열의 현재 요소를 비교합니다.
- 만약 두 배열의 현재 요소가 같다면, 두 포인터를 모두 한 칸씩 앞으로 이동합니다.
- 만약 첫 번째 배열의 현재 요소가 두 번째 배열의 현재 요소보다 작다면, 첫 번째 배열의 포인터를 한 칸 앞으로 이동합니다.
- 만약 첫 번째 배열의 현재 요소가 두 번째 배열의 현재 요소보다 크다면, 두 번째 배열의 포인터를 한 칸 앞으로 이동합니다.
- 첫 번째 배열의 요소가 두 번째 배열의 요소보다 큰 경우만 차집합에 추가합니다.
- 두 포인터 중 하나라도 배열의 끝에 도달하면 차집합을 찾는 과정을 종료합니다.
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class DifferenceOfTwoArrays {
public static int[] findDifference(int[] nums1, int[] nums2) {
Arrays.sort(nums1); // 첫 번째 배열 정렬
Arrays.sort(nums2); // 두 번째 배열 정렬
List<Integer> differenceList = new ArrayList<>();
int pointer1 = 0; // 첫 번째 배열의 포인터
int pointer2 = 0; // 두 번째 배열의 포인터
while (pointer1 < nums1.length && pointer2 < nums2.length) {
int num1 = nums1[pointer1];
int num2 = nums2[pointer2];
if (num1 == num2) {
// 두 배열의 현재 요소가 같으면 두 포인터를 모두 한 칸씩 앞으로 이동
pointer1++;
pointer2++;
} else if (num1 < num2) {
// 첫 번째 배열의 현재 요소가 두 번째 배열의 현재 요소보다 작으면 첫 번째 배열의 포인터 이동
pointer1++;
} else {
// 첫 번째 배열의 현재 요소가 두 번째 배열의 현재 요소보다 크면 두 번째 배열의 포인터 이동
differenceList.add(num2);
pointer2++;
}
}
// 두 번째 배열을 모두 탐색한 후, 첫 번째 배열에 남아 있는 요소들을 차집합에 추가
while (pointer1 < nums1.length) {
differenceList.add(nums1[pointer1]);
pointer1++;
}
// List를 배열로 변환
int[] differenceArray = new int[differenceList.size()];
for (int i = 0; i < differenceList.size(); i++) {
differenceArray[i] = differenceList.get(i);
}
return differenceArray;
}
public static void main(String[] args) {
int[] nums1 = {1, 2, 2, 3};
int[] nums2 = {2, 3, 4};
int[] difference = findDifference(nums1, nums2);
System.out.print("차집합: ");
for (int num : difference) {
System.out.print(num + " ");
}
}
}
'알고리즘 > 인프런 - Java알고리즘 입문' 카테고리의 다른 글
자바(Java) 알고리즘 문제풀이 입문: 코딩테스트 대비(Recursive_재귀함수(스택프레임)) (0) | 2023.09.27 |
---|---|
자바(Java) 알고리즘 문제풀이 입문: 코딩테스트 대비(sliding window_최대 매출) (2) | 2023.09.27 |
자바(Java) 알고리즘 문제풀이 입문: 코딩테스트 대비(two pointers_두 배열 합치기) (0) | 2023.09.27 |
자바(Java) 알고리즘 문제풀이 입문: 코딩테스트 대비(Array_임시반장 정하기) (0) | 2023.09.08 |
자바(Java) 알고리즘 문제풀이 입문: 코딩테스트 대비(Array_봉우리) (0) | 2023.09.06 |