코테 스터디가 시작되는 날이다 코테를 조금 풀어봤지만 본격적으로 해보지는 않았기에
조금(?) 무서웠다.
문제 제목부터 너무 귀여웠다 폰켓몬이라니.. 과연 문제 난이도는 어떨까 ?
이게 무슨 말이지..?
내 뇌를 누군가 꿀밤먹인거 같은 느낌이였다.
이게 비기너 수준의 문제라구..? 하며 겁을 먹어버렸다.
그래도 풀어야지 .. 해야지.. 하며 다시 마음을 다잡고 천천히 문제를 읽어내려갔다.
일단 문제를 정리해보자면
착각할수 있는 문장이 있었다 이 문제는 선택할 수 있는 경우의 수가 아니라 선택할 수 있는 '포켓몬 종류의 수'가 최대일 때를 구하는 것이다
[3,3,3,2,2,2] 이 배열이 있을경우 안에 6마리의 폰켓몬이 있으므로
총 3마리의 폰켓몬을 골라야만 합니다.. 가장 많은 종류의 폰켓몬을 고르기 위해서는 3번 포켓몬 한마리 2번폰켓몬 2마리를 고르거나 혹은 2번폰켓몬 2마리와 3번폰켓몬 1마리 이렇게 고를수 있습니다
입력받은 nums 배열에 원소값들이 존재하는데
이 배열에서 최대 num의 길이 / 2 만큼 원소를 선택 가능하다.
예를 들어서 만약 배열의 길이가 6이라고하면 총 3개를 선택 할 수 있는것이다.
하지만 원소를 선택할 경우 중복되는 원소는 선택하면 안된다.
예시를 보도록 하자
처음 예를 보면 [ 3, 1, 2 ,3 ] 을 입력받았다고 생각해보자
nums = [3,1,2,3] 에서는 nums 의 길이 / 2 즉 최대 2개만 선택이 가능하다
여기서 문제 조건에 중복된 원소는 고를 필요가 없으니 nums = [1,2,3] 에서 최대 2개를 고를 수 있다 즉 정답은 2가 되는것이다.
그렇다면 다른 예시를 봐보자 [3,3,3,2,2,2] 를 입력받았다고 해보자.
이어서 nums 의 길이 / 2 는 3 이다 이때 중복된 원소는 고를 필요는 없으니 [3,2] 에서 최대 3개만 고르면 되지만 중복 원소를 제거하면 원소가 2개밖에 없다 이럴경우 nums에 있는 것들을 모두 골라주면 정답이 된다고 생각했다.
결국 이때 중요한 키워드는 중복 제거
라는 키워드인거 같아 공부를 하기 시작했다.
내가 아는 HASHSET ..
일단 중복제거 해주는 녀석으로만 알고있었다.. 사실 자세하게 공부하진 않았다
그때 당시 공부했을땐 과정이 뭐 중요한가 ? 라고 생각했지만 요즘 들어서 개발을 공부할땐 과정
과 왜?
라는게 참 중요하다고 생각한다.
일단 자바의 hashset은 set인터페이스에서 지원하는 구현 클래스 라고한다.
순서대로 입력되지 않고 일정하게 유지되지 않는게 특징이다
또한 null 값도 허용한다 그리고 가장 중요한 특징은 중복을 허용하지 않는다는 것이다.
hashset은 객체를 저장하기 전에 먼저 객체의 hashcode()메소드를 호출해 해시코드를 얻어낸 다음 저장되어 있는 객체들의 해시 코드와 비교한뒤 같은 해시코드가 있따면 다시 equals()메소드로 두 객체를 비교하여 true값이 나온다면 동일한 객체로 판단하고 저장하지 않는다.
문자열을 hashset에 저장할 경우 같은 문자열을 갖는 string 객체는 동일한 객체로 간주되고 다른 문자열을 갖는 string 객체는 다른 객체로 간주되는데 그 이유는 string 클래스가 hashcode()와 equals() 메소드를 재정의 하여 같은 문자열일 경우 hashCode() 의 리턴값을 같게 equlas() 의 리턴값은 true 값이 나오도록 했기 때문이다.
hashset 의 변수를 선언하는 방법이다 .
HashSet<Integer> set = new HashSet<Integer>();
HashSet<String> set = new HashSet<String>();
이렇게 HashSet<데이터타입> 변수명 = new HashSet<데이터타입>(); 으로 선언해 주면 된다
public class HashSetTest {
public static void main(String[] args) {
// Integer
HashSet<Integer> set = new HashSet<Integer>();
set.add(1);
set.add(2);
set.add(3);
set.add(1);
// String
HashSet<String> set2 = new HashSet<String>();
set2.add("a");
set2.add("b");
set2.add("c");
set2.add("a");
}
}
HashSet의 add(value) 메소드를 사용하여 값을 추가합니다
추가되는 값은 HashSet<데이터타입>의 맞는 데이터만 추가해줍니다
public class HashSetTest {
public static void main(String[] args) {
// Integer
HashSet<Integer> set = new HashSet<Integer>();
set.remove(1);
set.clear();
// String
HashSet<String> set2 = new HashSet<String>();
set2.remove("a");
set2.clear();
}
}
HashSet의 remove(value) 메소드를 사용하면 원하는 value 값만 삭제가 된다.
public class HashSetTest {
public static void main(String[] args) {
// Integer
HashSet<Integer> set = new HashSet<Integer>();
set.add(1);
set.add(2);
set.add(3);
set.add(1);
System.out.println("set의 크기 : " + set.size());
// String
HashSet<String> set2 = new HashSet<String>();
set2.add("a");
set2.add("b");
set2.add("c");
set2.add("a");
System.out.println("set2의 크기 : " + set2.size());
}
}
Size() 메소드 사용시 둘 다 결과가 3으로 출력이 됩니다
public class HashSetTest {
public static void main(String[] args) {
// Integer
HashSet<Integer> set = new HashSet<Integer>();
set.add(1);
set.add(2);
set.add(3);
set.add(1);
System.out.println("1은 있는가? : " + set.contains(1));
// String
HashSet<String> set2 = new HashSet<String>();
set2.add("a");
set2.add("b");
set2.add("c");
set2.add("a");
System.out.println("a는 있는가? : " + set2.contains("a"));
}
}
반환값으로는 boolean 값이 나온다
코드 반환값은 true로 나오게 됩니다.
사실 고민하다가 HashSet으로 풀긴하였지만
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
public class Solution {
public int solution(int[] nums){
int answer = nums.length / 2;
HashSet<Integer> numHash = new HashSet<>();
for (int num : nums) {
numHash.add(num);
}
if(answer > numHash.size()){
return numHash.size();
}else {
return answer;
}
}
}
for문으로만 풀고싶었다.
이유는 아직 알고리즘 초보이기도 하고 내장함수에만 의존하다보면 나중에 감도 잊을거같아서 for문으로도 풀어보았다.
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
public class Solution {
public int solution(int[] nums){
int[] counts = new int[200001];
int answer = 0;
for(int i = 0; i < nums.length; i++) {
if(counts[nums[i]] == 0) {
answer++;
}
counts[nums[i]]++;
}
if(answer > nums.length / 2) {
answer = nums.length / 2;
}
return answer;
}
}
결론을 말해보자면 차근차근 읽고 이해하고 풀어보면 난이도 자체는 쉬운거 같다.
어렵지도않고 사실 이 문제는 코드를 짜는 실력보다 독해력을 요구하는 문제가 아니였을까 싶다..
앞으로는 문제가 길거나 어려워 보인다고해서 쫄지말고 차근차근 정리해나가 풀어보도록 하겠다.