Skip to content
Open
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
26 changes: 26 additions & 0 deletions clone-graph/jinvicky.java
Copy link
Contributor

Choose a reason for hiding this comment

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

clone() 메서드로 분리하니까 코드 이해가 더 쉬웠습니다!

Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import java.util.HashMap;
import java.util.Map;

class Solution {
public Node cloneGraph(Node node) {
if (node == null) return null;

Map<Node, Node> map = new HashMap<>();
return clone(node, map);
}

private Node clone(Node node, Map<Node, Node> map) {
if (map.containsKey(node)) {
return map.get(node);
}

Node clonedNode = new Node(node.val);
map.put(node, clonedNode);

for (Node neighbor : node.neighbors) {
clonedNode.neighbors.add(clone(neighbor, map));
}

return clonedNode;
}
}
76 changes: 76 additions & 0 deletions invert-binary-tree/jinvicky.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
import java.util.LinkedList;
import java.util.Queue;

/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
public TreeNode invertTree(TreeNode root) {
if (root == null) return null;

TreeNode temp = root.left;
root.left = root.right;
root.right = temp;

System.out.println(root.val);

invertTree(root.left);
invertTree(root.right);

return root;
}

public TreeNode invertTreeByQueue(TreeNode root) {
if (root == null) {
return null;
}

// BFS를 위한 큐 생성
Queue<TreeNode> queue = new LinkedList<>();
queue.add(root);

// 큐가 빌 때까지 반복
while (!queue.isEmpty()) {
TreeNode current = queue.poll();

// 현재 노드의 왼쪽 자식과 오른쪽 자식 교환
TreeNode temp = current.left;
current.left = current.right;
current.right = temp;

// 자식 노드가 있으면 큐에 추가
if (current.left != null) {
queue.add(current.left);
}
if (current.right != null) {
queue.add(current.right);
}
}

return root;
}
}
/**
* public TreeNode invertTreeByQueue(TreeNode root) {
* // root가 널이면 리턴
* // 큐 선언하고 루트를 삽입
*
* // 큐가 비기 전까지 연산 반복
* // temp 변수로 left와 right을 교체
* // 자식 left 노드를 큐에 추가 (있다면)
* // 자식 right 노드를 큐에 추가 (있다면)
* // 루트를 반환
* }
*/
3 changes: 3 additions & 0 deletions longest-common-subsequence/jinvicky.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
class Solution {
// dp 표를 봐야 이해가 더 쉽다. https://twinw.tistory.com/126
// dp, 즉 메모이제이션의 범위는 이전 row인 것이다. (기존 cell 위주의 문제보다 넓은 범위)
public int longestCommonSubsequence(String text1, String text2) {
// 왼쪽과 위로 1줄씩 버퍼(여유) 배열이 있다. 즉, dp[0][..], dp[..][0]은 0으로 초기화된 상태
int m = text1.length();
int n = text2.length();

Expand Down
51 changes: 51 additions & 0 deletions longest-repeating-character-replacement/jinvicky.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import java.util.HashMap;
import java.util.Map;

class Solution {
public int characterReplacement(String s, int k) {
Map<Character, Integer> charCount = new HashMap<>();

int left = 0;
int maxFrequency = 0;
int maxLength = 0;

for(int right = 0; right < s.length(); right++) {
char rightChar = s.charAt(right);

charCount.put(rightChar, charCount.getOrDefault(rightChar, 0) + 1);

maxFrequency = Math.max(maxFrequency, charCount.get(rightChar));

if((right - left + 1) - maxFrequency > k) {
char leftChar = s.charAt(left);

charCount.put(leftChar, charCount.get(leftChar) - 1);
left++;
}

maxLength = Math.max(maxLength, right - left + 1);
}
return maxLength;
}

// while문과 배열로 성능이 개선된 풀이
public int characterReplacement2(String s, int k) {
int left = 0, right = 0;
int maxCount = 0, result = 0;
int[] freq = new int[26];

while (right < s.length()) {
freq[s.charAt(right) - 'A']++;
maxCount = Math.max(maxCount, freq[s.charAt(right) - 'A']);

while ((right - left + 1) - maxCount > k) {
freq[s.charAt(left) - 'A']--;
left++;
}

result = Math.max(result, right - left + 1);
right++;
}
return result;
}
}
6 changes: 6 additions & 0 deletions maximum-product-subarray/jinvicky.java
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
class Solution {
// 최소값은 음수가 곱해질 때 최대값이 될 수 있기 때문에 최소, 최대를 각각 dp[]로 관리해야 한다.
public int maxProduct(int[] nums) {
if (nums.length == 1)
return nums[0];
Expand All @@ -15,6 +16,11 @@ public int maxProduct(int[] nums) {

for (int i = 1; i < len; i++) {
// 후보 3을 준비
/**
* 현재 인덱스값 (justNum)
* 이전 인덱스 최소값 x 현재 인덱스 값 (reverse)
* 이전 인덱스 최대값 x 현재 인덱스 값 (keep)
*/
int justNum = nums[i];
// 계속 더한 값
int keep = justNum * max[i-1];
Expand Down
66 changes: 66 additions & 0 deletions pacific-atlantic-water-flow/jinvicky.java
Copy link
Contributor

Choose a reason for hiding this comment

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

pacific, atlantic 이름의 배열을 visited 역할을 주어 풀이한 거군요. 처음에 pacific, atlantic은 무슨 역할이지 살짝 헤맸는데 코드를 몇 번 읽어보고 visited 역할을 하고 흐르고 있다는 걸 나타내는 구나를 알 수 있었습니다. 덕분에 공부할 수 있었습니다.

Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import java.util.ArrayList;
import java.util.List;

class Solution {
private int[][] heights;
private int rows, cols;
private int[][] directions = {{0, 1}, {0, -1}, {1, 0}, {-1, 0}}; // 상하좌우

public List<List<Integer>> pacificAtlantic(int[][] heights) {
this.heights = heights;
this.rows = heights.length;
this.cols = heights[0].length;

// 태평양과 대서양에서 도달 가능한 지점을 저장하는 배열
boolean[][] pacific = new boolean[rows][cols];
boolean[][] atlantic = new boolean[rows][cols];

// 태평양과 대서양 경계에서 탐색 시작
// 맨 윗줄과 맨 아랫줄
for (int j = 0; j < cols; j++) {
dfs(0, j, pacific, Integer.MIN_VALUE); // 태평양 (윗줄)
dfs(rows - 1, j, atlantic, Integer.MIN_VALUE); // 대서양 (아랫줄)
}

// 맨 왼쪽줄과 맨 오른쪽줄
for (int i = 0; i < rows; i++) {
dfs(i, 0, pacific, Integer.MIN_VALUE); // 태평양 (왼쪽줄)
dfs(i, cols - 1, atlantic, Integer.MIN_VALUE); // 대서양 (오른쪽줄)
}

// 결과를 저장할 리스트
List<List<Integer>> result = new ArrayList<>();

// 양쪽 바다로 모두 흐를 수 있는 지점 찾기
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
if (pacific[i][j] && atlantic[i][j]) {
List<Integer> coord = new ArrayList<>();
coord.add(i);
coord.add(j);
result.add(coord);
}
}
}

return result;
}

// 깊이 우선 탐색 (DFS) 함수
private void dfs(int r, int c, boolean[][] visited, int prevHeight) {
// 유효하지 않은 지점 (범위 밖, 이미 방문, 높이 조건 불만족)
if (r < 0 || r >= rows || c < 0 || c >= cols || visited[r][c] || heights[r][c] < prevHeight) {
return;
}

// 현재 지점 방문 표시
visited[r][c] = true;

// 상하좌우로 탐색 진행
for (int[] dir : directions) {
int newR = r + dir[0];
int newC = c + dir[1];
dfs(newR, newC, visited, heights[r][c]);
}
}
}
61 changes: 61 additions & 0 deletions palindromic-substrings/jinvicky.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@


class Solution {

public int countSubstrings(String s) {
int n = s.length();
int count = 0;

// 홀수와 짝수 통합 처리 (0부터 2n-1까지)
for (int center = 0; center < 2 * n - 1; center++) {
int left = center / 2;
int right = left + center % 2;

while (left >= 0 && right < n && s.charAt(left) == s.charAt(right)) {
count++;
left--;
right++;
}
}

return count;
}

// 더 가독성이 좋은 풀이

/**
* 1. 회문의 중심을 명확하게 분리한다.
* 2. c는 회문의 중심후보가 된다. 1글자짜리 중심이거나 혹은 두 글자짜리 회문의 왼쪽 중심이다.
* 3. c를 홀수 길이 회문의 중심으로 설정한다 -> expand(s,c,c)
* 4. c부터 c+1까지 짝수 길이 회문의 왼쪽 중심으로 설정한다 -> expand(s,c,c+1)
* <p>
* 이렇게 하는 이유는 ABA와 ABBA 두 가지 경우를 모두 커버하기 위해서이다.
*/
public int countSubstrings2(String s) {
int n = s.length();
int count = 0;
for (int c = 0; c < n; c++) {
count += expand(s, c, c); // 홀수 길이 중심
count += expand(s, c, c + 1); // 짝수 길이 중심
}
return count;
}

private int expand(String s, int L, int R) {
int add = 0;
while (L >= 0 && R < s.length() && s.charAt(L) == s.charAt(R)) {
add++;
L--;
R++;
}
return add;
}

/**
* 프라이빗 메서드 "확장" 선언
* 1. L, R 포인터 인덱스를 받는다.
* 2. 두 포인터가 문자열 내 유효한 범위에 있어야 한다.
* 3. L과 R이 가리키는 문자가 같아야 한다.
* 2와 3을 모두 만족한다면 회문
*/
}
18 changes: 18 additions & 0 deletions reverse-bits/jinvicky.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@


public class Solution {
public int reverseBits(int n) {
int reversed = 0;

for (int i = 0; i < 32; i++) {
reversed <<= 1;

int lsb_of_n = n & 1; // n이 홀수면 1, 짝수면 0을 반환

reversed |= lsb_of_n;

n >>= 1;
}
return reversed;
}
}
21 changes: 21 additions & 0 deletions sum-of-two-integers/jinvicky.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
class Solution {
public int getSum(int a, int b) {

while (b != 0) {

// 변수 2개와 비트 연산
// 1.
int sum = a ^ b;

// 2.
int carry = (a & b) << 1;

/// 3.
a = sum;
b = carry; // 한번하고 말면 b는 쓰일 일이 없는데? -> 빠뜨린 반복문이 없는지 확인한다.

}

return a;
}
}
Loading