Skip to content
26 changes: 26 additions & 0 deletions contains-duplicate/grapefruitgreentealoe.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/**
* @param {number[]} nums
* @return {boolean}
*/

/**
* 문제설명: 2개 이상 반복되는 값이 있으면 true, 모두 반복되지 않으면 false.

제한사항
1 <= nums.length <= 10^5
-109 <= nums[i] <= 109
*/

var containsDuplicate = function (nums) {
const numberSet = new Set();
//시간 복잡도 O(n)
for (let i of nums) {
if (!numberSet.has(i)) {
//공간복잡도 O(n)
numberSet.add(i);
} else {
return true;
}
}
return false;
};
45 changes: 45 additions & 0 deletions house-robber/grapefruitgreentealoe.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
/**
* 도둑이 각 집에 돈의 양이 있는데, 근접한 집은 연결된 보안 시스템이 있다
* 두 근접 집이 같은 밤에 강도당하면 경찰에게 연락감
* 오늘 경찰에게 연락이 가지 않으면서 훔칠 수 있는 최대 돈 리턴
*/

/**
* 만약 dfs로 구한다면, 시간복잡도는 2^n이 된다
*/
/**
* @param {number[]} nums
* @return {number}
*/

//최대값 즉 최적의 해를 구하는 문제. dp를 활용해보자.
var rob = function (nums) {
//배열 크기가 늘어남에 따라, 작은 배열에 대한 결과를 활용하여 계산하는 아이디어.
const dp = new Array(nums.length + 1); //공간복잡도 O(n)
/**
dp[0] = 0; //하나도 없을떄
dp[1] = nums[0]; //집이 한곳일때
dp[2] = Math.max(dp[1], nums[1]); //집이 한곳일때의 dp값과, 현재 순번의 돈
dp[3] = Math.max(dp[2], dp[1] + nums[2]);// 더하지 않으면 이전 결과값, 더하려면 그 전의 결과값에 더하기
*/
for (let i = 2; i < dp.length; i++) {
//시간복잡도 O(n)
dp[i] = Math.max(dp[i - 1], dp[i - 2] + nums[i - 1]);
}
return dp[dp.length - 1];
};

var rob2 = function (nums) {
//배열에 저장하지 않고 변수에 바로 담는 방식
let prev = 0;
let curr = 0;
for (let num of nums) {
//prev는 이전의 curr값으로, curr값은 이전의 prev + num
let tempPrev = prev;
prev = curr;
curr = Math.max(num + tempPrev, curr);
}
return curr;
};
//공간복잡도를 O(1)로 개선

30 changes: 30 additions & 0 deletions longest-consecutive-sequence/grapefruitgreentealoe.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/**
* 정수 배열 nums
* 가장 많이 연속되는 요소의 길이 리턴.
* O(n) 시간안에 돌아가는 알고리즘 사용할것.
*/
/**
* @param {number[]} nums
* @return {number}
*/
var longestConsecutive = function (nums) {
const numSet = new Set(nums);
let maxCount = 0;
for (let i of numSet) {
//n 번 순회
// ++ 이전에 연속체크가 되었을 수 있으므로, 이전 숫자가 존재한다면 pass
if (numSet.has(i - 1)) continue; //이미 진행 된 연속체크의 경우 하지 않는다.
//연속이 되는지 확인해서 있으면 1추가.
let length = 0;
while (numSet.has(i + length)) {
//연속이 끊기는 순간 멈추는 반복문. 즉 for문 전체 통틀어 최대 n번 실행.
length++;
}
maxCount = Math.max(length, maxCount);
}
return maxCount;
};

//시간복잡도 O(n) + O(n) = O(n) /공간복잡도 O(n)

//생각할 지점. 양쪽으로 진행된다면, 시간복잡도 최적화 가능
29 changes: 29 additions & 0 deletions top-k-frequent-elements/grapefruitgreentealoe.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/**
* 정수 array nums , 정수 k가 있을때, 가장 빈도가 높은 숫자 k개 리턴. 순서상관 X
*/

/**
* @param {number[]} nums
* @param {number} k
* @return {number[]}
*/

//nums에 대해서 각 요소에 대해 중복되는 횟수를 구한다. 그리고 내림차순으로 k개 리턴한다.

var topKFrequent = function (nums, k) {
const numsFreqMap = new Map(); // O(1)

// O(n) 시간 / O(n) 공간
for (let num of nums) {
numsFreqMap.set(num, (numsFreqMap.get(num) ?? 0) + 1);
}

const arrFromFreqMap = [...numsFreqMap]; // O(n) 시간 / O(n) 공간
arrFromFreqMap.sort((a, b) => b[1] - a[1]); // O(n log n) 시간

return arrFromFreqMap
.map((x) => x[0]) // O(n) 시간 / O(n) 공간
.slice(0, k); // O(k) 시간 / O(k) 공간
};

//O(n) + O(n log n) + O(n) + O(k) = O(n log n)
50 changes: 50 additions & 0 deletions two-sum/grapefruitgreentealoe.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
/**
* 정수 숫자 배열과 정수 target
* 숫자 합이 target과 같은 두 숫자의 index를 리턴.
* 같은 요소 두번 X. 답은 항상 1개
* 정렬필요 X
*/

/**
* @param {number[]} nums
* @param {number} target
* @return {number[]}
*/
var twoSum = function (nums, target) {
//순회. target에서 nums[i]를 뺀 요소를 찾기.
//2중포문. 시간복잡도 O(1)~O(N^2)
for (let i = 0; i < nums.length; i++) {
const subNum = target - nums[i]; // 공간 O(1)
for (let j = i + 1; j < nums.length; j++) {
if (nums[j] == subNum) {
return [i, j];
Comment on lines +13 to +20
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

역시 시작은 다 이렇게..ㅋㅋ (저만 그런게 아니였네요)

}
}
}
};

var twoSum2 = function (nums, target) {
for (let i = 0; i < nums.length; i++) {
//시간복잡도 O(N)
const subNum = target - nums[i]; // 공간 O(1)
if (nums.includes(subNum) && nums.indexOf(subNum) !== i) {
//시간복잡도 O(N). 2중포문과 같은 효과.
return [i, nums.indexOf(subNum)];
}
}
};

//Better answer
var twoSum3 = function (nums, target) {
// map으로 관리하여 indexing 최적화
const numMap = new Map();
for (let i = 0; i < nums.length; i++) {
//시간복잡도 O(N)
const subNum = target - nums[i];
if (numMap.has(subNum)) {
//시간복잡도 O(1)
return [i, numMap.get(subNum)];
}
numMap.set(nums[i], i); // 공간 O(1)
}
};