Skip to content

[grapefruitgreentealoe] WEEK 01 solutions #1130

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 10 commits into from
Apr 6, 2025
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)
}
};