Skip to content

Commit 3391b60

Browse files
committed
modify on class
1 parent 3780d3e commit 3391b60

File tree

4 files changed

+290
-10
lines changed

4 files changed

+290
-10
lines changed
Lines changed: 259 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,259 @@
1+
package followup;
2+
3+
import java.util.ArrayList;
4+
5+
public class AddRemoveGetIndexGreat {
6+
7+
public static class SBTNode<V> {
8+
public V value;
9+
public SBTNode<V> l;
10+
public SBTNode<V> r;
11+
public int size;
12+
13+
public SBTNode(V v) {
14+
value = v;
15+
size = 1;
16+
}
17+
}
18+
19+
public static class SbtList<V> {
20+
private SBTNode<V> root;
21+
22+
private SBTNode<V> rightRotate(SBTNode<V> cur) {
23+
SBTNode<V> leftNode = cur.l;
24+
cur.l = leftNode.r;
25+
leftNode.r = cur;
26+
leftNode.size = cur.size;
27+
cur.size = (cur.l != null ? cur.l.size : 0) + (cur.r != null ? cur.r.size : 0) + 1;
28+
return leftNode;
29+
}
30+
31+
private SBTNode<V> leftRotate(SBTNode<V> cur) {
32+
SBTNode<V> rightNode = cur.r;
33+
cur.r = rightNode.l;
34+
rightNode.l = cur;
35+
rightNode.size = cur.size;
36+
cur.size = (cur.l != null ? cur.l.size : 0) + (cur.r != null ? cur.r.size : 0) + 1;
37+
return rightNode;
38+
}
39+
40+
private SBTNode<V> maintain(SBTNode<V> cur) {
41+
if (cur == null) {
42+
return null;
43+
}
44+
int leftSize = cur.l != null ? cur.l.size : 0;
45+
int leftLeftSize = cur.l != null && cur.l.l != null ? cur.l.l.size : 0;
46+
int leftRightSize = cur.l != null && cur.l.r != null ? cur.l.r.size : 0;
47+
int rightSize = cur.r != null ? cur.r.size : 0;
48+
int rightLeftSize = cur.r != null && cur.r.l != null ? cur.r.l.size : 0;
49+
int rightRightSize = cur.r != null && cur.r.r != null ? cur.r.r.size : 0;
50+
if (leftLeftSize > rightSize) {
51+
cur = rightRotate(cur);
52+
cur.r = maintain(cur.r);
53+
cur = maintain(cur);
54+
} else if (leftRightSize > rightSize) {
55+
cur.l = leftRotate(cur.l);
56+
cur = rightRotate(cur);
57+
cur.l = maintain(cur.l);
58+
cur.r = maintain(cur.r);
59+
cur = maintain(cur);
60+
} else if (rightRightSize > leftSize) {
61+
cur = leftRotate(cur);
62+
cur.l = maintain(cur.l);
63+
cur = maintain(cur);
64+
} else if (rightLeftSize > leftSize) {
65+
cur.r = rightRotate(cur.r);
66+
cur = leftRotate(cur);
67+
cur.l = maintain(cur.l);
68+
cur.r = maintain(cur.r);
69+
cur = maintain(cur);
70+
}
71+
return cur;
72+
}
73+
74+
private SBTNode<V> add(SBTNode<V> root, int index, SBTNode<V> cur) {
75+
if (root == null) {
76+
return cur;
77+
}
78+
root.size++;
79+
int leftAndHeadSize = (root.l != null ? root.l.size : 0) + 1;
80+
if (index < leftAndHeadSize) {
81+
root.l = add(root.l, index, cur);
82+
} else {
83+
root.r = add(root.r, index - leftAndHeadSize, cur);
84+
}
85+
root = maintain(root);
86+
return root;
87+
}
88+
89+
private SBTNode<V> remove(SBTNode<V> root, int index) {
90+
root.size--;
91+
int rootIndex = root.l != null ? root.l.size : 0;
92+
if (index != rootIndex) {
93+
if (index < rootIndex) {
94+
root.l = remove(root.l, index);
95+
} else {
96+
root.r = remove(root.r, index - rootIndex - 1);
97+
}
98+
return root;
99+
}
100+
if (root.l == null && root.r == null) {
101+
return null;
102+
}
103+
if (root.l == null) {
104+
return root.r;
105+
}
106+
if (root.r == null) {
107+
return root.l;
108+
}
109+
SBTNode<V> pre = null;
110+
SBTNode<V> suc = root.r;
111+
suc.size--;
112+
while (suc.l != null) {
113+
pre = suc;
114+
suc = suc.l;
115+
suc.size--;
116+
}
117+
if (pre != null) {
118+
pre.l = suc.r;
119+
suc.r = root.r;
120+
}
121+
suc.l = root.l;
122+
suc.size = suc.l.size + (suc.r == null ? 0 : suc.r.size) + 1;
123+
return suc;
124+
}
125+
126+
private SBTNode<V> get(SBTNode<V> root, int index) {
127+
int leftSize = root.l != null ? root.l.size : 0;
128+
if (index < leftSize) {
129+
return get(root.l, index);
130+
} else if (index == leftSize) {
131+
return root;
132+
} else {
133+
return get(root.r, index - leftSize - 1);
134+
}
135+
}
136+
137+
public void add(int index, V num) {
138+
SBTNode<V> cur = new SBTNode<V>(num);
139+
if (root == null) {
140+
root = cur;
141+
} else {
142+
if (index <= root.size) {
143+
root = add(root, index, cur);
144+
}
145+
}
146+
}
147+
148+
public V get(int index) {
149+
SBTNode<V> ans = get(root, index);
150+
return ans.value;
151+
}
152+
153+
public void remove(int index) {
154+
if (index >= 0 && size() > index) {
155+
root = remove(root, index);
156+
}
157+
}
158+
159+
public int size() {
160+
return root == null ? 0 : root.size;
161+
}
162+
163+
}
164+
165+
// 通过以下这个测试,
166+
// 可以很明显的看到LinkedList的插入、删除、get效率不如SbtList
167+
// LinkedList需要找到index所在的位置之后才能插入或者读取,时间复杂度O(N)
168+
// SbtList是平衡搜索二叉树,所以插入或者读取时间复杂度都是O(logN)
169+
public static void main(String[] args) {
170+
// 功能测试
171+
int test = 50000;
172+
int max = 1000000;
173+
boolean pass = true;
174+
ArrayList<Integer> list = new ArrayList<>();
175+
SbtList<Integer> sbtList = new SbtList<>();
176+
for (int i = 0; i < test; i++) {
177+
if (list.size() != sbtList.size()) {
178+
pass = false;
179+
break;
180+
}
181+
if (list.size() > 1 && Math.random() < 0.5) {
182+
int removeIndex = (int) (Math.random() * list.size());
183+
list.remove(removeIndex);
184+
sbtList.remove(removeIndex);
185+
} else {
186+
int randomIndex = (int) (Math.random() * (list.size() + 1));
187+
int randomValue = (int) (Math.random() * (max + 1));
188+
list.add(randomIndex, randomValue);
189+
sbtList.add(randomIndex, randomValue);
190+
}
191+
}
192+
for (int i = 0; i < list.size(); i++) {
193+
if (!list.get(i).equals(sbtList.get(i))) {
194+
pass = false;
195+
break;
196+
}
197+
}
198+
System.out.println("功能测试是否通过 : " + pass);
199+
200+
// 性能测试
201+
test = 500000;
202+
list = new ArrayList<>();
203+
sbtList = new SbtList<>();
204+
long start = 0;
205+
long end = 0;
206+
207+
start = System.currentTimeMillis();
208+
for (int i = 0; i < test; i++) {
209+
int randomIndex = (int) (Math.random() * (list.size() + 1));
210+
int randomValue = (int) (Math.random() * (max + 1));
211+
list.add(randomIndex, randomValue);
212+
}
213+
end = System.currentTimeMillis();
214+
System.out.println("ArrayList插入总时长(毫秒) : " + (end - start));
215+
216+
start = System.currentTimeMillis();
217+
for (int i = 0; i < test; i++) {
218+
int randomIndex = (int) (Math.random() * (i + 1));
219+
list.get(randomIndex);
220+
}
221+
end = System.currentTimeMillis();
222+
System.out.println("ArrayList读取总时长(毫秒) : " + (end - start));
223+
224+
start = System.currentTimeMillis();
225+
for (int i = 0; i < test; i++) {
226+
int randomIndex = (int) (Math.random() * list.size());
227+
list.remove(randomIndex);
228+
}
229+
end = System.currentTimeMillis();
230+
System.out.println("ArrayList删除总时长(毫秒) : " + (end - start));
231+
232+
start = System.currentTimeMillis();
233+
for (int i = 0; i < test; i++) {
234+
int randomIndex = (int) (Math.random() * (sbtList.size() + 1));
235+
int randomValue = (int) (Math.random() * (max + 1));
236+
sbtList.add(randomIndex, randomValue);
237+
}
238+
end = System.currentTimeMillis();
239+
System.out.println("SbtList插入总时长(毫秒) : " + (end - start));
240+
241+
start = System.currentTimeMillis();
242+
for (int i = 0; i < test; i++) {
243+
int randomIndex = (int) (Math.random() * (i + 1));
244+
sbtList.get(randomIndex);
245+
}
246+
end = System.currentTimeMillis();
247+
System.out.println("SbtList读取总时长(毫秒) : " + (end - start));
248+
249+
start = System.currentTimeMillis();
250+
for (int i = 0; i < test; i++) {
251+
int randomIndex = (int) (Math.random() * sbtList.size());
252+
sbtList.remove(randomIndex);
253+
}
254+
end = System.currentTimeMillis();
255+
System.out.println("SbtList删除总时长(毫秒) : " + (end - start));
256+
257+
}
258+
259+
}

