문제 설명
정수 배열 numbers가 주어집니다. numbers에서 서로 다른 인덱스에 있는 두 개의 수를 뽑아 더해서 만들 수 있는 모든 수를 배열에 오름차순으로 담아 return 하도록 solution 함수를 완성해주세요.
제한사항
- numbers의 길이는 2 이상 100 이하입니다.
- numbers의 모든 수는 0 이상 100 이하입니다.
import java.util.*;
class Solution {
public int[] solution(int[] numbers) {
// 중복을 제거하기 위해 Set 사용
Set sumSet = new HashSet<>();
// 두 개의 숫자를 더해 중복 없이 Set에 추가
for (int i = 0; i < numbers.length; i++) {
for (int j = i + 1; j < numbers.length; j++) {
sumSet.add(numbers[i] + numbers[j]);
}
}
// Set을 List로 변환 후 정렬
List sumList = new ArrayList<>(sumSet);
Collections.sort(sumList);
// 결과를 int 배열로 변환
int[] result = new int[sumList.size()];
for (int i = 0; i < sumList.size(); i++) {
result[i] = sumList.get(i);
}
return result;
}
}
1. Set 초기화
먼저 중복을 제거하기 위해 Set을 사용합니다. Set은 중복된 요소를 허용하지 않는 자료구조입니다.
Set sumSet = new HashSet<>();
2. 두 숫자의 합 계산 및 추가
numbers 배열의 각 요소를 순회하면서 서로 다른 인덱스에 있는 두 숫자의 합을 계산하고 이를 Set에 추가합니다.
for (int i = 0; i < numbers.length; i++) {
for (int j = i + 1; j < numbers.length; j++) {
sumSet.add(numbers[i] + numbers[j]);
}
}
- 첫 번째 for 루프는 배열의 첫 번째 요소부터 마지막 요소까지 순회합니다.
- 두 번째 for 루프는 첫 번째 루프의 현재 요소 다음 요소부터 마지막 요소까지 순회합니다.
- 각 두 요소의 합을 계산하고 sumSet에 추가합니다. Set은 중복을 허용하지 않기 때문에, 동일한 합이 여러 번 계산되더라도 Set에는 한 번만 저장됩니다.
3. Set을 List로 변환 후 정렬
Set을 List로 변환한 후 정렬합니다. List는 순서를 보장하므로, 정렬된 상태로 결과를 얻을 수 있습니다.
List sumList = new ArrayList<>(sumSet);
Collections.sort(sumList);
- new ArrayList<>(sumSet)은 Set을 List로 변환합니다.
- Collections.sort(sumList)는 sumList를 오름차순으로 정렬합니다.
4. List를 int 배열로 변환
정렬된 List를 int 배열로 변환합니다. 이는 최종 결과를 반환하기 위함입니다.
int[] result = new int[sumList.size()];
for (int i = 0; i < sumList.size(); i++) {
result[i] = sumList.get(i);
}
- new int[sumList.size()]로 sumList와 같은 크기의 배열을 생성합니다.
- for 루프를 사용하여 sumList의 각 요소를 result 배열에 복사합니다.
5. 결과 반환
최종적으로 정렬된 고유한 합의 배열을 반환합니다.
return result;
모르는 문법 정리
Set의 주요 메서드
Set 인터페이스와 이를 구현하는 HashSet 클래스는 다양한 메서드를 제공합니다. 이번 예제에서는 add 메서드가 사용되었습니다.
add 메서드
add 메서드는 Set에 요소를 추가합니다. 만약 추가하려는 요소가 이미 Set에 존재하면, Set의 내용은 변경되지 않습니다. 즉, 중복된 값이 저장되지 않습니다.
예제 코드에서의 Set 사용
예제 코드에서 Set을 사용하는 이유는 서로 다른 인덱스에서 두 개의 수를 더한 결과들을 중복 없이 저장하기 위해서입니다.
여기서 각 두 요소의 합을 Set에 추가합니다. 예를 들어, numbers 배열이 [2, 1, 3, 4, 1]인 경우, 다음과 같은 합이 계산되고 Set에 추가됩니다:
- 2 + 1 = 3
- 2 + 3 = 5
- 2 + 4 = 6
- 2 + 1 = 3 (이미 존재하므로 추가되지 않음)
- 1 + 3 = 4
- 1 + 4 = 5 (이미 존재하므로 추가되지 않음)
- 1 + 1 = 2
- 3 + 4 = 7
- 3 + 1 = 4 (이미 존재하므로 추가되지 않음)
- 4 + 1 = 5 (이미 존재하므로 추가되지 않음)
결국 sumSet에는 [3, 5, 6, 4, 2, 7]가 저장됩니다. 이 값들은 중복 없이 저장되었으며, 이후 단계에서 오름차순으로 정렬됩니다.
HashSet의 특징 요약
- 중복 제거: HashSet은 중복된 값을 허용하지 않으므로, 중복 제거가 자동으로 이루어집니다.
- 빠른 성능: HashSet은 일반적으로 요소의 추가, 삭제, 검색이 빠릅니다.
- 순서 없음: 요소들이 저장된 순서를 보장하지 않습니다. 순서가 중요한 경우 LinkedHashSet을 사용할 수 있습니다.
- 다양한 메서드: add, remove, contains 등 다양한 메서드를 통해 요소를 조작할 수 있습니다.
따라서, HashSet은 중복을 제거하고 고유한 요소만을 저장할 때 매우 유용한 자료구조입니다.
List<Integer> sumList = new ArrayList<>();는 자바에서 ArrayList를 초기화하는 코드입니다. ArrayList는 자바 컬렉션 프레임워크의 List 인터페이스를 구현한 클래스 중 하나로, 동적 배열을 사용하여 요소를 저장합니다. 이 코드에 대해 더 자세히 설명하겠습니다.
List와 ArrayList의 개념
List 인터페이스
List는 자바 컬렉션 프레임워크에서 제공하는 인터페이스로, 순서가 있는 요소의 집합을 나타냅니다. List는 중복된 요소를 허용하며, 특정 위치에 요소를 삽입하거나 제거할 수 있는 다양한 메서드를 제공합니다.
ArrayList 클래스
ArrayList는 List 인터페이스를 구현한 클래스 중 하나로, 내부적으로 동적 배열을 사용하여 요소를 저장합니다. ArrayList는 배열과 달리 크기가 고정되지 않고, 요소가 추가되면 자동으로 크기가 증가합니다.
ArrayList 초기화
이 코드는 ArrayList를 초기화하여 sumList라는 변수를 생성합니다. ArrayList는 다음과 같은 특성을 갖고 있습니다:
- 동적 크기: 요소가 추가되면 자동으로 크기가 증가합니다.
- 빠른 임의 접근: 인덱스를 통한 요소 접근이 O(1)의 시간복잡도를 가집니다.
- 순서 보장: 요소가 추가된 순서대로 저장됩니다.
- 유연성: 다양한 유형의 데이터를 저장할 수 있습니다.
예제 코드에서의 ArrayList 사용
예제 코드에서는 Set에 저장된 고유한 합을 List로 변환하여 정렬하기 위해 ArrayList를 사용합니다.
for (int i = 0; i < numbers.length; i++) {
for (int j = i + 1; j < numbers.length; j++) {
sumSet.add(numbers[i] + numbers[j]);
}
}
List<Integer> sumList = new ArrayList<>(sumSet);
Collections.sort(sumList);
ArrayList 초기화와 Set 변환
- new ArrayList<>(sumSet)은 Set을 ArrayList로 변환하여 sumList에 저장합니다.
- ArrayList는 Collection 인터페이스를 구현하는 모든 타입의 컬렉션을 인자로 받아 초기화할 수 있습니다. 이 경우 sumSet의 요소들이 sumList로 복사됩니다.
정렬
- Collections.sort(sumList)는 sumList를 오름차순으로 정렬합니다. Collections는 자바의 유틸리티 클래스이며, 컬렉션과 관련된 다양한 알고리즘을 제공합니다.
ArrayList의 주요 메서드
ArrayList는 List 인터페이스를 구현하기 때문에 다양한 메서드를 제공합니다. 주요 메서드는 다음과 같습니다:
- add(E e): 리스트의 끝에 요소를 추가합니다.
- get(int index): 지정된 위치에 있는 요소를 반환합니다.
- size(): 리스트의 요소 개수를 반환합니다.
- remove(int index): 지정된 위치에 있는 요소를 제거합니다.
- contains(Object o): 리스트에 지정된 요소가 포함되어 있는지 확인합니다.
전체적인 흐름 설명
이제 예제 코드의 전체 흐름을 다시 한 번 설명하겠습니다.
- Set<Integer> sumSet = new HashSet<>();:
- 중복을 허용하지 않는 HashSet을 초기화합니다.
- 두 개의 숫자를 더해 sumSet에 추가:
- numbers 배열의 각 요소를 순회하면서 서로 다른 인덱스의 두 숫자의 합을 sumSet에 추가합니다. 이 과정에서 중복이 제거됩니다.
- List<Integer> sumList = new ArrayList<>(sumSet);:
- HashSet을 ArrayList로 변환하여 sumList에 저장합니다.
- Collections.sort(sumList);:
- sumList를 오름차순으로 정렬합니다.
- int[] result = new int[sumList.size()];:
- sumList와 같은 크기의 배열을 생성합니다.
- for (int i = 0; i < sumList.size(); i++) { result[i] = sumList.get(i); }:
- sumList의 각 요소를 result 배열에 복사합니다.
- return result;:
- 정렬된 고유한 합의 배열을 반환합니다.
Collections.sort()는 자바의 Collections 클래스에서 제공하는 정적 메서드로, 리스트를 정렬하는 데 사용됩니다. 이 메서드는 기본적으로 오름차순으로 리스트의 요소들을 정렬합니다. Collections 클래스는 자바의 유틸리티 클래스이며, 다양한 컬렉션과 관련된 메서드를 제공합니다.
기본 사용법
여기서 list는 List 인터페이스를 구현하는 어떤 객체도 될 수 있습니다. 이 메서드는 Comparable 인터페이스를 구현한 객체들로 구성된 리스트를 정렬할 수 있습니다.
예제
import java.util.*;
public class Main {
public static void main(String[] args) {
List list = new ArrayList<>(Arrays.asList(5, 3, 4, 1, 2));
Collections.sort(list);
System.out.println(list); // [1, 2, 3, 4, 5]
}
}
이 예제에서는 ArrayList를 생성하고 Collections.sort()를 사용하여 리스트를 오름차순으로 정렬합니다.
Comparable 인터페이스
기본 정렬 순서는 요소들이 Comparable 인터페이스를 구현하고 있어야 합니다. Comparable 인터페이스는 compareTo 메서드를 정의하며, 이 메서드를 통해 객체의 자연 순서를 결정합니다.
예를 들어, Integer 클래스는 Comparable 인터페이스를 구현하고 있어, 정수 리스트를 쉽게 정렬할 수 있습니다.
사용자 정의 정렬 순서
Collections.sort()는 두 번째 인자로 Comparator를 받아 사용자 정의 정렬을 수행할 수 있습니다. Comparator 인터페이스는 compare 메서드를 정의하며, 두 객체의 순서를 비교하는 로직을 제공합니다.
예제: 사용자 정의 Comparator
import java.util.*;
public class Main {
public static void main(String[] args) {
List list = new ArrayList<>(Arrays.asList("banana", "apple", "pear", "grape"));
// 문자열 길이를 기준으로 정렬하는 Comparator
Comparator lengthComparator = new Comparator() {
@Override
public int compare(String s1, String s2) {
return Integer.compare(s1.length(), s2.length());
}
};
Collections.sort(list, lengthComparator);
System.out.println(list); // [pear, apple, grape, banana]
}
}
이 예제에서는 문자열의 길이를 기준으로 정렬하는 Comparator를 정의하고, Collections.sort()에 전달하여 리스트를 정렬합니다.
Collections.sort()의 작동 원리
- Collections.sort()는 내부적으로 List의 toArray 메서드를 호출하여 요소들을 배열로 복사합니다.
- 배열을 정렬한 후 다시 리스트로 복사합니다.
- 기본적으로 TimSort 알고리즘을 사용하여 정렬을 수행합니다. TimSort는 MergeSort와 InsertionSort를 결합한 효율적인 정렬 알고리즘입니다.
'(Java)코테연습' 카테고리의 다른 글
푸드 파이트 (3) | 2024.07.23 |
---|---|
가장 가까운 같은 글자 (0) | 2024.07.20 |
k번째수 (0) | 2024.07.18 |
문자열 내 마음대로 정렬하기 (0) | 2024.07.17 |
숫자 문자열과 영단어 (0) | 2024.07.16 |