Skip to content

Commit b34981c

Browse files
authored
Merge branch 'DaleStudy:main' into main
2 parents fdcf209 + 65a41cd commit b34981c

File tree

14 files changed

+416
-0
lines changed

14 files changed

+416
-0
lines changed

clone-graph/hu6r1s.py

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
"""
2+
# Definition for a Node.
3+
class Node:
4+
def __init__(self, val = 0, neighbors = None):
5+
self.val = val
6+
self.neighbors = neighbors if neighbors is not None else []
7+
"""
8+
9+
from typing import Optional
10+
class Solution:
11+
def cloneGraph(self, node: Optional['Node']) -> Optional['Node']:
12+
if not node:
13+
return None
14+
15+
visited = [None] * 101
16+
17+
def dfs(n):
18+
if visited[n.val] is not None:
19+
return visited[n.val]
20+
21+
copy = Node(n.val, [])
22+
visited[n.val] = copy
23+
24+
for nei in n.neighbors:
25+
copy.neighbors.append(dfs(nei))
26+
return copy
27+
28+
return dfs(node)

clone-graph/njngwn.java

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
/*
2+
// Definition for a Node.
3+
class Node {
4+
public int val;
5+
public List<Node> neighbors;
6+
public Node() {
7+
val = 0;
8+
neighbors = new ArrayList<Node>();
9+
}
10+
public Node(int _val) {
11+
val = _val;
12+
neighbors = new ArrayList<Node>();
13+
}
14+
public Node(int _val, ArrayList<Node> _neighbors) {
15+
val = _val;
16+
neighbors = _neighbors;
17+
}
18+
}
19+
*/
20+
21+
class Solution {
22+
HashMap<Node, Node> nodeMap = new HashMap<>(); // key: original Node, value: copied Node
23+
24+
public Node cloneGraph(Node node) {
25+
if (node == null) return null;
26+
27+
if (nodeMap.containsKey(node)) {
28+
return nodeMap.get(node);
29+
}
30+
31+
Node newNode = new Node(node.val);
32+
nodeMap.put(node, newNode);
33+
34+
for (Node neighborNode : node.neighbors) {
35+
newNode.neighbors.add(cloneGraph(neighborNode));
36+
}
37+
38+
return newNode;
39+
}
40+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
class Solution:
2+
"""
3+
문제의 힌트에서 DP를 활용하는 것을 확인
4+
"""
5+
def longestCommonSubsequence(self, text1: str, text2: str) -> int:
6+
dp = [[0] * (len(text2)+1) for _ in range(len(text1)+1)]
7+
8+
for i in range(1, len(text1)+1):
9+
for j in range(1, len(text2)+1):
10+
if text1[i-1] == text2[j-1]:
11+
dp[i][j] = dp[i-1][j-1] + 1
12+
else:
13+
dp[i][j] = max(dp[i-1][j], dp[i][j-1])
14+
15+
return dp[-1][-1]
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
class Solution {
2+
public int longestCommonSubsequence(String text1, String text2) {
3+
int m = text1.length();
4+
int n = text2.length();
5+
6+
int[][] dp = new int[m+1][n+1];
7+
8+
for (int i = 0; i < m; i++) {
9+
for (int j = 0; j < n; j++) {
10+
// DP 계산을 +1로 했어야 했는데 이전 케이스를 재사용하는 -1로만 접근해서 범위 에러가 많이 났었다.
11+
if (text1.charAt(i) == text2.charAt(j)) {
12+
dp[i + 1][j + 1] = dp[i][j] + 1;
13+
} else {
14+
dp[i + 1][j + 1] = Math.max(dp[i][j + 1], dp[i + 1][j]);
15+
}
16+
}
17+
}
18+
19+
return dp[m][n];
20+
}
21+
22+
// -1을 참조해 이전 케이스를 재사용하는 경우는 1부터 m,n까지 하면 그렇게 할 수 있다.
23+
public int longestCommonSubsequence2(String text1, String text2) {
24+
int m = text1.length();
25+
int n = text2.length();
26+
int[][] dp = new int[m + 1][n + 1];
27+
28+
for (int i = 1; i <= m; i++) {
29+
for (int j = 1; j <= n; j++) {
30+
if (text1.charAt(i - 1) == text2.charAt(j - 1)) {
31+
dp[i][j] = dp[i - 1][j - 1] + 1; // 문자가 같으면 대각선 값 + 1
32+
} else {
33+
dp[i][j] = Math.max(dp[i - 1][j], dp[i][j - 1]); // 위 or 왼쪽 중 큰 값
34+
}
35+
}
36+
}
37+
38+
return dp[m][n];
39+
}
40+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
class Solution:
2+
def characterReplacement(self, s: str, k: int) -> int:
3+
start, max_len, max_freq = 0, 0, 0
4+
5+
window = {}
6+
for end in range(len(s)):
7+
char = s[end]
8+
window[char] = window.get(char, 0) + 1
9+
max_freq = max(max_freq, window[char])
10+
11+
while (end - start + 1) - max_freq > k:
12+
left_char = s[start]
13+
window[left_char] -= 1
14+
start += 1
15+
16+
max_len = end - start + 1 if end - start + 1 > max_len else max_len
17+
18+
return max_len
19+
20+
21+
if __name__ == "__main__":
22+
s = Solution()
23+
print(s.characterReplacement('ABAB', 2))
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
class Solution:
2+
def characterReplacement(self, s: str, k: int) -> int:
3+
counts = {}
4+
left = 0
5+
max_count = 0
6+
res = 0
7+
8+
for right in range(len(s)):
9+
counts[s[right]] = counts.get(s[right], 0) + 1
10+
max_count = max(max_count, counts[s[right]])
11+
12+
while (right - left + 1) - max_count > k:
13+
counts[s[left]] -= 1
14+
left += 1
15+
16+
res = max(res, right - left + 1)
17+
18+
return res
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
// Time Complexity: O(n), n: s.length()
2+
// Space Complexity: O(1)
3+
class Solution {
4+
public int characterReplacement(String s, int k) {
5+
int[] charFreqArr = new int[26]; // s consists of only uppercase English letters
6+
int maxFreq = 0;
7+
int maxLength = 0;
8+
9+
for (int left = 0, right = 0; right < s.length(); right++) {
10+
char letter = s.charAt(right);
11+
int letterIdx = letter-'A';
12+
13+
charFreqArr[letterIdx]++;
14+
maxFreq = Math.max(maxFreq, charFreqArr[letterIdx]);
15+
16+
// when left idx moves rightward? -> k + maxFreq < size of sliding window
17+
// here, we don't neet to recalculate maxFreq because the point is to calculate 'best' maxFreq
18+
if (maxFreq + k < right-left+1) {
19+
char leftChar = s.charAt(left);
20+
charFreqArr[leftChar-'A']--;
21+
left++;
22+
}
23+
24+
maxLength = Math.max(maxLength, right-left+1);
25+
}
26+
27+
return maxLength;
28+
}
29+
}
30+
31+
// AABABBA, k=1, maxFreq=1, maxLength=1
32+
// l
33+
// r
34+
35+
// AABABBA, k=1, maxFreq=2, maxLength=2
36+
// lr
37+
38+
// AABABBA, k=1, maxFreq=2, maxLength=3
39+
// l r
40+
41+
// AABABBA, k=1, maxFreq=3, maxLength=4
42+
// l r
43+
44+
// AABABBA, k=1, maxFreq=3, maxLength=4 ==> fail
45+
// l r
46+
47+
// AABABBA, k=1, maxFreq=3
48+
// l r

palindromic-substrings/hu6r1s.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
class Solution:
2+
"""
3+
브루트포스로 모두 탐색하면서 집어넣는 방법
4+
O(n^2)
5+
"""
6+
def countSubstrings(self, s: str) -> int:
7+
cnt = []
8+
for i in range(len(s)):
9+
for j in range(i, len(s)):
10+
sub = s[i:j+1]
11+
if sub and sub == sub[::-1]:
12+
cnt.append(sub)
13+
return len(cnt)
Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
/**
2+
* @param {string} s
3+
* @return {number}
4+
*
5+
* 풀이 방법 1
6+
*
7+
* 1. brute force 를 사용해서 모든 경우의 수를 구한다.
8+
* 2. 투포인터를 통해 isPalindrome 을 확인한다.
9+
*
10+
* 복잡성
11+
*
12+
* Time Complexity: O(n^2)
13+
* Space Complexity: O(1)
14+
*/
15+
16+
/**
17+
* isPalindrome 함수
18+
*/
19+
function isPalindrome(s) {
20+
let left = 0;
21+
let right = s.length - 1;
22+
23+
while (left < right) {
24+
if (s[left] !== s[right]) return false;
25+
left++;
26+
right--;
27+
}
28+
29+
return true;
30+
}
31+
32+
var countSubstrings = function(s) {
33+
let count = 0;
34+
35+
// 모든 경우의 수를 구한다.
36+
for (let start = 0; start < s.length; start++) {
37+
for (let end = start; end < s.length; end++) {
38+
const subStr = s.slice(start, end + 1);
39+
40+
// isPalindrome 함수를 통해 팰린드롬인지 확인한다.
41+
if (isPalindrome(subStr)) {
42+
count++;
43+
}
44+
}
45+
}
46+
47+
return count;
48+
};
49+
50+
/**
51+
* 풀이 방법 2
52+
*
53+
* 1. dfs를 통해 모든 경우의 수를 구한다.
54+
* 2. isPalindrome 함수를 통해 팰린드롬인지 확인한다.
55+
*
56+
* 복잡성
57+
*
58+
* Time Complexity: O(n^2)
59+
* Space Complexity: O(1)
60+
*/
61+
62+
function isPalindrome(s) {
63+
let left = 0;
64+
let right = s.length - 1;
65+
66+
while (left < right) {
67+
if (s[left] !== s[right]) return false;
68+
left++;
69+
right--;
70+
}
71+
72+
return true;
73+
}
74+
75+
var countSubstrings = function(s) {
76+
let count = 0;
77+
78+
function dfs(startIdx) {
79+
// 모든 시작점 탐색 완료
80+
if (startIdx === s.length) return;
81+
82+
// 현재 시작점에서 가능한 모든 끝점 확인
83+
for (let end = startIdx; end < s.length; end++) {
84+
const sub = s.slice(startIdx, end + 1);
85+
if (isPalindrome(sub)) {
86+
count++;
87+
}
88+
}
89+
90+
// 다음 시작점으로 이동
91+
dfs(startIdx + 1);
92+
}
93+
94+
dfs(0);
95+
return count;
96+
};

palindromic-substrings/njngwn.java

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
// Time Complexity: O(n*n), n: s.length()
2+
// Space Complexity: O(1)
3+
class Solution {
4+
public int countSubstrings(String s) {
5+
int cnt = 0;
6+
7+
for (int i = 0; i < s.length(); i++, cnt++) { // i: center of palindrom
8+
// odd number palindrom: e.g. aba
9+
int left = i-1, right = i+1;
10+
11+
while (left >= 0 && right < s.length()) {
12+
if (s.charAt(left) != s.charAt(right)) {
13+
break;
14+
}
15+
cnt++;
16+
left--;
17+
right++;
18+
}
19+
20+
// even number palindrom: e.g. abba
21+
left = i;
22+
right = i+1;
23+
24+
while (left >= 0 && right < s.length()) {
25+
if (s.charAt(left) != s.charAt(right)) {
26+
break;
27+
}
28+
cnt++;
29+
left--;
30+
right++;
31+
}
32+
}
33+
34+
return cnt;
35+
}
36+
}

0 commit comments

Comments
 (0)