Lsiron
코딩테스트 12(slice, sort, map) 본문
문제 1. 가장 가까운 같은 글자
문자열 s가 주어졌을 때, s의 각 위치마다 자신보다 앞에 나왔으면서, 자신과 가장 가까운 곳에 있는 같은 글자가 어디 있는지 알고 싶습니다.
예를 들어, s="banana"라고 할 때, 각 글자들을 왼쪽부터 오른쪽으로 읽어 나가면서 다음과 같이 진행할 수 있습니다.
b는 처음 나왔기 때문에 자신의 앞에 같은 글자가 없습니다. 이는 -1로 표현합니다.
a는 처음 나왔기 때문에 자신의 앞에 같은 글자가 없습니다. 이는 -1로 표현합니다.
n은 처음 나왔기 때문에 자신의 앞에 같은 글자가 없습니다. 이는 -1로 표현합니다.
a는 자신보다 두 칸 앞에 a가 있습니다. 이는 2로 표현합니다.
n도 자신보다 두 칸 앞에 n이 있습니다. 이는 2로 표현합니다.
a는 자신보다 두 칸, 네 칸 앞에 a가 있습니다. 이 중 가까운 것은 두 칸 앞이고, 이는 2로 표현합니다.
따라서 최종 결과물은 [-1, -1, -1, 2, 2, 2]가 됩니다.
문자열 s이 주어질 때, 위와 같이 정의된 연산을 수행하는 함수 solution을 완성해주세요.
풀이=해답.
function solution(s) {
let arr = [];
for(let i = 0; i < s.length; i += 1) {
let found = false;
for(let j = i - 1; j >= 0; j -= 1) {
if(s[i] === s[j]) {
arr.push(i - j);
found = true;
break;
}
}
if (!found) {
arr.push(-1);
}
}
return arr;
}
배열을 처음부터 끝까지 순회하면서 가장 가까운 글자를 찾는 문제이니, 부모 반복문 해당 요소의 인덱스부터 0까지 역순으로 순회하는 자식 반복문을 하나 더 추가했다. ( 정방향으로 하면 같은 문자를 찾아도 그 뒤에 또 같은 문자가 있는 경우에 답이 없다. )
가장 가깝고 같은 문자를 찾은 뒤 반복문으로 거리를 계산하도록 하고 선언 해 놓았던 found를 true로 변경 한 뒤에 반복문을 멈추도록 했다.
만약 같은 문자를 찾지 못할경우 선언해놓았던 found가 false값을 유지하도록 하여 if 조건문으로 -1을 push 하도록 했다. (found는 오로지 -1을 넣기위해 선언한 것)
// 이래저래 참 많은 경우의 수를 생각하도록 한 문제였다. 당연히 반복문에 종속반복문을 넣어야 한다고 생각했고 가장 가까운 문자이니 종속 반복문은 역순으로 순회해야 한다고 생각했다. 허나 -1을 어떻게 넣어야 할지 고민 하던중 if조건문으로 시작해서 found 변수로 해당 경우의 수를 해결 할 수 있었다. 전에 풀었던 문제중에 반복문은 사용하지 않지만 변수를 선언해서 경우의 수를 해결하는 문제가 있었던 것으로 기억한다.
문제 2. K번째 수
배열 array의 i번째 숫자부터 j번째 숫자까지 자르고 정렬했을 때, k번째에 있는 수를 구하려 합니다.
예를 들어 array가 [1, 5, 2, 6, 3, 7, 4], i = 2, j = 5, k = 3이라면
array의 2번째부터 5번째까지 자르면 [5, 2, 6, 3]입니다.
1에서 나온 배열을 정렬하면 [2, 3, 5, 6]입니다.
2에서 나온 배열의 3번째 숫자는 5입니다.
배열 array, [i, j, k]를 원소로 가진 2차원 배열 commands가 매개변수로 주어질 때, commands의 모든 원소에 대해 앞서 설명한 연산을 적용했을 때 나온 결과를 배열에 담아 return 하도록 solution 함수를 작성해주세요.
제한사항
array의 길이는 1 이상 100 이하입니다.
array의 각 원소는 1 이상 100 이하입니다.
commands의 길이는 1 이상 50 이하입니다.
commands의 각 원소는 길이가 3입니다.
array commands return
[1, 5, 2, 6, 3, 7, 4] [[2, 5, 3], [4, 4, 1], [1, 7, 3]] [5, 6, 3]
[1, 5, 2, 6, 3, 7, 4]를 2번째부터 5번째까지 자른 후 정렬합니다. [2, 3, 5, 6]의 세 번째 숫자는 5입니다.
[1, 5, 2, 6, 3, 7, 4]를 4번째부터 4번째까지 자른 후 정렬합니다. [6]의 첫 번째 숫자는 6입니다.
[1, 5, 2, 6, 3, 7, 4]를 1번째부터 7번째까지 자릅니다. [1, 2, 3, 4, 5, 6, 7]의 세 번째 숫자는 3입니다.
풀이=해답.
function solution(array, commands) {
arr = [];
for ( let i = 0 ; i < commands.length ; i += 1){
arr.push(array.slice(commands[i][0]-1,commands[i][1])
.sort((a,b) => a - b)[commands[i][2]-1])
}
return arr
}
빈배열을 하나 선언 해 놓고 array를 commands n번째 요소의 0번 요소부터 1번 요소까지 자를려면 slice 특성상 0번요소 -1을 해주어야한다. 이 후, sort로 오름차순으로 정렬한 뒤, commands n번째 요소의 2번 요소 - 1 으로 추출해 주면 된다. slice는 불변성을 유지시켜 주기 때문에, sort로 정렬한 뒤에 다시 commands 내부 요소를 사용해도된다.
// JavaScript의 `.sort()` 함수는 기본적으로 배열의 요소를 문자열로 변환한 후 유니코드 순서로 정렬을 수행한다.
따라서, 숫자 배열을 의도한 대로 정렬하려면 `.sort()` 함수에 비교 함수를 인자로 제공해야 한다.
예를 들어, [2, 10, 3]을 정렬하려고 할 때, 단순히 `.sort()`를 호출하면 ["10", "2", "3"]로 정렬이 되어 원치 않는 결과를 얻게 된다. 이를 해결하기 위해 `.sort((a, b) => a - b)`와 같이 비교 함수를 사용하면 [2, 3, 10]으로 숫자의 크기에 맞게 올바르게 정렬할 수 있다.
처음에 그냥 .sort() 로 했을 때 한 문제가 오답처리 되어 정석대로 인자를 넣어주니 되었다. 이유를 찾아보니 위와 같은 이유 때문이었다.
반복문이 아닌 commands에 map 함수를 사용해서 푸는 경우도 많았다. 다음엔 반복문 보다 map 함수를 사용해서 풀어봐야겠다. 차이는 for 반복문과 크게 다를 것은 없지만 코드가 단축된다는 장점이 있다.
function solution(array, commands) {
return commands.map(v => {
return array.slice(v[0] - 1, v[1]).sort((a, b) => a - b)[v[2]-1];
});
}
'코딩테스트 > Java Script' 카테고리의 다른 글
코딩테스트 11(Math.max, Math.min, 아스키코드, s.charCodeAt, string.fromCharCode) (0) | 2024.07.02 |
---|---|
코딩테스트 10(map, join) (0) | 2024.07.01 |
코딩테스트 9(sort, break, slice) (0) | 2024.06.30 |
코딩테스트 8(filter) (0) | 2024.06.07 |
코딩테스트 7(배열 초기화, \n을 포함한 표현식 삽입, 유클리드 호제법-최대공약수, 최소공배수) (0) | 2024.06.05 |