Day 20 함수(메소드)
Day20 20단계 2023-11-09
1. 배열의 길이를 2의 거듭제곱으로 만들기
- 내 풀이 : arr의 길이를 전달 받아 가장 가까운 2의 거듭제곱 수를 반환하는 함수를 만들고, 이 함수에서 변환된 길이를 새 배열의 길이로 지정해서 기존 배열의 요소를 옮겼다.
- 다른 사람들의 풀이와 비교해보니 너무 어렵게 생각해서 푼 듯 하다.
- Math 클래스
class Solution {
public static int twoPow(int length) {
if (Integer.bitCount(length) != 1) {
int pow = (int)Math.log10(Integer.parseInt(Integer.toBinaryString(length)));
length = (int)Math.pow(2, pow+1);
}
return length;
}
public int[] solution(int[] arr) {
int length = arr.length;
int[] answer = new int[twoPow(length)];
for(int i = 0; i < arr.length; i++) {
answer[i] = arr[i];
}
return answer;
}
}
- 다른 사람 풀이 : 크기가 1인 length가 arr의 길이보다 클 때까지 2를 곱해서 새 배열의 길이를 구하고, 기존 배열에서 Arrays.copyOf(arr, length)를 사용해서 새 배열을 만들었다.
int length = 1;
while (length < arr.length) length *= 2;
return Arrays.copyOf(arr, length);
- 다른 사람 풀이 2 : Stream을 사용하여 배열을 새로 만들었고, Math.log를 활용한 길이 구하는 방법을 Math.ceil(Math.log(arr.length)/Math.log(2))로 구했다.
- 자연 로그(ln)로 각각 arr.length와 2의 지수를 얻고, arr.length 지수 결과를 2의 지수 결과로 나누어 올림 계산한 값을 pow(2, result)로 사용했다.
int length = (int) Math.pow(2, (Math.ceil(Math.log(arr.length)/Math.log(2))))
2. 배열 비교하기
- 내 풀이 : 문제에서 주어진 조건별로 if문을 사용해 크기별로 반환값을 지정했다.
class Solution {
public int solution(int[] arr1, int[] arr2) {
if (arr1.length > arr2.length) return 1;
else if (arr1.length < arr2.length) return -1;
else {
int sum1 = 0;
int sum2 = 0;
for(int i : arr1) sum1 += i;
for(int j : arr2) sum2 += j;
return (sum1 > sum2) ? 1 : (sum1 == sum2) ? 0 : -1;
}
}
}
- 다른 사람 풀이 : Integer.compare()을 사용해서 비교 결과값을 반환값으로 사용했다.
- Wrapper 클래스#1. Integer 클래스
3. 문자열 묶기
- 내 풀이 : HashMap을 사용해서 strArr의 배열 요소의 길이를 key로 설정, value는 key가 등장한 횟수로 저장하였고, value 중 가장 높은 값을 반환했다.
- 다른 사람의 풀이와 비교하던 중 1181번 단어 정렬의 경우처럼 HashMap과 int 배열을 사용한 것의 속도 차이가 궁금해서 비교해봤다.
import java.util.*;
class Solution {
public int solution(String[] strArr) {
HashMap<Integer, Integer> map = new HashMap<>();
int answer = 0;
for(String s : strArr) {
map.put(s.length(), map.getOrDefault(s.length(), 0) + 1);
}
for(Map.Entry<Integer, Integer> entry : map.entrySet()) {
answer = Math.max(answer, entry.getValue());
}
return answer;
}
}
- 다른 사람 풀이 : strArr의 원소의 길이가 30까지이므로, 길이가 (30+1)(길이가 0인 String은 주어지지 않음)인 int배열을 만든다.
- 각 strArr의 길이를 확인해서 int 배열에 strArr 길이에 해당하는 인덱스 요소를 1씩 증가시킨 후, 최대값을 반환했다.
- 10989번 수 정렬하기 3의 카운트 정렬을 사용한 풀이
- 비교를 위해 다른 사람 풀이의 원본 코드를 첨부했다.
class Solution {
public int solution(String[] strArr) {
int answer = 0;
int[] lengArr = new int[31];
for(int i=0; i<strArr.length; i++) {
lengArr[strArr[i].length()]++;
}
for(int i=0; i<=30; i++) {
answer = Math.max(answer, lengArr[i]);
}
return answer;
}
}
- 다른 사람 풀이를 향상된 for문으로 수정한 코드
- 위 코드를 간단하게 작성할 수 있을 것 같아서 향상된 for문으로 수정하였고, 속도 차이가 있는지 비교해보았다.
class Solution {
public int solution(String[] strArr) {
int answer = 0;
int[] num = new int[30+1];
for(String s : strArr) num[s.length()]++;
for(int i : num) answer = Math.max(answer, i);
return answer;
}
}
- 코드들 처리 속도를 비교한 결과
- 결론 : 3번 코드가 가장 최적화 되어있다.
