-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
w1-Merge pull request #13 from southppp22/main
- Loading branch information
Showing
14 changed files
with
752 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
### 빈도 카운터 패턴 | ||
|
||
- 두 개의 배열을 입력받아, 첫 번째 배열의 모든 요소를 제곱한 값이 두 번째 배열에 정확히 존재하는지 확인합니다. | ||
- 결과는 boolean으로 반환합니다. | ||
|
||
### 수도코드 | ||
|
||
- 빈도수를 담을 카운터 객체 두개를 만든다. | ||
- 배열을 순회하면서 카운터에 빈도수를 기록한다. | ||
- 만약 값이 이미 존재 한다면 1을 증가 시킨다. | ||
- 만약 값이 존재 하지 않는다면 1로 초기화 한다. | ||
- 카운터1을 순회하면서 카운터1의 제곱값과 카운터2의 값을 비교한다. | ||
- 존재하지 않으면 false | ||
- 빈도수가 같지 않다면 false | ||
|
||
```javascript | ||
//O(n) | ||
function same(arr1, arr2) { | ||
if (arr1.length != arr2.length) return false; | ||
|
||
let counter1 = new Map(); | ||
let counter2 = new Map(); | ||
|
||
//O(n) | ||
for (let val of arr1) { | ||
counter1.set(val, (counter1.get(val) || 0) + 1); | ||
} | ||
|
||
//O(n) | ||
for (let val of arr2) { | ||
counter2.set(val, (counter2.get(val) || 0) + 1); | ||
} | ||
|
||
//O(n) | ||
for (let [val1, f1] of counter1) { | ||
let f2 = counter2.get(val1 ** 2); | ||
|
||
if (!f2) { | ||
return false; | ||
} | ||
|
||
if (f1 != f2) { | ||
return false; | ||
} | ||
} | ||
|
||
return true; | ||
} | ||
``` | ||
|
||
### 구현하면서 놓친 부분 | ||
|
||
- 배열의 길이를 비교하는 부분을 빠뜨려서 두번째 배열의 길이가 긴 경우 예외적으로 통과하는 케이스가 생겼다. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
### 애너그램 | ||
|
||
- 두 개의 문자열을 입력받아, 첫 번째 문자열의 모든 요소가 두 번째 문자열에 정확히 존재하는지 확인합니다. | ||
- 결과는 boolean으로 반환합니다. | ||
|
||
```javascript | ||
//O(n) | ||
function validAnagram(str1, str2) { | ||
let counter1 = new Map(); | ||
let counter2 = new Map(); | ||
|
||
//O(n) | ||
for (let char of str1) { | ||
counter1.set(char, (counter1.get(char) || 0) + 1); | ||
} | ||
|
||
//O(n) | ||
for (let char of str2) { | ||
counter2.set(char, (counter2.get(char) || 0) + 1); | ||
} | ||
|
||
//O(n) | ||
for (let [key, value] of counter1) { | ||
const count2 = counter2.get(key); | ||
|
||
if (!count2) { | ||
return false; | ||
} | ||
|
||
if (value != count2) { | ||
return false; | ||
} | ||
} | ||
|
||
return true; | ||
} | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
### 다중 포인터 패턴 | ||
|
||
- 오름차순으로 정렬된 정수 배열을 입력받아 합이 0이 되는 첫번째 쌍을 찾는다. | ||
- 값의 쌍을 배열로 리턴한다. 만약 0이 되는 쌍이 없다면 undefined를 리턴한다. | ||
|
||
### 수도코드 | ||
|
||
- 포인터의 인덱스를 할 변수 start, end를 선언한다. | ||
- start는 0, end는 배열의 마지막 인덱스로 값을 할당한다. | ||
- start가 end보다 값이 작다면 | ||
- 배열의 start 인덱스의 값과 end 인덱스의 값을 비교한다. | ||
- 만약 값이 같다면 결과값을 리턴한다. | ||
- 만약 값이 같지 않고 합이 0보다 크다면 end를 1 감소 시킨다. | ||
- 만약 값이 같지 않고 합이 0보다 작다면 start를 1 증가 시킨다. | ||
|
||
```javascript | ||
//O(n) | ||
function sumZero(arr) { | ||
let start = 0; | ||
let end = arr.length - 1; | ||
|
||
//O(n) | ||
while (start < end) { | ||
const sum = arr[start] + arr[end]; | ||
|
||
if (sum == 0) { | ||
return [arr[start], arr[end]]; | ||
} else { | ||
if (sum > 0) { | ||
end--; | ||
} else { | ||
start++; | ||
} | ||
} | ||
} | ||
} | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
### 고유값 세기 | ||
|
||
- 정렬된 정수의 배열을 입력 받아 배열의 고유한 값이 몇 개 있는지 리턴합니다. | ||
- 입력 값엔 음수도 존재합니다. | ||
|
||
### 수도 코드 | ||
|
||
- 기준점이 될 포인터(p1)와 현재 위치를 가르키는 포인터(p2) 변수를 생성한다. | ||
- 만약 배열의 길이가 2보다 작다면 배열 길이를 리턴한다. | ||
- 초기 결과값은 1로 설정한다. | ||
- p2가 배열의 길이와 같을때까지 | ||
- p1과 p2의 값을 비교한다. | ||
- 만약 값이 같다면 p2를 1 증가 시킨다. | ||
- 만약 값이 같지 않다면 | ||
- p1에 p2값을 대입한다. | ||
- 결과값을 1 증가 시킨다. | ||
|
||
### 예시 | ||
|
||
- countUniqueValues([1,1,1,1,1,2]) // 2 | ||
- countUniqueValues([1,2,3,4]) // 4 | ||
- countUniqueValues([1,2,3,4,4,4,4,7,7,7,12,12,12,13]) // 7 | ||
- countUniqueValues([]) // 0 | ||
|
||
```javascript | ||
function countUniqueValues(arr) { | ||
if (arr.length < 2) { | ||
return arr.length; | ||
} | ||
|
||
let result = 1; | ||
let p1 = 0; | ||
let p2 = 0; | ||
|
||
while (p2 < arr.length) { | ||
if (arr[p1] == arr[p2]) { | ||
p2++; | ||
} else { | ||
p1 = p2; | ||
result++; | ||
} | ||
} | ||
|
||
return result; | ||
} | ||
``` | ||
|
||
### 강의의 해결책 | ||
|
||
- 포인터 두개를 사용해서 문제를 해결한다. | ||
- i는 기준점, j는 값을 비교할 대상이 된다. | ||
- 배열을 순회하면서 i와 j를 비교하여 값이 다르면 | ||
- i를 1 증가 시킨다. | ||
- i의 위치에 j의 값을 대입한다. | ||
- 따라서 0번째 인덱스부터 i까지는 고유한 값의 배열이 생성된다. | ||
- i와 j를 비교해서 값이 다르면 | ||
- j를 1 증가 시킨다. | ||
- 0-index를 사용함으로 i + 1을 결과값으로 리턴한다. | ||
|
||
```javascript | ||
//O(n) | ||
function countUniqueValues(arr) { | ||
let i = 0; | ||
|
||
//O(n) | ||
for (let j = 1; j < arr.length - 1; j++) { | ||
if (arr[i] != arr[j]) { | ||
i++; | ||
arr[i] = arr[j]; | ||
} | ||
} | ||
|
||
return i + 1; | ||
} | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
### 슬라이딩 윈도우 패턴 | ||
|
||
- 기존 값을 재활용해 연속된 하위 집합을 빠르게 계산하는 효율적인 패턴. | ||
- 만약 하위 집합의 합을 구하는 문제가 있다면 | ||
- 기존 방식은 모든 하위 집합의 합을 계산하므로 O(n^2)의 시간복잡도가 발생. | ||
- 해당 패턴을 사용하면 | ||
- 첫 번째 하위 집합의 합을 한 번 계산. | ||
- 다음 하위 집합으로 이동할 때: | ||
- 이전 합에서 첫 번째 값을 빼고 새 값을 더함. | ||
|
||
### 문제설명 | ||
|
||
- 배열과 정수를 입력받아, 정수 크기의 하위 집합중에 가장 큰 합을 리턴한다. | ||
|
||
### 수도코드 | ||
|
||
- 만약 배열의 크기가 정수보다 작으면 Null을 리턴한다. | ||
- 처음 윈도우 크기만큼 합을 tempSum, maxSum에 저장한다. | ||
|
||
- 배열을 순회하면서 tempSum에서 이전값을 빼고 새로운 값을 더한다. | ||
- maxSum과 비교하고 값이 더 크다면 tempSum을 maxSum에 대입한다. | ||
|
||
### 예시 | ||
|
||
- maxSubarraySum([1,2,3,4], 3) // 9 | ||
- maxSubarraySum([1,2], 3) // null | ||
- maxSubarraySum([1,1,1,1,9,2,9,3], 3) // 20 | ||
|
||
```javascript | ||
//O(n) | ||
function maxSubarraySum(arr, num) { | ||
if (arr.length < num) { | ||
return null; | ||
} | ||
|
||
let tempSum = 0; | ||
let maxSum = 0; | ||
|
||
for (let i = 0; i < num; i++) { | ||
tempSum += arr[i]; | ||
maxSum += arr[i]; | ||
} | ||
|
||
for (let i = 1; i < arr.length - num + 1; i++) { | ||
const prevVal = arr[i - 1]; | ||
const newVal = arr[i + num - 1]; | ||
tempSum = tempSum - prevVal + newVal; | ||
|
||
if (tempSum > maxSum) { | ||
maxSum = tempSum; | ||
} | ||
} | ||
|
||
return maxSum; | ||
} | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
### 분할 정복 패턴 | ||
|
||
- 데이터를 작게 나누어 처리하는 과정을 반복하는 패턴 | ||
- 정렬된 배열과 정수를 입력받아 위치를 리턴한다. | ||
- 정수가 존재하지 않으면 -1을 리턴한다. | ||
|
||
### 수도코드 | ||
|
||
- 배열의 시작과 끝을 변수로 생성 | ||
- 시작이 끝보다 같거나 작다면 | ||
- 중간값과 정수를 비교한다. | ||
- 만약 중간값이 정수보다 크다면 | ||
- 시작을 중간 + 1으로 설정한다. | ||
- 만약 중간값이 정수보다 작다면 | ||
- 끝을 중간 - 1으로 설정한다. | ||
- 만약 중간값이 정수와 같다면 | ||
- 결과를 리턴한다. | ||
|
||
### 예제 | ||
|
||
- search([1,2,3,4], 4) // 3 | ||
- search([1,2,3,4], 5) // -1 | ||
|
||
```javascript | ||
//O(log n) | ||
function search(array, val) { | ||
let min = 0; | ||
let max = array.length - 1; | ||
|
||
while (min <= max) { | ||
const middle = Math.floor((min + max) / 2); | ||
|
||
if (array[middle] < val) { | ||
min = middle + 1; | ||
} else if (array[middle] > val) { | ||
max = middle - 1; | ||
} else { | ||
return middle; | ||
} | ||
} | ||
|
||
return -1; | ||
} | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
# javascript-algorythm-and-data-structures | ||
자바스크립트 알고리즘 & 자료구조 스터디 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
### 문제설명 | ||
|
||
- 두개의 정수를 입력받아 정수를 이루는 숫자들의 빈도수가 같은지를 리턴하는 함수를 구현한다. | ||
- 음수가 존재하는 케이스는 무시한다. | ||
|
||
### 수도코드 | ||
|
||
- 만약 자릿수가 다르다면 false를 리턴한다. | ||
|
||
- 첫번째 정수의 구성요소를 카운팅할 객체 생성 | ||
- 첫번째 정수를 문자열로 만들어 순회하고 객체에 빈도수 카운팅 | ||
- 두번째 정수를 문자열로 만들어 순회하고 카운팅 객체와 비교한다. | ||
- 만약 값이 없거나 0이라면 false를 리턴한다. | ||
- 만약 값이 있으면 객체에서 빈도를 1을 감소시킨다. | ||
- true로 리턴한다. | ||
|
||
```javascript | ||
//O(n) | ||
function sameFrequency(num1, num2) { | ||
let counter = new Map(); | ||
|
||
let strNum1 = String(num1); | ||
let strNum2 = String(num2); | ||
|
||
if (strNum1.length != strNum2.length) { | ||
return false; | ||
} | ||
|
||
//O(n) | ||
for (let i = 0; i < strNum1.length; i++) { | ||
const n = strNum1[i]; | ||
counter.set(n, (counter.get(n) || 0) + 1); | ||
} | ||
|
||
//O(n) | ||
for (let i = 0; i < strNum2.length; i++) { | ||
const n = strNum2[i]; | ||
|
||
if (!counter.get(n)) { | ||
return false; | ||
} | ||
|
||
counter.set(n, counter.get(n) - 1); | ||
} | ||
|
||
return true; | ||
} | ||
``` |
Oops, something went wrong.