Skip to content

Commit

Permalink
Merge branch 'DaleStudy:main' into main
Browse files Browse the repository at this point in the history
  • Loading branch information
gitsunmin authored Oct 19, 2024
2 parents 5c1f5b9 + a3c9195 commit f3a850c
Show file tree
Hide file tree
Showing 20 changed files with 860 additions and 0 deletions.
37 changes: 37 additions & 0 deletions course-schedule/TonyKim9401.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
// TC: O(n + p)
// n -> number of courses, p -> the length of prerequisites
// SC: O(n + m)
// n -> the length of the graph size, m -> the length of nested list's size
class Solution {
public boolean canFinish(int numCourses, int[][] prerequisites) {
List<List<Integer>> graph = new ArrayList<>();
int[] inDegree = new int[numCourses];

for (int i = 0; i < numCourses; i++) graph.add(new ArrayList<>());

for (int[] prerequisite : prerequisites) {
int course = prerequisite[0];
int pre = prerequisite[1];
graph.get(pre).add(course);
inDegree[course] += 1;
}

Queue<Integer> q = new LinkedList<>();
for (int i = 0; i < numCourses; i++) {
if (inDegree[i] == 0) q.offer(i);
}

int visitedCourses = 0;
while (!q.isEmpty()) {
int course = q.poll();
visitedCourses += 1;

for (int nextCourse : graph.get(course)) {
inDegree[nextCourse] -= 1;
if (inDegree[nextCourse] == 0) q.offer(nextCourse);
}
}

return visitedCourses == numCourses;
}
}
31 changes: 31 additions & 0 deletions course-schedule/haklee.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
"""TC: O(node + edge), SC: O(node + edge)
์œ ๋ช…ํ•œ ์œ„์ƒ ์ •๋ ฌ ์•Œ๊ณ ๋ฆฌ์ฆ˜์ด๋ฏ€๋กœ ์„ค๋ช…์€ ์ƒ๋žตํ•œ๋‹ค.
"""


class Solution:
def canFinish(self, numCourses: int, prerequisites: List[List[int]]) -> bool:
# ์œ„์ƒ ์ •๋ ฌ.

# init
adj_list = [[] for _ in range(numCourses)] # SC: O(edge)
in_deg = [0] * numCourses # SC: O(node)

for edge in prerequisites:
adj_list[edge[0]].append(edge[1])
in_deg[edge[1]] += 1

node_to_search = [i for i, v in enumerate(in_deg) if v == 0] # TC: O(node)
sorted_list = []

# process
while node_to_search:
cur = node_to_search.pop() # TC: ์ตœ์•…์˜ ๊ฒฝ์šฐ ์ด O(node)๋งŒํผ ์‹คํ–‰
sorted_list.append(cur)
for node in adj_list[cur]:
in_deg[node] -= 1 # TC: ์ตœ์•…์˜ ๊ฒฝ์šฐ ์ด O(edge)๋งŒํผ ์‹คํ–‰
if in_deg[node] == 0:
node_to_search.append(node)

return len(sorted_list) == numCourses
79 changes: 79 additions & 0 deletions course-schedule/jdalma.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
package leetcode_study

import io.kotest.matchers.shouldBe
import org.junit.jupiter.api.Test

