Skip to content

Commit

Permalink
w1-Merge pull request #13 from southppp22/main
Browse files Browse the repository at this point in the history
  • Loading branch information
wwwr-kim0en authored Dec 10, 2024
2 parents a7f9291 + c39d81f commit 00e20d1
Show file tree
Hide file tree
Showing 14 changed files with 752 additions and 0 deletions.
53 changes: 53 additions & 0 deletions namin/05/05_01_빈도_카운터_패턴.md
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;
}
```

### 구현하면서 놓친 부분

- 배열의 길이를 비교하는 부분을 빠뜨려서 두번째 배열의 길이가 긴 경우 예외적으로 통과하는 케이스가 생겼다.
37 changes: 37 additions & 0 deletions namin/05/05_02_애너그램.md
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;
}
```
37 changes: 37 additions & 0 deletions namin/05/05_03_다중_포인터_패턴.md
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++;
}
}
}
}
```
75 changes: 75 additions & 0 deletions namin/05/05_04_고유값_세기.md
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;
}
```
56 changes: 56 additions & 0 deletions namin/05/05_05_슬라이딩_윈도우_패턴.md
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;
}
```
44 changes: 44 additions & 0 deletions namin/05/05_06_분할_정복_패턴.md
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;
}
```
2 changes: 2 additions & 0 deletions namin/05/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# javascript-algorythm-and-data-structures
자바스크립트 알고리즘 &amp; 자료구조 스터디
48 changes: 48 additions & 0 deletions namin/06/06_01_same_frequency.md
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;
}
```
Loading

0 comments on commit 00e20d1

Please sign in to comment.