Skip to content

Commit 87ce663

Browse files
authored
Merge pull request #994 from forest000014/main
[forest000014] Week 09
2 parents fb89135 + 7eac78a commit 87ce663

File tree

4 files changed

+157
-1
lines changed

4 files changed

+157
-1
lines changed

clone-graph/forest000014.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ public void dfs(Node oldNode) {
7070
Node newNeighbor = createNode(oldNeighbor.val);
7171
newNode.neighbors.add(newNeighbor);
7272
newNeighbor.neighbors.add(newNode);
73-
dfs(oldNeighbor, newNeighbor);
73+
dfs(oldNeighbor);
7474
}
7575
}
7676
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
/*
2+
# Time Complexity: O(logn)
3+
# Space Complexity: O(1)
4+
5+
binary search를 사용해 접근했습니다.
6+
sorted array인 경우는 while문 시작 전, 예외 체크를 했습니다.
7+
binary search를 진행하면, 각각의 loop의 mid 원소는 아래 4가지 경우 중 하나입니다.
8+
maximum / minimum / 앞쪽 수열의 원소 중 하나 / 뒤쪽 수열의 원소 중 하나
9+
maximum이거나 minimum인 경우는 더 이상 탐색할 필요 없이 종료합니다.
10+
앞쪽 수열인 경우, 우리가 원하는 minimum은 왼쪽에는 없으므로, left 포인터를 mid의 오른쪽으로 옮기고 다음 loop를 진행하고,
11+
뒤쪽 수열인 경우, 우리가 원하는 minimum은 오른쪽에는 없으므로, rigth 포인터를 mid의 왼쪽으로 옮기고 다음 loop를 진행합니다.
12+
13+
*/
14+
class Solution {
15+
public int findMin(int[] nums) {
16+
int l = 0;
17+
int r = nums.length - 1;
18+
19+
if (nums[l] <= nums[r]) { // sorted array인 경우 (size가 1인 경우도 포함)
20+
return nums[l];
21+
}
22+
23+
while (l <= r) {
24+
int m = (r - l) / 2 + l; // 만약 문제 조건상 l, r의 합이 int 범위를 넘어가서 overflow가 생길 수 있는 경우에, 이런 식으로 overflow를 방지할 수 있다고 알고 있습니다. 이 문제는 overflow 걱정은 없지만, 나중에 실전에서 나오면 잊지 않으려고 이렇게 구현해보았습니다.
25+
if (m > 0 && nums[m - 1] > nums[m]) {
26+
return nums[m];
27+
} else if (m < nums.length - 1 && nums[m] > nums[m + 1]) {
28+
return nums[m + 1];
29+
} else if (nums[m] > nums[l]) {
30+
l = m + 1;
31+
} else {
32+
r = m - 1;
33+
}
34+
}
35+
36+
return -1;
37+
}
38+
}

linked-list-cycle/forest000014.java

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
/**
2+
# Time Complexity : O(n)
3+
# Space Complexity: O(1)
4+
5+
* Definition for singly-linked list.
6+
* class ListNode {
7+
* int val;
8+
* ListNode next;
9+
* ListNode(int x) {
10+
* val = x;
11+
* next = null;
12+
* }
13+
* }
14+
*/
15+
public class Solution {
16+
private final int VISITED = -999999;
17+
public boolean hasCycle(ListNode head) {
18+
while (head != null) {
19+
if (head.val == VISITED) {
20+
return true;
21+
}
22+
23+
head.val = VISITED;
24+
head = head.next;
25+
}
26+
27+
return false;
28+
}
29+
}
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
/*
2+
# Time Complexity: O(n)
3+
4+
# Space Complexity: O(1)
5+
6+
# Solution
7+
1. array에 0이 존재하는 경우
8+
9+
(observation: 정답이 음수가 될 가능성이 있는가? Yes. 다만, 원소 개수가 1개이고, 그 원소가 음수인 경우에만 그렇다. 음수인 원소가 2개 이상인 경우는 subarray를 잘 선택하면 그 곱을 항상 0 이상으로 만들 수 있다. 즉, 원소 개수가 1개이고 음수인 경우만 예외 처리를 해주면, 그 외의 경우는 정답이 0이거나 양수이다.)
10+
11+
subarray에 0이 포함되는 순간 곱은 0이 되므로, 0보다 큰 곱을 찾기 위해서는 0을 제외하고 판단한다.
12+
즉, 0을 기준으로 slice해서, 각각의 segment만 독립적으로 검토하면 된다. (0으로 slice한 각 segment가 아래 2번 케이스로 환원된다.)
13+
14+
2. (sub)array에 0이 존재하지 않는 경우
15+
음수의 개수에 따라 접근을 다르게 한다.
16+
17+
2-1. 짝수개
18+
고민할 것 없이, 전체 subarray의 원소를 곱하면 그 subarray에서 얻을 수 있는 곱의 최대값이다.
19+
20+
2-2. 홀수개
21+
subarray 양 끝에서 각각 출발하여 최초의 마이너스(즉 가장 바깥쪽의 마이너스)를 만날 때까지, 원소들을 누적해서 곱하며 이동.
22+
두 값 중 절대값이 작은 쪽을 subarray에서 제외. 남은 부분의 곱을 구하면, 최대값이다.
23+
*/
24+
25+
class Solution {
26+
public int maxProduct(int[] nums) {
27+
if (nums.length == 1) {
28+
return nums[0];
29+
}
30+
31+
int ans = 0;
32+
int start = 0;
33+
for (int i = 0; i < nums.length; i++) {
34+
if (nums[i] != 0) {
35+
continue;
36+
}
37+
38+
if (i > 0) {
39+
int res = calculateMaxProduct(start, i - 1, nums);
40+
ans = Math.max(ans, res);
41+
}
42+
start = i + 1;
43+
}
44+
45+
if (start <= nums.length - 1) {
46+
int res = calculateMaxProduct(start, nums.length - 1, nums);
47+
ans = Math.max(ans, res);
48+
}
49+
50+
return ans;
51+
}
52+
53+
private int calculateMaxProduct(int l, int r, int[] nums) {
54+
if (l == r) {
55+
return nums[l];
56+
}
57+
58+
int minusCount = 0;
59+
int product = 1;
60+
for (int i = l; i <= r; i++) {
61+
if (nums[i] < 0) {
62+
minusCount++;
63+
}
64+
product *= nums[i];
65+
}
66+
67+
if (minusCount % 2 == 0) {
68+
return product;
69+
} else {
70+
int leftProduct = 1;
71+
for (int i = l; i <= r; i++) {
72+
leftProduct *= nums[i];
73+
if (nums[i] < 0) {
74+
break;
75+
}
76+
}
77+
78+
int rightProduct = 1;
79+
for (int i = r; i >= l; i--) {
80+
rightProduct *= nums[i];
81+
if (nums[i] < 0) {
82+
break;
83+
}
84+
}
85+
86+
return product / Math.max(leftProduct, rightProduct);
87+
}
88+
}
89+
}

0 commit comments

Comments
 (0)