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

[GangBean] Week 8 #969

Merged
merged 10 commits into from
Feb 1, 2025
47 changes: 47 additions & 0 deletions design-add-and-search-words-data-structure/GangBean.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
class WordDictionary {
private Map<Character, WordDictionary> children;
private boolean isEnd;

public WordDictionary() {
this.children = new HashMap<>();
this.isEnd = false;
}

public void addWord(String word) {
char[] arr = word.toCharArray();
WordDictionary next = this;
for (int i = 0; i < arr.length; i++) {
char c = arr[i];
next.children.putIfAbsent(c, new WordDictionary());
next = next.children.get(c);
}
next.isEnd = true;
}

public boolean search(String word) {
// System.out.println(this);
return search(word, 0);
}

private boolean search(String word, int idx) {
if (idx == word.length()) return this.isEnd;
char c = word.charAt(idx);
if (c == '.') {
return this.children.values().stream().anyMatch(child -> child.search(word, idx+1));
}
if (!this.children.containsKey(c)) return false;
return this.children.get(c).search(word, idx+1);
}

public String toString() {
return String.format("%s -> %s", isEnd, this.children);
}
}

/**
* Your WordDictionary object will be instantiated and called as such:
* WordDictionary obj = new WordDictionary();
* obj.addWord(word);
* boolean param_2 = obj.search(word);
*/

22 changes: 22 additions & 0 deletions longest-increasing-subsequence/GangBean.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
class Solution {
/**
1. understanding
- dp[n] : length of longest increasing subsequence in 0...n
2. space
- time: O(N^2)
- space: O(N)
*/
public int lengthOfLIS(int[] nums) {
int[] dp = new int[nums.length];
Arrays.fill(dp, 1);
for (int i = 0; i < nums.length; i++) { // O(N)
for (int j = 0; j <= i; j++) { // O(N)
if (nums[j] < nums[i]) {
dp[i] = Math.max(dp[j]+1, dp[i]);
}
}
}
return Arrays.stream(dp).max().orElse(1);
}
}

38 changes: 38 additions & 0 deletions longest-substring-without-repeating-characters/GangBean.java
Copy link
Contributor

Choose a reason for hiding this comment

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

반복문 풀이 잘 보았습니다! 해당 문제는 백트랙킹으로도 풀 수 있어서 시간이 되신다면 백트랙킹으로 문제 풀이도 도전해 보시면 너무 좋을것 같습니다!

Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
class Solution {
/**
1. understanding
- [a] -> [a,b] -> [a,b,c] -> [a] -> [a,b] -> [a,b,c] -> [b] -> [b]
2. complexity
- time: O(N)
- space: O(N)
*/
public int lengthOfLongestSubstring(String s) {
int left = 0;
int right = 0;
int len = s.length();
HashSet charSet = new HashSet();
int ret = (len==0)?0:1;
while (left<len && right<len) {
if (left == right) {
right++;
charSet = new HashSet();
charSet.add(s.charAt(left));
} else {
if (!charSet.contains(s.charAt(right))) {
charSet.add(s.charAt(right));
int tmpLen = right - left + 1;
if (tmpLen > ret) {
ret = tmpLen;
}
right++;
} else {
left++;
right = left;
}
}
}

return ret;
}
}

11 changes: 11 additions & 0 deletions number-of-1-bits/GangBean.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
class Solution {
public int hammingWeight(int n) {
int count = 0;
while (n >= 1) {
count += n % 2;
n /= 2;
}
return count;
}
}

38 changes: 38 additions & 0 deletions number-of-islands/GangBean.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
class Solution {
/**
1. understanding
- for each grid cell, if it is land, then move horizontally and vertically, to find connecting lands
2. complexity
- time: O(N * M) where grid is N * M matrix
- space: O(1)
*/
public int numIslands(char[][] grid) {
int ret = 0;
for (int i=0; i<grid.length; i++) {
for (int j=0; j<grid[0].length; j++) {
if (grid[i][j] == '1') {
findIsland(grid,i,j,'.');
ret++;
}
}
}
return ret;
}

private void findIsland(char[][] grid, int i, int j, char color) {
if (grid[i][j] == '1') {
grid[i][j] = color;
}
int[] dx = {0,1,0,-1};
int[] dy = {1,0,-1,0};

for (int dir=0; dir<4; dir++) {
int nx = i + dx[dir];
int ny = j + dy[dir];
if (0<= nx&&nx<grid.length && 0<=ny&&ny<grid[0].length && grid[nx][ny]=='1') {
findIsland(grid,nx,ny,color);
}
}
}
}

