diff --git a/contains-duplicate/grapefruitgreentealoe.js b/contains-duplicate/grapefruitgreentealoe.js index 2bd26ce0a..7331c3e47 100644 --- a/contains-duplicate/grapefruitgreentealoe.js +++ b/contains-duplicate/grapefruitgreentealoe.js @@ -24,3 +24,23 @@ var containsDuplicate = function (nums) { } return false; }; + +//25.7.23 풀이시간 10분 +/** + * @param {number[]} nums + * @return {boolean} + */ +var containsDuplicate = function(nums) { + //두번 이상 나타나는게 있으면 바로 리턴하시오. + //이중 순회하게 되면 시간 초과할 예정. + //시간복잡도 중요. + //1. 저장하는 배열을 만들고, 그 배열에 값이 있으면 리턴 false. + //2.배열보다 Set을 사용한,삽입 및 조회 속도 최적화 활용하기. + const container = new Set(); + for(let i =0; ia-b); + for(let i = 0;i < nums.length;i++){ + let current = nums[i]; + let count = 1; + for(let j = i+1;j n^2. +공간복잡도: +nums는 초기화했고, +기타 변수들만 사용을 했다(maxCount,current,count)=> O(1) + +하지만 이문제는 O(n)의 시간복잡도를 가져가야한다. +그러려면 sort도 하지말아야하고, 2중for문을 쓰지도 말아야한다. +(생각해보니 내가 사용한 방법을 인덱스+1해서 해결해도 되긴한다. 그래도 정렬때문에 nlogn이 된다.) + +두번째 방법으로는,set을 사용해서 중복을 제거하는 방법이다. +*/ + /** * @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++; +var longestConsecutive = function(nums) { + if(nums.length == 0) return 0 + let maxCount = 1; + nums.sort((a,b)=>a-b); + nums = [...new Set(nums)]; + let count = 1; + for (let i = 0; i < nums.length - 1; i++) { + if (nums[i] + 1 === nums[i + 1]) { + count += 1; + } else if (nums[i] === nums[i + 1]) { + // 중복일 경우 아무것도 안 하고 넘어감 + continue; + } else { + maxCount = Math.max(maxCount, count); + count = 1; + } } - maxCount = Math.max(length, maxCount); - } - return maxCount; + maxCount = Math.max(maxCount, count); // 마지막에도 비교 필요 + + return maxCount }; +/*sort할때 시간복잡도가 nlog(n)인데 왜 통과했지.. 빅오 계산법이 최악의 경우를 계산한거라, 운좋게 통과한 것 같다. +좀 더 최적화 해보자 +*/ -//시간복잡도 O(n) + O(n) = O(n) /공간복잡도 O(n) +/** + * @param {number[]} nums + * @return {number} + */ +var longestConsecutive = function(nums) { + const numsSet = new Set(nums); + let maxCount = 0; + for(let num of numsSet){ + //중복된 계산 패스 + if(numsSet.has(num-1)) continue; + let length = 1; + while(numsSet.has(num+length)){ + length++ + } + maxCount = Math.max(maxCount,length) + } + return maxCount +}; -//생각할 지점. 양쪽으로 진행된다면, 시간복잡도 최적화 가능 +/* +set을 이용해서 중복을 제거 +set의 has메소드를 활용하여 조회 최적화 +while을 썼지만, for문의 첫번째 if문을 통해 실제 수행은 O(n)의 시간복잡도를 가짐. +이 외에도, set으로 만든 다음에 삭제해가면서(while) 순회가 아닌, 왼쪽 오른쪽값들을 연속적으로(while) 지우고, 연속이 끝나면 pop에서 나온 값의 left right를 조회해서 없으면 다시 최대값과 비교하는 방식이 있다. +근데 위의 코드에서 has로 조회하나, remove를 하려면 어차피 또 조회해야하니, +성능상의 차이는 크게 없는 것 같다. +*/ diff --git a/top-k-frequent-elements/grapefruitgreentealoe.js b/top-k-frequent-elements/grapefruitgreentealoe.js index 29981ee40..26464ade4 100644 --- a/top-k-frequent-elements/grapefruitgreentealoe.js +++ b/top-k-frequent-elements/grapefruitgreentealoe.js @@ -27,3 +27,31 @@ var topKFrequent = function (nums, k) { }; //O(n) + O(n log n) + O(n) + O(k) = O(n log n) + + +//7.22 소요시간 10분 +/** + * @param {number[]} nums + * @param {number} k + * @return {number[]} + */ +var topKFrequent = function(nums, k) { + //우선은, Map으로 만들어서 숫자 각각에 대한 개수를 구한다. + const numsMap = new Map(); + for(let num of nums){ + if(numsMap.has(num)){ + numsMap.set(num,numsMap.get(num)+1) + }else{ + numsMap.set(num,1) + } + } + //그런다음 Map에 대해서, 가장 큰 값을 가진 순으로 정렬을 한다. + const ret = [...numsMap].sort((a,b)=>b[1]-a[1]).slice(0,k).map(x=>x[0]); + return ret +}; + +// 이전 답과 비슷하지만, for문 처리에 대해서, 조금 풀어서 작성을 하게 된거같다. +// 시간복잡도와 공간복잡도는 위의 코드와 같다. + +// 시간 복잡도 : for문 - O(n) , sort O(nlogn) +// 공간 복잡도 : O(n) diff --git a/two-sum/grapefruitgreentealoe.js b/two-sum/grapefruitgreentealoe.js index cce88588a..91206909b 100644 --- a/two-sum/grapefruitgreentealoe.js +++ b/two-sum/grapefruitgreentealoe.js @@ -48,3 +48,53 @@ var twoSum3 = function (nums, target) { numMap.set(nums[i], i); // 공간 O(1) } }; + + +//25.7.24 +/** + * @param {number[]} nums + * @param {number} target + * @return {number[]} + */ +var twoSum = function(nums, target) { + //우선 nums배열에서 target보다 큰것은 삭제한다. => 이것 또한 시간복잡도가 든다. 하지말자 + //1. 투포인터 방식으로 접근한다. + for(let i=0;i