코드카타는 2인1조를 이루어 알고리즘을 푸는 역량을 기르는 시간.
twoSum함수에 숫자배열과 '특정 수'를 인자로 넘기면, 더해서 '특정 수'가 나오는 index를 배열에 담아 return해 주세요.
nums: 숫자 배열 target: 두 수를 더해서 나올 수 있는 합계 return: 두 수의 index를 가진 숫자 배열
예) nums = [4, 9, 11, 14], target = 13 👉 return은 [0, 1]이 된다
가정
target으로 보내는 합계의 조합은 배열 전체 중에 2개 밖에 없다.
틀린 풀이:
const twoSum = (nums, target) => {
// 아래 코드를 작성해주세요.
for(let i in nums){
for(let j in nums){
if(nums[i] + nums[j] === target){
return [Number(i),Number(j)];
}
}
}
}
console.log(twoSum([4, 9, 11, 14], 15)); // [0,1]
정리
for...in 구문에서 i는 string타입이고
for문에서 i는 number타입이다
but, 중복이 허용되지 않으면 문제가 된다!
중복 없는 덧셈의 경우의 수는 다음과 같다
i | j | [i,j] |
---|---|---|
0 | 1,2,3 | [0,1], [0,2], [0,3] |
1 | 2,3 | [1,2], [1,3] |
2 | 3 | [2,3] |
...에서 다음의 규칙을 찾을 수 있다
const twoSum = (nums, target) => {
// 아래 코드를 작성해주세요.
for(let i=0; i<nums.length; i++){
for(let j=i+1; j<nums.length; j++){
if(nums[i] + nums[j] === target){
return [i,j];
}
}
}
}
reverse 함수에 정수인 숫자를 인자로 받습니다. 그 숫자를 뒤집어서 return해주세요.
x: 숫자 return: 뒤집어진 숫자를 반환!
예들 들어, x: 1234 return: 4321
x: -1234 return: -4321
x: 1230 return: 321
const reverse = x => {
// 여기에 코드를 작성해주세요.
let result="";
let array = x.toString().split("");
if(array[0] === "-"){ // 음수일 때
result = "-";
for(let i=array.length-1; i>0; i--){
result += array[i];
}
return Number(result);
}else{ // 정수일 때
for(let i=array.length-1; i>=0; i--){
result += array[i];
}
return Number(result);
}
}
console.log(reverse(1234));
console.log(reverse(-1234));
다른 풀이1
다른 풀이2
String 형인 str 인자에서 중복되지 않은 알파벳으로 이루어진 제일 긴 단어의 길이를 반환해주세요.
str: 텍스트 return: 중복되지 않은 알파벳 길이 (숫자 반환)예를 들어,
str = "abcabcabc" return 은 3 => 'abc' 가 제일 길기 때문
str = "aaaaa" return 은 1 => 'a' 가 제일 길기 때문
str = "sttrg" return 은 3 => 'trg' 가 제일 길기 때문
방법1.
1. 입력받은 문자열str을 알파벳 단위로 쪼개서 배열v1으로 만든다
2. 배열v1을 중복 요소 없는 배열v2로 만든다
3. 배열v2의 요소로 만들 수 있는 모든 문자열의 경우의 수를 배열v3로 구한다
4. 배열v3를 뒤집은 배열v4를 구한다
👉 길이가 긴 요소부터 짧은 요소 순으로 반복문을 돌릴 것이므로
5. 배열v4의 요소가 str에 존재하는지 반복문을 돌린다
6. 있으면 그 요소의 길이를 반환한다(끝)
문제점: 중복 요소 없는 배열v2의 길이가 9이상이면 max 콜스택 초과 에러가 발생한다
// 배열에서 순서가 있는 num 개수만큼 경우의 수 뽑기
const getPermutations = (arr, num) => {
const results = [];
if (num === 1) return arr.map(v => v);
arr.forEach((fixed, index, origin) => {
const rest = [...origin.slice(0, index), ...origin.slice(index + 1)];
const permutations = getPermutations(rest, num - 1);
const attached = permutations.map(v => [fixed, ...v]);
results.push(...attached);
});
return results;
}
// 배열에서 순서가 있는 모든 경우의 수 뽑기
const getAllPermutations = (arr) => {
let results = [];
arr.forEach((value, index, origin) => {
results.push(...getPermutations(origin, index + 1));
});
return results;
}
// 유닛테스트할 함수 본체
const getLengthOfStr = str => {
// 입력된 str값이 빈문자열이 0을 반환
if(str === ""){
return 0;
}else{
const v1 = str.split(""); // 쪼갠다
const v2 = [...new Set(v1)]; // 최소인자만 뽑는다
let v3 = getAllPermutations(v2); // 모든 경우의 수를 구한다(배열로)
// 배열로 반환된 내부 요소를 string으로 만들기
for(let i=v2.length; i<v3.length; i++){
let result="";
for(let j=0; j<v3[i].length; j++){
result += v3[i][j];
}
v3[i] = result;
}
// 그걸 거꾸로 뒤집기: 길이가 큰 문자열부터 비교할 것이다
const v4 = v3.reverse();
// 입력받은 str에 v4의 요소가 있으면 v4의 길이를 반환한다
for(let i=0; i<v4.length; i++){
if(str.indexOf(v4[i])!==-1){
return v4[i].length;
}
}
}
}
console.log(getLengthOfStr("abcdefghi"))
// 중복없는글자의 길이가 9이상일 때 콜스택초과 에러: 7~9번 테스트 불합격
방법2.
설명은.. 나중에 알아보자..
숫자인 num을 인자로 넘겨주면, 뒤집은 모양이 num과 똑같은지 여부를 반환해주세요.
num: 숫자 return: true or false (뒤집은 모양이 num와 똑같은지 여부)예를 들어, num = 123 return false => 뒤집은 모양이 321 이기 때문
num = 1221 return true => 뒤집은 모양이 1221 이기 때문
num = -121 return false => 뒤집은 모양이 121- 이기 때문
num = 10 return false => 뒤집은 모양이 01 이기 때문const sameReverse = num => { }
i
와 맨뒤length-1
을 비교한다(반복 i++)2
👉 i<2
까지2.5
👉 i<2.5
까지const sameReverse = num => {
let str = String(num);
let arr = str.split("");
for (let i =0; i<str.length/2; i++){
if(arr[i] !== arr[str.length-1-i]){
return false; }
}
return true;
}
console.log(sameReverse(10801));
다른 풀이1 <오주형 님>
1. 쪼개서 배열로 만들고 = a
2. 역순으로 재배치하고 = b
3. for문으로 a와 b의 요소를 서로 비교해서
같으면 true, 다르면 false
const sameReverse = num => {
let a = String(num).split("");
let b = String(num).split("").reverse();
for(let i = 0; i < a.length; i++) {
if (a[i] == b[i]) {
return true;
} else {
return false;
}
}
}
다른 풀이2 <박지영-김호준 님>
1. num을 문자형태로 변환(String())
2. 배열에 쪼개서 할당(스프레드 연산자)
3. 역순으로 변환
4. 합치기
5. 4.를 기존 num과 비교(숫자와 문자를 비교하는 것이므로 ==
사용)
6. 삼항연산자로 같으면 true 다르면 false 반환
const sameReverse = num => { return ([...String(num)].reverse().join("")) == num ? true : false;}
strs은 단어가 담긴 배열입니다. 공통된 시작 단어(prefix)를 반환해주세요.
예를 들어 strs = ['start', 'stair', 'step'] return은 'st'
strs = ['start', 'wework', 'today'] return은 ''
예를 들어
strs = ['stccccccc', 'stb', 'staaaa'] 라는 배열이 입력된다면
가장 짧은 문자열인 'stb'의 길이
만큼만 다른 요소와도 비교해주면 된다
각 요소를 slice(0,길이
) 해서 새로운 배열arrNew을 만든다
=> arrNew = ['stc', 'stb', 'sta']
새 배열arrNew의 요소가 모두 동일한가?
즉, 새 배열arrNew 중복값이 없는 배열result 로 만들었을 때
=> result = ['stc', 'stb', 'sta']
result의 길이가 1인가? No
각 요소를 slice(0,길이-1
)해서 배열arrNew을 다시 만든다
=> arrNew = ['st', 'st', 'st']
중복값 없는 배열 result = ['st']
result의 길이가 1인가? YES
result[0]의 값을 반환한다
마지막 1글자끼리 비교해도 result의 길이가 1이 아니면 반복문을 종료하고 빈문자열("")을 반환한다
const getPrefix = strs => {
let array = [];
for(let i=0; i<strs.length; i++){
array.push(strs[i].length);
}
const minLen = array.sort()[0];
for(let i = minLen; i>0; i--){
let arrNew = strs.map(el => el.split("").slice(0, i).join(""));
let result = [...new Set(arrNew)];
if(result.length === 1){
return result[0];
}
}
return "";
}
Today I Learn
substring(기준, n)을 쓰면 문자열을 기준위치부터 n위치 전까지를 반환할 수 있다! slice(기준, n)만 알았던 나는 string을 배열로 만들어야 했기에 split("")와 join("") 메소드를 쓰는 번거로운 작업을 해야 했다.