프로그래머스 코딩테스트 연습
3진법뒤집기
내가 쓴 코드
- 주어진 숫자열 n을 toString메서드를 사용해 3진법으로 변환 => 1200
- 변환한 3진법을 split메서드로 배열로 변환 => [1,2,0,0]
- 배열로 변환한 3진법을 reverse 메서드로 역순으로 바꿈 => [0,0,2,1]
- 역순으로 바꾼 배열을 join 메서드로 문자열로합침 => 0021
- 합친 메서드를 parseInt 메서드로 숫자로 바꾸는 동시에 10진법으로 변환함
function solution(n) {
//n을 3진법으로 변환
//변환한 3진법을 역순으로 바꾸기
//역순으로 바꾼 3진법을 10진법으로 변환함
return parseInt(n.toString(3).split("").reverse().join(""), 3)
}
전개연산자를 이용하여 배열만들기
- split메서드를 사용하지 않고 전개 연산자를 사용하여 3진법으로 변환한 숫자열n을 배열에 담아 풀이했다.
function solution(n) {
return parseInt([...n.toString(3)].reverse().join(""), 3) //전개연산자로 배열 만들기
}
toString()과 parseInt()
- toString(n)메서드를 사용해 특정 숫자를 n진수로 변환한 할 수 있다는 부분을 처음 알았다
let num = 5
// 숫자5를 2진법인 문자열로 반환
console.log(Num.toString(2)); // 101 type = string
// 숫자5를 3진법인 문자열로 반환
console.log(Num.toString(3)); // 12
- parseInt("변환하고자하는 문자열", "해당수의 진수") 메서드를 사용해 변환하고자하는 문자열을 10진법 숫자열로 변환할 수 있다.
- parseInt("22" , 3) 3진법 문자열 "22"를 10진법 8로 변환하는 과정이다 이때 parseInt의 두번째 인자에는 문자열 "22" 가 어떤 진수인지 기입해야 문자열 "22"를 10진법수로 변환할 수 있다.
let num = 8
//숫자열 8을 3진법문자열로 변환
num.toString(3) // "22"
//3진법 문자열 "22"를 다시 10진법숫자열로 변환
parseInt(num.toString(3), 3) //8 type == number
최소직사각형
내가 쓴 코드
- 빈배열 arr1 과 arr2를 만든다.
- for문에서 i는 0으로 시작하고 매개변수 sizes의 길이만큼 반복하는 반복문을 작성했다 => i =0 , i=1 i = 2 ...
sizes.length = 4
- 반복문 안에서 배열 sizes의 값들이 오름차순으로 정렬되게하는 sort() 메서드를 사용해 배열을 오름차순으로 정렬한다.
sizes[0] = [60, 50] sizes[0].sort(( a ,b ) => a - b) = [50, 60]
sizes[1] = [30, 70], sizes[1].sort(( a ,b ) => a - b) = [30, 70]
sizes[2] = [60, 30], sizes[2].sort(( a ,b ) => a - b) = [30, 60]
sizes[length -1] = [80, 40] sizes[length -1].sort(( a ,b ) => a - b) = [40, 80]
- 빈배열 arr1에 size[i][0]에 인덱스에 해당하는 값을 push메서드로 넣어준다
다.
sizes[0][0] = 50
sizes[1][0] = 30
sizes[2][0] = 30
sizes[length -1][0] = 40
arr1 =[50,30,30,40]
- 빈배열 arr2에 size[i][1]에 인덱스에 해당하는 값을 push메서드로 넣어준다
sizes[0][1] = 60
sizes[1][1] = 70
sizes[2][1] = 60
sizes[length -1][1] = 80
arr2= [60,70,60,80]
- Math.max함수를 이용해 arr1, arr2 각 배열에서 가장큰 값을 찾아 곱한다 이때 가장큰 값을 찾기 위해서는 배열을 전개해서 가장 큰 수를 찾아야 한다.
Math.max는 Number를 인자로 받는 함수이기 때문에 array가 들어가면 NaN을 출력하기 때문에 split메서드나 전개연산자를 사용해 배열을 분해 한후 숫자열들끼리 비교해야한다.
Math.max(arr1) = 50
Math.max(arr2) = 80
return 50 * 80
function solution(sizes) {
//[[60, 50], [30, 70], [60, 30], [80, 40]]
let arr1 = []
let arr2 = []
for (let i = 0; i < sizes.length; i++) {
(sizes[i].sort((a, b) => a - b))
arr1.push(sizes[i][0])
arr2.push(sizes[i][1])
}
// arr1에서 가장 큰 값 * arr2에서 가장 큰 값
return (Math.max(...arr1) * Math.max(...arr2))
}
같은 숫자는 싫어
내가 쓴 코드
- 빈 배열 answer을 생성
- for 반복문을 사용해 i가 0부터 시작하고 i가 배열 arr의 길이만까지 도는 반복문 i를 작성한다.
- 조건문으로 arr의 현재배열의 값 arr[i]와 현재배열의 전 배열값 arr[i-1] 이 같은지 비교한다.
현재 배열 이전 배열
arr[0] arr[0-1]
arr[1] arr[1-1]
arr[2] arr[2-1]
arr[3] arr[3-1]
arr[4] arr[4-1]
arr[5] arr[5-1]
.
.
arr[length -1] arr[(length -1) -1]
- 현재배열 값 arr[i]와 이전배열 값arr[i-1] 가 같을때 빈배열 answer에 현재값 arr[i]를 push 메서드로 넣는다.
function solution(arr) {
let answer = []
//배열을 하나씩 돌면서 배열의 현재값과 전 값이 같은지 비교.
for (let i = 0; i < arr.length; i++) {
if (arr[i] !== arr[i - 1]) {
answer.push(arr[i])
}
}
//현재 값과 전 값이 같으면 현재 값만 넣음.
return answer;
}
//[1, 1, 3, 3, 0, 1, 1]
- filter 메서드를 사용해 한개 배열안에 같은 값이 있는지 판단
arr.filter((ele,i ) => ele !== arr[i-1])
- 위 식을 통해 arr배열의 각 요소를 돌면서 arr[i-1]로 전 배열의 값과 현재값 ele가 같은지 판단하는 식이다
- ele가 arr[i-1]와 같지 않는 값만 모아 새로운 배열을 만든다
function solution1(arr) {
return arr.filter((ele, i) => ele !== arr[i - 1]) //ele arr배열의 각 요소 arr[i-1] = arr배열의 전 요소
}
- 약수의 개ㅇ수와 덧
약수의 개수와 덧셈
내가 쓴 풀이
function solution(left, right) {
let answer = 0
let count = 0
let count1 = []
for (let i = left; i <= right; i++) {
//left부터 right 까지 수의 약수를 구함
count = []
for (let j = 1; j <= i; j++) {
//약수의 개수를 구함
if (i % j === 0) {
count.push(j)
}
//약수의 개수가 홀수면 빼고 짝수면 더함.
}
count1.push(count)
}
for (let k = 0; k < count1.length; k++) {
if (count1[k].length % 2 === 0) {
answer += Math.max(...count1[k])
} else {
answer -= Math.max(...count1[k])
}
}
return answer;
}
- i의 약수를 구하는식 i를 j로 나눴을때 0을 떨어지는수 j가 i의 약수이다.
if (i % j === 0) {
count.push(j)
}
- i의 제곱근이 정수이면 약수의 갯수가 홀수인 식
if (Number.isInteger(Math.sqrt(i))) {
answer -= i;
} else {
answer += i;
}
약수의 합
내가 쓴 풀이
- 정수 n의 약수를 구하여 변수 answer에 하나씩 더하는 식이다
- 반복문을 사용하여 i가 0부터 시작하여 n까지 순회하는 식을 만들었다.
- i=0 부터 i <=12까지 순회함
- 조건문 if로 정수 n을 i로 나누었을때 0으로 떨어지는 수가 약수이기때문에 12 % (1~12) 가 0으로 떨어지는 정수 i 들만
answer = 0에 i를 더해준다.
function solution(n) {
let answer = 0
for (let i = 0; i <= n; i++) {
if (n % i === 0) {
answer += i
}
}
return answer;
}
//n =12
예산
내가 쓴 풀이
function solution(d, budget) { //배열= d [1, 3, 2, 5, 4] 숫자열= budget 9
let answer = 0;
d = d.sort((a, b) => a - b)
//d=[1, 3, 2, 5, 4] 의 총합 === 7 - budget === 9
for (let i = 0; i < d.length; i++) {
//배열들의 총합이 9보다 작은 배열들 조합의 갯수
budget = budget - d[i]
if (budget < 0) {
break;
}
answer++
}
return answer;
}
- 배열 d를 sort 메서드를 사용해 오름차순으로 정렬해준다
d = d.sort((a, b) => a - b) //[1,2,3,4,5]
- 반복문을 사용해 i가 0 부터 배열d의 length 까지 순회하게 한다.
- 조건문을 사용해 매개변수 budget에 budget의 값에서 배열d[i] 값을 뺀값들을 budget에 누적시킨다
- 누적시킨 budget값이 음수일때 조건문을 빠져나간다.
for (let i = 0; i < d.length; i++) {
//배열들의 총합이 9보다 작은 배열들 조합의 갯수
budget = budget - d[i]
if (budget < 0) {
break;
}
answer++
}
최대공약수와 최소공배수
내가 쓴 풀이
function solution(n, m) {
let answer = [];
let arrn1 = []
let arrn2 = []
for (let i = 0; i <= n; i++) {
if (n % i === 0) {
arrn1.push(i)
}
}
for (let j = 0; j <= m; j++) {
if (m % j === 0) {
arrn2.push(j)
}
}
let a = arrn1.filter(e => arrn2.includes(e))
answer.push((Math.max(...a)))
//n와 m의 n*m=최대공약수*최소공배수 입니다
answer.push(n * m / Math.max(...a))
//n*m 을 곱한 값
return answer;
}
- 정수 n의 약수를 구하는 식을 for문과 if문을 사용해 만들고 n의 약수일때 빈배열 arrn1에 i값을 push한다.
for (let i = 0; i <= n; i++) {
if (n % i === 0) {
arrn1.push(i)
}
}
- 정수 m의 약수를 구하는 식을 for문과 if문을 사용해 만들고 i가 m의 약수일때 빈배열 arrn2에 i값을 push한다.
for (let j = 0; j <= m; j++) {
if (m % j === 0) {
arrn2.push(j)
}
}
- 최소공배수 구하기: 새로운 변수 a에 filter 메서드를 사용해 배열arrn1담긴 값과 배열 arrn2에 담긴 값 중에 공통된 값을 새로운 배열로 가져오고, 전개연산자를 사용해 배열 arrn1와 arrn2에 공통된 값을 출력한 배열 a를 전개 연산자로 분해하고, Math.max함수를 사용해 가장큰 값을 answer에 push한다.
let a = arrn1.filter(e => arrn2.includes(e))
answer.push((Math.max(...a)))
- 최대공약수 구하는식 : 정수 n과 정수 m의 최대공약수를 구하려면 n과 m을 곱하고 곱한값을 최소공배수로 나눠주면
최대공약수를 구할 수 있다.
//n와 m의 n*m=최대공약수*최소공배수 입니다
answer.push(n * m / Math.max(...a))
k번째수
내가 쓴 풀이
function solution(array, commands) {
//commands[0][0] = 2 commands[0][1] = 5 commands[0][2] = 3
//commands[1][0] = 4 commands[1][1] = 4 commands[1][2] = 1
//commands[2][0] = 1 commands[1][1] = 7 commands[1][2] = 3
let answer = []
let arr = null
//array를 commands[0][0]번째부터commands[0][1]번째까지 자름 slice
for (let i = 0; i < commands.length; i++) {
arr = array.slice((commands[i][0]) - 1, commands[i][1])
arr.sort((a, b) => a - b)
answer.push((arr[commands[i][2] - 1]))
}
return answer;
}
//commands = [[2, 5, 3], [4, 4, 1], [1, 7, 3]]
// array = [1, 5, 2, 6, 3, 7, 4]
- 반복문을 사용해 i가 0부터 배열 commands의 length까지 순회하는 반복문을 만들고 빈배열 arr에 매개변수로 들어온
배열 array를 slice 메서드를 사용해 commands[i][0] -1 번째값부터 , commnads[i][i]번째 값까지 잘라내어 넣는다.
잘라낸 배열 arr을 sort()메서드를 사용해 오름차순으로 정렬한다.
빈배열 answer에 배열 arr의 commands[i][2] - 1인덱스에 해당하는 값을 answer의 마지막 값으로 넣는다.
for (let i = 0; i < commands.length; i++) {
arr = array.slice((commands[i][0]) - 1, commands[i][1])
//arr = [5,2,6,3]
arr.sort((a, b) => a - b)
//arr = [2,3,5,6]
answer.push((arr[commands[i][2] - 1])) // [2,3,5,6].[[2,5,3],[4,4,1],[1,7,3]] = 3
}
느낀점; 알고리즘 연습 문제를 반복해서 풀면서 for반복문에 대한 이해와 반복 메서드들에 대한 이해를 조금씩 해나가고 있다는 느낌이 들고 있다. filter , map , forEach, reduce같은 메서드들을 자주사용하면서 사용법을 좀 더 익히고, 정수n의 약수를 구하는 방법이나, 배열에서 최대값을 구하는 Math.max 같은 함수들의 사용법도 조금씩 알아가는것 같다는 느낌이들었다 중첩반복문이나 배열을 내림차순이나 오름차순으로 정렬하는 sort()메서드의 사용법도 조금씩 이해하고 있고, 중학생때 배웠던 최소공배수나 최대공약수를 자바스크립트로 구하는 공식도 이해하게 돼서 문제 푸는게 계속 재밌어지고 있다.
하지만 식이 조금이라도 복잡해지거나 중첩반복문이 등장했을때 if문을 어떻게 사용해야하는지 구체적인 구현력이 조금 떨어지는 것 같아서 계속해서 알고리즘 문제를 반복해서 연습해야겠다는 생각이들었다. 알고리즘 연습문제들을 전체적으로 이해하고 어떤방식으로 구현해야 하는지 까지는 대략적으로 머릿속에 그려지지만 구체적인 구현력이 아직까지 조금 떨어지는 것 같아서 계속해서 반복문이나 메서드들과 친해지고 반복해서 풀어보며 사용법을 익혀야겠다는 생각이 들었다.
'개발일지' 카테고리의 다른 글
개발일지 27일차 (0) | 2023.04.13 |
---|---|
VS Code 소스제어 10K 없애기 (0) | 2023.04.12 |
개발일지 25일차 (0) | 2023.04.11 |
개발일지 1주차 WIL (3) | 2023.04.09 |
개발일지 24일차 (0) | 2023.04.06 |