Skip to content

Commit bf4c802

Browse files
committed
feeat : Week 9
1 parent 260d1cd commit bf4c802

File tree

5 files changed

+236
-0
lines changed

5 files changed

+236
-0
lines changed
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// 정렬을 하고하면 O(nlogn)이 나온다.
2+
// 정렬이 되어있다 가정할 수 있으니 배열을 모두 탐색해서 편차가 가장 큰걸 찾으면 O(n)
3+
// 위 두 방법은 속도가 너무 느리게 나와서 다른 방법을 찾아보니
4+
// 가장 빠른 방법은 최소값만 찾으면 되니 이진 탐색으로 찾으면 O(logn)
5+
class Solution {
6+
public int findMin(int[] nums) {
7+
int left = 0, right = nums.length - 1;
8+
9+
while (left < right) {
10+
int mid = left + (right - left) / 2; // 중간 인덱스
11+
12+
if (nums[mid] > nums[right]) {
13+
left = mid + 1;
14+
} else {
15+
right = mid;
16+
}
17+
}
18+
19+
return nums[left];
20+
}
21+
}

linked-list-cycle/imsosleepy.java

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
// 단순 루프 방식이 너무 오래걸려서 다른 방식을 찾아봄
2+
public class Solution {
3+
public boolean hasCycle(ListNode head) {
4+
HashSet<ListNode> visited = new HashSet<>();
5+
while (head != null) {
6+
if (visited.contains(head)) {
7+
return true; // 사이클 존재
8+
}
9+
visited.add(head);
10+
head = head.next;
11+
}
12+
return false; // 사이클 없음
13+
}
14+
}
15+
16+
// 투포인터로 해결
17+
public class Solution {
18+
public boolean hasCycle(ListNode head) {
19+
if (head == null || head.next == null) return false;
20+
21+
ListNode slow = head;
22+
ListNode fast = head;
23+
24+
while (fast != null && fast.next != null) {
25+
slow = slow.next; // 한 칸 이동
26+
fast = fast.next.next; // 두 칸 이동
27+
28+
if (slow == fast) {
29+
return true; // 사이클 존재
30+
}
31+
}
32+
return false; // 사이클 없음
33+
}
34+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
// dp인건 부분 배열 문제인걸 확인하고 바로 알아차림
2+
// 그런데 음수일때를 고려못해서 한참헤멤. 2번째 예제가 음수가 있을 수 있음을 알려주는 거였따...
3+
class Solution {
4+
public int maxProduct(int[] nums) {
5+
int n = nums.length;
6+
int[] maxProd = new int[n];
7+
int[] minProd = new int[n];
8+
9+
maxProd[0] = nums[0];
10+
minProd[0] = nums[0]; // 음수일 경우를 대비
11+
int result = nums[0];
12+
13+
for (int i = 1; i < n; i++) {
14+
maxProd[i] = Math.max(nums[i], Math.max(nums[i] * maxProd[i - 1], nums[i] * minProd[i - 1]));
15+
minProd[i] = Math.min(nums[i], Math.min(nums[i] * maxProd[i - 1], nums[i] * minProd[i - 1]));
16+
17+
result = Math.max(result, maxProd[i]);
18+
}
19+
20+
return result;
21+
}
22+
}
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
// DP라 생각하고 시간을 너무 많이써서 GPT에게 물어보니 아예 접근 자체를 잘못함
2+
// 다시 생각해봐야할듯
3+
class Solution {
4+
public String minWindow(String s, String t) {
5+
if (s == null || s.length() == 0 || t == null || t.length() == 0) return "";
6+
7+
// 1️⃣ t의 문자 개수를 카운트해서 저장
8+
Map<Character, Integer> tCount = new HashMap<>();
9+
for (char c : t.toCharArray()) {
10+
tCount.put(c, tCount.getOrDefault(c, 0) + 1);
11+
}
12+
int required = tCount.size(); // 필요한 고유 문자 개수
13+
14+
// 2️⃣ 슬라이딩 윈도우 변수 초기화
15+
int left = 0, right = 0; // 윈도우 포인터
16+
int formed = 0; // t의 문자 개수를 만족하는 개수
17+
Map<Character, Integer> windowCounts = new HashMap<>();
18+
19+
int minLength = Integer.MAX_VALUE;
20+
int startIdx = 0;
21+
22+
// 3️⃣ 슬라이딩 윈도우 확장
23+
while (right < s.length()) {
24+
char c = s.charAt(right);
25+
windowCounts.put(c, windowCounts.getOrDefault(c, 0) + 1);
26+
27+
if (tCount.containsKey(c) && windowCounts.get(c).intValue() == tCount.get(c).intValue()) {
28+
formed++;
29+
}
30+
31+
// 4️⃣ 모든 문자가 포함되었을 때, 윈도우 크기를 줄이면서 최소 길이 찾기
32+
while (left <= right && formed == required) {
33+
char leftChar = s.charAt(left);
34+
35+
// 최소 길이 갱신
36+
if (right - left + 1 < minLength) {
37+
minLength = right - left + 1;
38+
startIdx = left;
39+
}
40+
41+
// 윈도우 크기를 줄이기 위해 left 이동
42+
windowCounts.put(leftChar, windowCounts.get(leftChar) - 1);
43+
if (tCount.containsKey(leftChar) && windowCounts.get(leftChar) < tCount.get(leftChar)) {
44+
formed--;
45+
}
46+
47+
left++;
48+
}
49+
50+
right++;
51+
}
52+
53+
// 5️⃣ 결과 반환
54+
return (minLength == Integer.MAX_VALUE) ? "" : s.substring(startIdx, startIdx + minLength);
55+
}
56+
}
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
// 개인적으로 행렬에서 전파되는 방식은 BFS를 이용한 구현 방식을 선호한다.
2+
// 최적의 실행시간이 나오지 않는 것 같아서 DFS로 선회
3+
class Solution {
4+
private int[][] directions = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}};
5+
private int m, n;
6+
7+
public List<List<Integer>> pacificAtlantic(int[][] heights) {
8+
m = heights.length;
9+
n = heights[0].length;
10+
11+
boolean[][] pacific = new boolean[m][n];
12+
boolean[][] atlantic = new boolean[m][n];
13+
List<List<Integer>> result = new ArrayList<>();
14+
15+
16+
for (int i = 0; i < m; i++) {
17+
dfs(heights, pacific, i, 0);
18+
dfs(heights, atlantic, i, n - 1);
19+
}
20+
for (int j = 0; j < n; j++) {
21+
dfs(heights, pacific, 0, j);
22+
dfs(heights, atlantic, m - 1, j);
23+
}
24+
25+
for (int i = 0; i < m; i++) {
26+
for (int j = 0; j < n; j++) {
27+
if (pacific[i][j] && atlantic[i][j]) {
28+
result.add(Arrays.asList(i, j));
29+
}
30+
}
31+
}
32+
33+
return result;
34+
}
35+
36+
private void dfs(int[][] heights, boolean[][] visited, int x, int y) {
37+
visited[x][y] = true;
38+
for (int[] dir : directions) {
39+
int newX = x + dir[0], newY = y + dir[1];
40+
if (newX >= 0 && newX < m && newY >= 0 && newY < n && !visited[newX][newY] && heights[newX][newY] >= heights[x][y]) {
41+
dfs(heights, visited, newX, newY);
42+
}
43+
}
44+
}
45+
}
46+
47+
class Solution {
48+
private int[][] directions = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}};
49+
private int m, n;
50+
51+
public List<List<Integer>> pacificAtlantic(int[][] heights) {
52+
m = heights.length;
53+
n = heights[0].length;
54+
55+
boolean[][] pacific = new boolean[m][n];
56+
boolean[][] atlantic = new boolean[m][n];
57+
List<List<Integer>> result = new ArrayList<>();
58+
59+
Queue<int[]> pacificQueue = new LinkedList<>();
60+
Queue<int[]> atlanticQueue = new LinkedList<>();
61+
62+
for (int i = 0; i < m; i++) {
63+
pacificQueue.offer(new int[]{i, 0});
64+
atlanticQueue.offer(new int[]{i, n - 1});
65+
pacific[i][0] = true;
66+
atlantic[i][n - 1] = true;
67+
}
68+
for (int j = 0; j < n; j++) {
69+
pacificQueue.offer(new int[]{0, j});
70+
atlanticQueue.offer(new int[]{m - 1, j});
71+
pacific[0][j] = true;
72+
atlantic[m - 1][j] = true;
73+
}
74+
75+
bfs(heights, pacificQueue, pacific);
76+
bfs(heights, atlanticQueue, atlantic);
77+
78+
for (int i = 0; i < m; i++) {
79+
for (int j = 0; j < n; j++) {
80+
if (pacific[i][j] && atlantic[i][j]) {
81+
result.add(Arrays.asList(i, j));
82+
}
83+
}
84+
}
85+
86+
return result;
87+
}
88+
89+
private void bfs(int[][] heights, Queue<int[]> queue, boolean[][] visited) {
90+
while (!queue.isEmpty()) {
91+
int[] cell = queue.poll();
92+
int x = cell[0], y = cell[1];
93+
94+
for (int[] dir : directions) {
95+
int newX = x + dir[0], newY = y + dir[1];
96+
if (newX >= 0 && newX < m && newY >= 0 && newY < n && !visited[newX][newY] && heights[newX][newY] >= heights[x][y]) {
97+
queue.offer(new int[]{newX, newY});
98+
visited[newX][newY] = true;
99+
}
100+
}
101+
}
102+
}
103+
}

0 commit comments

Comments
 (0)