class `course-schedule` {

/**
* TC: O(node + edge), SC: O(node + edge)
*/
fun canFinish(numCourses: Int, prerequisites: Array<IntArray>): Boolean {
if (prerequisites.isEmpty()) return true

return usingTopologySort(numCourses, prerequisites)
}

private fun usingTopologySort(numCourses: Int, prerequisites: Array<IntArray>): Boolean {
val adj = List(numCourses) { mutableListOf<Int>() }
val degree = IntArray(numCourses)
for (e in prerequisites) {
val (course, pre) = e[0] to e[1]
adj[pre].add(course)
degree[course]++
}

val queue = ArrayDeque<Int>().apply {
degree.forEachIndexed { index, i ->
if (i == 0) {
this.add(index)
}
}
}

var answer = 0
while (queue.isNotEmpty()) {
val now = queue.removeFirst()
answer++

queue.addAll(adj[now].filter { --degree[it] == 0 })
}

return answer == numCourses
}

@Test
fun `์ฝ”์Šค์˜ ๊ฐœ์ˆ˜์™€ ์ฝ”์Šค ๊ฐ„ ์˜์กด์„ฑ์„ ์ „๋‹ฌํ•˜๋ฉด ์ฝ”์Šค๋ฅผ ์™„๋ฃŒํ•  ์ˆ˜ ์žˆ๋Š”์ง€ ์—ฌ๋ถ€๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค`() {
canFinish(5,
arrayOf(
intArrayOf(0,1),
intArrayOf(0,2),
intArrayOf(1,3),
intArrayOf(1,4),
intArrayOf(3,4)
)
) shouldBe true
canFinish(5,
arrayOf(
intArrayOf(1,4),
intArrayOf(2,4),
intArrayOf(3,1),
intArrayOf(3,2)
)
) shouldBe true
canFinish(2, arrayOf(intArrayOf(1, 0))) shouldBe true
canFinish(2, arrayOf(intArrayOf(1, 0), intArrayOf(0, 1))) shouldBe false
canFinish(20,
arrayOf(
intArrayOf(0,10),
intArrayOf(3,18),
intArrayOf(5,5),
intArrayOf(6,11),
intArrayOf(11,14),
intArrayOf(13,1),
intArrayOf(15,1),
intArrayOf(17,4)
)
) shouldBe false
}
}
47 changes: 47 additions & 0 deletions course-schedule/sunjae95.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
/**
* @description
* memoization + dfs
*
* n = length of nums
* p = length of prerequisites
*
* time complexity: O(n)
* space complexity: O(p)
*/
var canFinish = function (numCourses, prerequisites) {
const memo = Array.from({ length: numCourses + 1 }, () => false);
const visited = Array.from({ length: numCourses + 1 }, () => false);
// graph setting
const graph = prerequisites.reduce((map, [linkedNode, current]) => {
const list = map.get(current) ?? [];
list.push(linkedNode);
map.set(current, list);
return map;
}, new Map());

const dfs = (current) => {
const linkedNode = graph.get(current);

if (memo[current] || !linkedNode || linkedNode.length === 0) return true;

for (const node of linkedNode) {
if (visited[node]) return false;

visited[node] = true;
if (!dfs(node)) return false;
visited[node] = false;
memo[node] = true;
}

return true;
};

for (const [current] of graph) {
visited[current] = true;
if (!dfs(current)) return false;
visited[current] = false;
memo[current] = true;
}

return true;
};
16 changes: 16 additions & 0 deletions invert-binary-tree/TonyKim9401.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// TC: O(n)
// -> visit all nodes to invert
// SC: O(n)
// -> create all nodes again to exchange
class Solution {
public TreeNode invertTree(TreeNode root) {
if (root == null) return null;
invertTree(root.left);
invertTree(root.right);
TreeNode left = root.left;
TreeNode right = root.right;
root.left = right;
root.right = left;
return root;
}
}
32 changes: 32 additions & 0 deletions invert-binary-tree/haklee.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
"""TC: O(n), SC: O(h)
h๋Š” ์ด์ง„ ํŠธ๋ฆฌ์˜ ๋†’์ด.
n์ด ์ „์ฒด ๋…ธ๋“œ ๊ฐœ์ˆ˜๋ผ๊ณ  ํ• ๋•Œ
- ์ตœ์•…์˜ ๊ฒฝ์šฐ ํ•œ ์ชฝ ์ž์‹ ๋…ธ๋“œ๋งŒ ์ฑ„์›Œ์ง. ์ด ๊ฒฝ์šฐ h = n.
- ์ตœ์„ ์˜ ๊ฒฝ์šฐ ์™„์ „ ์ด์ง„ ํŠธ๋ฆฌ. h = log(n).
์•„์ด๋””์–ด:
์–‘์ชฝ ์ž์‹ ๋…ธ๋“œ์— ์ ‘๊ทผํ•ด์„œ ์žฌ๊ท€์ ์œผ๋กœ invert๋ฅผ ์ง„ํ–‰ํ•˜๊ณ , ๋‘ ์ž์‹ ๋…ธ๋“œ๋ฅผ ๋ฐ”๊พผ๋‹ค.
SC:
- ํ˜ธ์ถœ ์Šคํƒ ๊นŠ์ด๋Š” ํŠธ๋ฆฌ์˜ ๊นŠ์ด๊นŒ์ง€ ๊นŠ์–ด์งˆ ์ˆ˜ ์žˆ๋‹ค. ์ฆ‰, O(h).
TC:
- ๋ชจ๋“  ๋…ธ๋“œ์— ์ ‘๊ทผ. O(n).
"""


# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def invertTree(self, root: Optional[TreeNode]) -> Optional[TreeNode]:
def invert(node: Optional[TreeNode]) -> None:
if node is not None:
node.left, node.right = invert(node.right), invert(node.left)
return node

return invert(root)
58 changes: 58 additions & 0 deletions invert-binary-tree/jdalma.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
package leetcode_study

import io.kotest.matchers.shouldBe
import org.junit.jupiter.api.Test

class `invert-binary-tree` {

fun invertTree(root: TreeNode?): TreeNode? {
if (root == null) return null

return usingStack(root)
}

/**
* TC: O(n), SC: O(n)
*/
private fun usingDFS(node: TreeNode?): TreeNode? {
if (node == null) return null

val (left, right) = node.left to node.right
node.left = usingDFS(right)
node.right = usingDFS(left)

return node
}

/**
* TC: O(n), SC: O(n)
*/
private fun usingStack(node: TreeNode): TreeNode {
val stack= ArrayDeque<TreeNode>().apply {
this.add(node)
}

while (stack.isNotEmpty()) {
val now = stack.removeLast()
val tmp = now.left
now.left = now.right
now.right = tmp

now.left?.let { stack.add(it) }
now.right?.let { stack.add(it) }
}
return node
}

@Test
fun `์ „๋‹ฌ๋œ ๋…ธ๋“œ์˜ ํ•˜์œ„ ๋…ธ๋“œ๋“ค์˜ ๋ฐ˜์ „๋œ ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•œ๋‹ค`() {
val actual = TreeNode.of(4,2,7,1,3,6,9)
val expect = TreeNode.of(4,7,2,9,6,3,1)
invertTree(actual) shouldBe expect

val actual1 = TreeNode.of(1,2)
val expect1 = TreeNode.of(1,null,2)

invertTree(actual1) shouldBe expect1
}
}
23 changes: 23 additions & 0 deletions invert-binary-tree/sunjae95.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/**
* @description
* brainstorming:
* preorder traverse
*
* n = length of root
* time complexity: O(n)
* space complexity: O(n)
*/
var invertTree = function (root) {
const preOrder = (tree) => {
if (tree === null) return null;

const currentNode = new TreeNode(tree.val);

currentNode.right = preOrder(tree.left);
currentNode.left = preOrder(tree.right);

return currentNode;
};

return preOrder(root);
};
13 changes: 13 additions & 0 deletions jump-game/TonyKim9401.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// TC: O(n)
// SC: O(1)
class Solution {
public boolean canJump(int[] nums) {
int jump = 0;

for (int i = 0; i < nums.length; i++) {
if (i > jump) return false;
jump = Math.max(jump, i + nums[i]);
}
return true;
}
}
44 changes: 44 additions & 0 deletions jump-game/haklee.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
"""TC: O(n), SC: O(1)
n์€ ์ฃผ์–ด์ง„ ๋ฆฌ์ŠคํŠธ์˜ ๊ธธ์ด
์•„์ด๋””์–ด:
- ๋์— ์žˆ๋Š” ์•„์ดํ…œ๋ถ€ํ„ฐ ์‹œ์ž‘ํ•ด์„œ '์ตœ์†Œ ์–ด๋””๊นŒ์ง€๋Š” ๋„๋‹ฌํ•ด์•ผ ๋ ์นธ๊นŒ์ง€ ์ ํ”„ ๊ฐ€๋Šฅํ•œ์ง€'๋ฅผ ์—…๋ฐ์ดํŠธ ํ•œ๋‹ค.
- example๋“ค๋กœ ์ดํ•ดํ•ด๋ณด์ž. index๋Š” 0๋ถ€ํ„ฐ ์‹œ์ž‘.
- example 1: [2,3,1,1,4]
- 4๋ฒˆ์งธ ์นธ์— ๋„๋‹ฌํ•  ์ˆ˜ ์žˆ์œผ๋ฉด ์„ฑ๊ณต์ด๋‹ค. reach_at_least ๊ฐ’์„ 4๋กœ ์ดˆ๊ธฐํ™” ํ•œ๋‹ค.
- 3๋ฒˆ์งธ ์นธ์—์„œ๋Š” ์ตœ๋Œ€ 4๋ฒˆ์งธ ์นธ๊นŒ์ง€ ๊ฐˆ ์ˆ˜ ์žˆ๋‹ค. ์ฆ‰, ์ ์–ด๋„ 3๋ฒˆ ์นธ๊นŒ์ง€ ๊ฐ€๋ฉด ์„ฑ๊ณต์ด๋ฏ€๋กœ
reach_at_least๋ฅผ 3์œผ๋กœ ์—…๋ฐ์ดํŠธ ํ•œ๋‹ค.
- 2๋ฒˆ์งธ ์นธ์—์„œ๋Š” ์ตœ๋Œ€ 3๋ฒˆ์งธ ์นธ๊นŒ์ง€ ๊ฐˆ ์ˆ˜ ์žˆ๋‹ค. reach_at_least๋ฅผ 2๋กœ ์—…๋ฐ์ดํŠธ ํ•œ๋‹ค.
- 1๋ฒˆ์งธ ์นธ์—์„œ๋Š” ์ตœ๋Œ€ 1+3=4๋ฒˆ์งธ ์นธ๊นŒ์ง€ ๊ฐˆ ์ˆ˜ ์žˆ๋‹ค. ์ด ์นธ์—์„œ ํ˜„ reach_at_least ๊ฐ’์ธ 2๋ฒˆ์งธ ์นธ๊นŒ์ง€
์ถฉ๋ถ„ํžˆ ๊ฐˆ ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ reach_at_least ๊ฐ’์„ 1๋กœ ์—…๋ฐ์ดํŠธ ํ•œ๋‹ค.
- 0๋ฒˆ์งธ ์นธ์—์„œ๋Š” ์ตœ๋Œ€ 0+2=2๋ฒˆ์งธ ์นธ๊นŒ์ง€ ๊ฐˆ ์ˆ˜ ์žˆ๋‹ค. ํ˜„ reach_at_least ๊ฐ’์ธ 1๋ฒˆ์งธ ์นธ๊นŒ์ง€ ์ถฉ๋ถ„ํžˆ
๊ฐˆ ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ reach_at_least ๊ฐ’์„ 0์œผ๋กœ ์—…๋ฐ์ดํŠธ ํ•œ๋‹ค.
- 0๋ฒˆ์งธ ์นธ์—์„œ ๋ ์นธ๊นŒ์ง€ ๊ฐˆ ์ˆ˜ ์žˆ๋‹ค.
- example 2: [3,2,1,0,4]
- 4๋ฒˆ์งธ ์นธ์— ๋„๋‹ฌํ•  ์ˆ˜ ์žˆ์œผ๋ฉด ์„ฑ๊ณต์ด๋‹ค. reach_at_least ๊ฐ’์„ 4๋กœ ์ดˆ๊ธฐํ™” ํ•œ๋‹ค.
- 3๋ฒˆ์งธ ์นธ์—์„œ๋Š” ์ตœ๋Œ€ 3๋ฒˆ์งธ ์นธ๊นŒ์ง€ ๊ฐˆ ์ˆ˜ ์žˆ๋‹ค. ์—ฌ๊ธฐ์„œ๋Š” ํ˜„ reach_at_least ๊ฐ’์ธ 4๊นŒ์ง€ ๊ฐˆ ์ˆ˜ ์—†์œผ๋‹ˆ
์•„๋ฌด ์ผ๋„ ์ผ์–ด๋‚˜์ง€ ์•Š๋Š”๋‹ค.
- 2๋ฒˆ์งธ ์นธ์—์„œ๋Š” ์ตœ๋Œ€ 2+1=3๋ฒˆ์งธ ์นธ๊นŒ์ง€ ๊ฐˆ ์ˆ˜ ์žˆ๋‹ค. ์—ฌ๊ธฐ์„œ๋„ ํ˜„ reach_at_least ๊ฐ’์ธ 4๊นŒ์ง€ ๊ฐˆ ์ˆ˜ ์—†๊ณ ,
์•„๋ฌด ์ผ๋„ ์ผ์–ด๋‚˜์ง€ ์•Š๋Š”๋‹ค.
- 1๋ฒˆ์งธ ์นธ์—์„œ๋Š” ์ตœ๋Œ€ 1+2=3๋ฒˆ์งธ ์นธ๊นŒ์ง€ ๊ฐˆ ์ˆ˜ ์žˆ๋‹ค. ๋น„์Šทํ•˜๊ฒŒ ์•„๋ฌด ์ผ๋„ ์ผ์–ด๋‚˜์ง€ ์•Š๋Š”๋‹ค.
- 0๋ฒˆ์งธ ์นธ์—์„œ๋Š” ์ตœ๋Œ€ 0+3=3๋ฒˆ์งธ ์นธ๊นŒ์ง€ ๊ฐˆ ์ˆ˜ ์žˆ๋‹ค. ๋น„์Šทํ•˜๊ฒŒ ์•„๋ฌด ์ผ๋„ ์ผ์–ด๋‚˜์ง€ ์•Š๋Š”๋‹ค.
- reach_at_least ๊ฐ’์ด 0์ด ์•„๋‹ˆ๋‹ค. ์ฆ‰, 0๋ฒˆ์งธ ์นธ์—์„œ๋Š” ๋ ์นธ๊นŒ์ง€ ๊ฐˆ ์ˆ˜ ์—†๋‹ค.
SC:
- reach_at_least ๊ฐ’์— ์ธ๋ฑ์Šค ํ•˜๋‚˜๋งŒ ๊ด€๋ฆฌํ•œ๋‹ค. ์ฆ‰, O(1).
TC:
- nums์˜ ๋์—์„œ ๋‘ ๋ฒˆ์งธ ์•„์ดํ…œ๋ถ€ํ„ฐ ์ฒซ ๋ฒˆ์งธ ์•„์ดํ…œ๊นŒ์ง€ ์ˆœ์ฐจ์ ์œผ๋กœ ์ ‘๊ทผํ•˜๋ฉด์„œ reach_at_least๊ฐ’์„ ์—…๋ฐ์ดํŠธ ํ•œ๋‹ค. O(n).
"""


class Solution:
def canJump(self, nums: List[int]) -> bool:
reach_at_least = len(nums) - 1

for i in range(len(nums) - 2, -1, -1):
if nums[i] + i >= reach_at_least:
reach_at_least = i

return reach_at_least == 0
Loading

0 comments on commit f3a850c

Please sign in to comment.