src/topinterviewquestions/Problem_0121_BestTimeToBuyAndSellStock.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ public static int maxProfit(int[] prices) {
66
if (prices == null || prices.length == 0) {
77
return 0;
88
}
9+
// 0...i 最小值
910
int min = prices[0];
1011
int ans = 0;
1112
for (int i = 0; i < prices.length; i++) {

src/topinterviewquestions/Problem_0123_BestTimeToBuyAndSellStockIII.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,11 @@ public static int maxProfit(int[] prices) {
88
}
99
int ans = 0;
1010
int doneOnceMinusBuyMax = -prices[0];
11-
int doneOnceMax = 0;
11+
int doneOnceMax = 0;// 0 : [0] - [0]
1212
int min = prices[0];
1313
for (int i = 1; i < prices.length; i++) {
14-
min = Math.min(min, prices[i]);
1514
ans = Math.max(ans, doneOnceMinusBuyMax + prices[i]);
15+
min = Math.min(min, prices[i]);
1616
doneOnceMax = Math.max(doneOnceMax, prices[i] - min);
1717
doneOnceMinusBuyMax = Math.max(doneOnceMinusBuyMax, doneOnceMax - prices[i]);
1818
}

src/topinterviewquestions/Problem_0188_BestTimeToBuyAndSellStockIV.java

Lines changed: 28 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,27 @@
22

33
public class Problem_0188_BestTimeToBuyAndSellStockIV {
44

5-
public static int maxProfit(int K, int[] prices) {
5+
public static int maxProfit1(int K, int[] arr) {
6+
if (arr == null || arr.length == 0) {
7+
return 0;
8+
}
9+
int N = arr.length;
10+
if (K >= N / 2) {
11+
return allTrans(arr);
12+
}
13+
int[][] dp = new int[N][K + 1];
14+
for (int i = 1; i < N; i++) {
15+
for (int j = 1; j <= K; j++) {
16+
dp[i][j] = dp[i - 1][j];
17+
for (int p = 0; p <= i; p++) {
18+
dp[i][j] = Math.max(dp[p][j - 1] + arr[i] - arr[p], dp[i][j]);
19+
}
20+
}
21+
}
22+
return dp[N - 1][K];
23+
}
24+
25+
public static int maxProfit2(int K, int[] prices) {
626
if (prices == null || prices.length == 0) {
727
return 0;
828
}
@@ -12,14 +32,14 @@ public static int maxProfit(int K, int[] prices) {
1232
}
1333
int[][] dp = new int[K + 1][N];
1434
int ans = 0;
15-
for (int tran = 1; tran <= K; tran++) {
16-
int pre = dp[tran][0];
35+
for (int j = 1; j <= K; j++) {
36+
int pre = dp[j][0];
1737
int best = pre - prices[0];
18-
for (int index = 1; index < N; index++) {
19-
pre = dp[tran - 1][index];
20-
dp[tran][index] = Math.max(dp[tran][index - 1], prices[index] + best);
21-
best = Math.max(best, pre - prices[index]);
22-
ans = Math.max(dp[tran][index], ans);
38+
for (int i = 1; i < N; i++) {
39+
pre = dp[j - 1][i];
40+
dp[j][i] = Math.max(dp[j][i - 1], prices[i] + best);
41+
best = Math.max(best, pre - prices[i]);
42+
ans = Math.max(dp[j][i], ans);
2343
}
2444
}
2545
return ans;

0 commit comments

Comments
 (0)