Skip to content
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

[dd_._._bb] Week 07 #927

Merged
merged 2 commits into from
Jan 24, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 56 additions & 0 deletions longest-substring-without-repeating-characters/lledellebell.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
/***
* @problem
* 주어진 문자열에서 중복되지 않는 문자로 이루어진 가장 긴 부분 문자열의 길이를 구해야 합니다.
*
* @constraints
* - 문자열의 길이는 0 이상 5 * 10^4 이하입니다.
* - 문자열은 ASCII 문자로만 구성됩니다.
*
* @example
* - 입력: "abcabcbb"
* 출력: 3 ("abc")
* - 입력: "bbbbb"
* 출력: 1 ("b")
* - 입력: "pwwkew"
* 출력: 3 ("wke")
*
* @description
* - ASCII 문자의 마지막 위치를 저장할 배열을 사용합니다.
* - 중복 문자가 발견되면 시작 지점을 해당 문자의 마지막 위치 다음으로 이동합니다.
* - 현재 서브스트링의 길이를 계산하여 최대 길이를 갱신합니다.
*
* @complexity
* - 시간 복잡도: O(n)
* ㄴ 문자열을 한 번 순회하며 각 문자를 처리합니다.
* - 공간 복잡도: O(1)
* ㄴ 고정 크기 배열(128)을 사용하므로 공간 복잡도는 상수입니다.
Copy link
Contributor

Choose a reason for hiding this comment

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

👍

Copy link
Contributor Author

Choose a reason for hiding this comment

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

리뷰 감사합니다! 😊
다음 주에는 5문제를 모두 풀 수 있도록 최선을 다하겠습니다! 💪

*/
function lengthOfLongestSubstring(s: string): number {
// ASCII 문자의 마지막 위치를 저장할 배열 (128 크기, 초기값 -1)
const lastSeenIndex = Array(128).fill(-1);
let substringStart = 0;
let longestLength = 0;

for (let currentIndex = 0; currentIndex < s.length; currentIndex++) {
const currentCharCode = s.charCodeAt(currentIndex);

// 중복 문자가 발견되었고, 그 문자의 마지막 위치가 현재 시작점 이후라면
if (lastSeenIndex[currentCharCode] >= substringStart) {
// 시작 지점을 중복 문자의 다음 위치로 이동
substringStart = lastSeenIndex[currentCharCode] + 1;
}

// 현재 문자의 위치를 배열에 저장
lastSeenIndex[currentCharCode] = currentIndex;

// 현재 서브스트링의 길이를 계산하고 최대값 갱신
longestLength = Math.max(longestLength, currentIndex - substringStart + 1);
}

return longestLength;
}

// 테스트
console.log(lengthOfLongestSubstring("abcabcbb")); // 출력: 3
console.log(lengthOfLongestSubstring("bbbbb")); // 출력: 1
console.log(lengthOfLongestSubstring("pwwkew")); // 출력: 3
84 changes: 84 additions & 0 deletions reverse-linked-list/lledellebell.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
/**
* @problem
* 단일 연결 리스트를 뒤집는 알고리즘을 함수형 프로그래밍 스타일로 구현합니다.
* 예: 1 -> 2 -> 3 -> 4 -> 5 -> => 5 -> 4 -> 3 -> 2 -> 1
*
* @constraints
* - 노드의 개수는 0 이상일 수 있습니다.
* - 각 노드의 값은 정수입니다.
* - 입력 리스트는 단일 연결 리스트입니다.
*
* @example
* - Input: head = [1, 2, 3, 4, 5]
* - Output: [5, 4, 3, 2, 1]
*
* @description
* 재귀를 사용하여 연결 리스트를 뒤집습니다.
* 함수형 프로그래밍 스타일에서는 상태를 변경하지 않고, 각 호출에서 새로운 리스트를 반환합니다.
*
* @complexity
* - 시간 복잡도: O(n)
* 리스트의 모든 노드를 한 번씩 방문합니다.
* - 공간 복잡도: O(n)
* 재귀 호출 스택을 사용합니다.
*/
class ListNode {
val: number;
next: ListNode | null;

/**
* @constructor
* @param val - 노드의 값
* @param next - 다음 노드에 대한 참조
*/
constructor(val?: number, next?: ListNode | null) {
this.val = val ?? 0; // 값이 없으면 기본값 0
this.next = next ?? null; // 다음 노드가 없으면
}
}

/**
* 단일 연결 리스트를 뒤집는 함수 (재귀적, 함수형 스타일)
* @param head - 연결 리스트의 시작 노드
* @param prev - 이전 노드 (초기값은)
* @returns 뒤집힌 연결 리스트의 시작 노드
*/
function reverseList(
head: ListNode | null,
prev: ListNode | null = null
): ListNode | null {
// 기본 조건: 리스트가 비어 있거나 마지막 노드에 도달한 경우
if (head === null) {
return prev;
}

// 다음 노드 저장
const next = head.next;

// 현재 노드의 방향을 이전 노드로 설정
head.next = prev;

// 재귀 호출로 다음 노드 처리
return reverseList(next, head);
}

// 연결 리스트 생성
const node1 = new ListNode(1);
const node2 = new ListNode(2);
const node3 = new ListNode(3);
const node4 = new ListNode(4);
const node5 = new ListNode(5);

node1.next = node2;
node2.next = node3;
node3.next = node4;
node4.next = node5;

const reversedHead = reverseList(node1);

// 결과
let current = reversedHead;
while (current !== null) {
console.log(current.val); // 5, 4, 3, 2, 1
current = current.next;
}
Loading