25 changes: 25 additions & 0 deletions reverse-linked-list/GangBean.java
Copy link
Contributor

Choose a reason for hiding this comment

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

head의 노드들을 모두 List에 옮긴 뒤 역순으로 재구성 하는 방법을 사용하셨네요!
해당 문제는 LinkedList의 특성 중 하나인 현재 노드가 다음 노드를 가리키는 포인터를 가지고 있다.
0 -> 0 -> 0 -> .... 를 활용하여
0 <- o <- 0 <-.... 와 같은 방식으로 풀이를 하는게 정석이라 생각이 됩니다!
문제 특성을 이해하기 전에는 어려우실 수 있으니 저같은 경우에는 해설을 먼저 보고 이해 한 뒤 이해했네요.
제가 말씀 대로 풀이 하시면 TC: O(n), SC: O(1) 으로 문제를 풀이 하실 수 있을겁니다.
이 문제는 꼭 다시 확인 해 보셨으면 좋겠어요!

Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode() {}
* ListNode(int val) { this.val = val; }
* ListNode(int val, ListNode next) { this.val = val; this.next = next; }
* }
*/
class Solution {
public ListNode reverseList(ListNode head) {
ListNode curr = head;
ListNode prev = null;
while (curr != null) {
ListNode next = curr.next;
curr.next = prev;
prev = curr;
curr = next;
}

return prev;
}
}

40 changes: 40 additions & 0 deletions set-matrix-zeroes/GangBean.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
class Solution {
/**
1. understanding
- iterate over all cells, if value is 0, then add row and col to sweep target set.
- for each row target set, and col target set, sweep all it's value to 0
2. complexity
- time: O(m * n)
- space: O(m + n)
*/
public void setZeroes(int[][] matrix) {
Set<Integer> rows = new HashSet<>(); // O(m)
Set<Integer> cols = new HashSet<>(); // O(n)

for (int row = 0; row < matrix.length; row++) { // O(m)
for (int col = 0; col < matrix[row].length; col++) { // O(n)
if (matrix[row][col] == 0) { // O(m * n)
rows.add(row);
cols.add(col);
}
}
}

for (int row: rows) { // O(m)
int col = 0;
while (col < matrix[row].length) { // O(n)
matrix[row][col] = 0;
col++;
}
}

for (int col: cols) { // O(n)
int row = 0;
while (row < matrix.length) { // O(m)
matrix[row][col] = 0;
row++;
}
}
}
}

37 changes: 37 additions & 0 deletions spiral-matrix/GangBean.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
class Solution {
/**
1. understanding
- 3 x 3 = N x M
- (1,2,3) -> (6,9) // (8,7) -> (4) // (5)
- upper: step M count, N -= 1 // right: step N count, M -= 1 // bottom: step M count, N -= 1 // left: step N count, M -= 1
2. complexity:
- time: O(N * M)
- space: O(1)
*/
public List<Integer> spiralOrder(int[][] matrix) {
int r = 0;
int c = -1;
int dir = 1;
int N = matrix.length;
int M = matrix[0].length;
List<Integer> ret = new ArrayList<>();

while (0 < N && 0 < M) {
for (int i = 0; i < M; i++) {
c += dir;
ret.add(matrix[r][c]);
}
N -= 1;
for (int i = 0; i < N; i++) {
r += dir;
ret.add(matrix[r][c]);
}
M -= 1;

dir *= -1;
}

return ret;
}
}

24 changes: 24 additions & 0 deletions unique-paths/GangBean.java
Copy link
Contributor

Choose a reason for hiding this comment

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

전체 배열을 1로 초기화 한 후 진행하는 방식이 좋은 접근법 같습니다!

Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import java.math.BigDecimal;

class Solution {
/**
1. understanding
- To reach destination, you have to move bottom direction in m-1 times, and move to right direction in n-1 times.
- in example 2, [(DDR), (DRD), (RDD)] is the paths.
- so, the number of paths are combinations of (m-1) D and (n-1) R
- (m+n-2)!/(m-1)!(n-1)!, where ! means factorial, n! = 1*2*...*n
- factorial[n]: n!
2. complexity
- time: O(m+n)
- space: O(m+n)
*/
public int uniquePaths(int m, int n) {
BigDecimal[] dp = new BigDecimal[m+n];
Arrays.fill(dp, BigDecimal.ONE);
for (int num = 2; num < m+n; num++) {
dp[num] = dp[num-1].multiply(new BigDecimal(num));
}
return dp[m+n-2].divide(dp[m-1]).divide(dp[n-1]).intValue();
}
}