일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- 모던 자바스크립트 Deep Dive TIL
- 프로그래머스 데브코스
- 리팩토링 회고
- useEffect return
- 투포인터알고리즘 js
- 모던 자바스크립트 Deep Dive
- 프로그래머스 K_Digital Training 프론트엔드
- 머쓱이
- Frontend Roadmap
- 우테캠 회고록
- 개발자 특강
- useRef 지역 변수
- KDT 프로그래머스 데브코스 프론트엔드
- Vue3 Router
- 모던 자바스크립트 TIL
- KDT 프로그래머스
- 백준 js
- react 프로젝트 리팩토링
- frontend roadmap study
- react customHook 예시
- 백준 node.js
- 프로그래머스 데브코스 프론트엔드
- K_Digital Training
- 프로그래머스 K_Digital Training
- 모던 자바스크립트 딥다이브
- 모던 javascript Deep Dive
- TypeScript 문법 소개
- 프로그래머스 데브코스 프론트엔드 TIL
- 인프런 자바스크립트 알고리즘 문제풀이
- Vue3
- Today
- Total
프론트엔드 개발자의 기록 공간
[프로그래머스 JavaScript] 키패드 누르기 본문
프로그래머스 Level1 키패드 누르기 -> 2020 카카오 인턴십 문제
문제 설명 : 주어진 입력 numbers에 따라 왼쪽 손가락으로 터치할 것인가 오른쪽 손가락으로 터치할 것인가
선택하면 되는 문제입니다. 조건문은 크게 4가지 경우로 나뉩니다.
1. 1,4,7의 경우 왼쪽 손가락으로만 이용.
2. 3,6,9의 경우 오른쪽 손가락으로만 이용
3. 가운데일 경우 왼쪽, 오른쪽 손가락에서 가장 가까운 손가락 이용
3-1. 왼쪽 오른쪽이 같은 거리라면 hand로 주어지는 손가락 이용
첫번째 풀이
function solution(numbers, hand) {
var answer = "";
//초기 왼쪽 손가락 위치 (3,0)
let Li = 3;
let Lj = 0;
//초기 오른쪽 손가락 위치 (3,2)
let Ri = 3;
let Rj = 2;
//키패드 위치 정보 * #은 10 12로 임의로 대체
let list = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9],
[10, 0, 12],
];
//입력 numbers만큼 반복
for (let k = 0; k < numbers.length; k++) {
//키패드 2차원 길이만큼 반복
for (let i = 0; i < list.length; i++) {
for (let j = 0; j < list[i].length; j++) {
//입력값과 키패드 위치값이 일치할때
if (numbers[k] === list[i][j]) {
//이차원 배열 j값이 0이라면 왼쪽 손가락으로만 사용
if (j === 0) {
Li = i;
Lj = j;
answer += "L";
//이차원 배열 j값이 2이라면 오른쪽 손가락으로만 사용
} else if (j === 2) {
Ri = i;
Rj = j;
answer += "R";
}
//가운데 2,5,8,0일 경우
else {
//점과 점사이 구하는 공식 이용
//왼쪽 손가락 위치와 현재 i,j의 떨어진 거리 계산(절대값 이용)
let tmpL = Math.abs(i - Li) + Math.abs(j - Lj);
//오른쪽 손가락 위치와 현자 i,j의 떨어진 거리 계산(절대값 이용)
let tmpR = Math.abs(i - Ri) + Math.abs(j - Rj);
//떨어진 거리가 더 가까운 경우를 판별해서
//해당 손가락으로 사용
if (tmpL > tmpR) {
Ri = i;
Rj = j;
answer += "R";
} else if (tmpL < tmpR) {
Li = i;
Lj = j;
answer += "L";
//떨어진 거리가 왼쪽 오른쪽 같은 경우
} else if (tmpL === tmpR) {
//왼손잡이라면 왼쪽 이용
if (hand === "left") {
Li = i;
Lj = j;
answer += "L";
//오른손잡이일 경우
} else {
Ri = i;
Rj = j;
answer += "R";
}
}
}
}
}
}
}
return answer;
}
코드 설명 : 그래프 좌표값 구하는 방식을 이용해서 풉니다. (Math.abs() 절대값 메소드 사용)
처음에 list배열에 키패드 정보, 왼쪽 손가락 위치, 오른쪽 손가락 위치를 세팅해줍니다.
그 후, 입력으로 주어진 배열 numbers를 반복하면서 list에 해당하는 값을 찾기위해 이중 for문을 탐색해줍니다.
number값과 list에 해당하는 값이 일치하다면 위에 작성한 1,2,3 번째의 조건에 따라 분류해줍니다.
3번째 조건일 경우 가장 가까운 손가락위치를 구하기 위해 마지막에 사용한 왼쪽, 오른쪽 손가락의 좌표값과 현재 i,j의 값을 절대값을 이용하여 빼줍니다. 그 후 위치가 가까운 손가락으로 세팅해줍니다.
왼쪽, 오른쪽이 같다면 hand로 입력해준 손가락을 이용합니다.
*초기에 이렇게 작성하여 해결했습니다. 하지만 코드를 보면 가독성도 떨어지고 삼중 for문으로 시간복잡도가 O(n^3)이 되어 비효율적인 코드입니다.
다른 사람의 풀이를 보고 수정한 두번째 풀이 방법을 소개하겠습니다.
function solution(numbers, hand) {
var answer = "";
//객체 배열 이용
//키패드 위치에 따라 좌표 정보를 세팅
let list = {
1: [0, 0],
2: [0, 1],
3: [0, 2],
4: [1, 0],
5: [1, 1],
6: [1, 2],
7: [2, 0],
8: [2, 1],
9: [2, 2],
"*": [3, 0],
0: [3, 1],
"#": [3, 2],
};
//초기 손가락 위치
let left = list["*"];
let right = list["#"];
//입력 numbers만큼 반복
for (let x of numbers) {
let [i, j] = list[x]; //입력 숫자위치 i,j에 저장
//j값이 0이라면 왼쪽 손가락으로만 사용
if (j === 0) {
answer += "L";
left = list[x];
}
//j값이 2이라면 오른쪽 손가락으로만 사용
else if (j === 2) {
answer += "R";
right = list[x];
}
//가운데일 경우
else {
//왼쪽 손가락 위치와 현재 i,j의 떨어진 거리 계산(절대값 이용)
let tmpL = Math.abs(i - left[0]) + Math.abs(j - left[1]);
//오른쪽 손가락 위치와 현자 i,j의 떨어진 거리 계산(절대값 이용)
let tmpR = Math.abs(i - right[0]) + Math.abs(j - right[1]);
//떨어진 거리가 더 가까운 경우를 판별해서
//해당 손가락으로 사용
if (tmpL > tmpR) {
right = list[x];
answer += "R";
} else if (tmpL < tmpR) {
left = list[x];
answer += "L";
//떨어진 거리가 왼쪽 오른쪽 같은 경우
} else if (tmpL === tmpR) {
//왼손잡이라면 왼쪽 이용
if (hand === "left") {
left = list[x];
answer += "L";
//오른손잡이일 경우
} else {
right = list[x];
answer += "R";
}
}
}
}
return answer;
}
코드 설명 : 객체 배열을 이용하여 키패드 정보를 입력해줍니다. 그 후 numbers배열을 반복하면서 해당 키패드의 위치정보를 받아와서 1,2,3,3-1 조건을 해결해주면됩니다.
첫번째 풀이와 달라진 것은 키패드 정보를 이차원 배열로 했냐 객체 배열을 이용했냐 차이입니다.
나머지 알고리즘은 동일합니다.
하지만 시간복잡도는 O(n^3)에서 O(n)으로 줄어 확실히 효율적인 코드가 되었습니다.
* 문제 유형에 따른 알고리즘 선택이 중요하다는 것을 알 수 있었던 문제입니다. 또한 항상 정답만 맞출 것이 아니라 다른 사람의 코드를 보면서 리팩토링하는 습관이 중요합니다.
'알고리즘_JS > 프로그래머스_Level1' 카테고리의 다른 글
[프로그래머스 JavaScript] 폰켓몬 (0) | 2021.06.07 |
---|---|
[프로그래머스 JavaScript] 크레인 인형뽑기 게임 (0) | 2021.06.06 |
[프로그래머스 JavaScript] 체육복 (0) | 2021.05.24 |
[프로그래머스 JavaScript] 모의고사 (0) | 2021.05.22 |
[프로그래머스 JavaScript] K번째수 (0) | 2021.05.22 |