Skip to content

Commit 0ee39f3

Browse files
committed
weekly contest 310
1 parent 693b80c commit 0ee39f3

File tree

2 files changed

+239
-1
lines changed

2 files changed

+239
-1
lines changed

README.md

+2-1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ Record leetcode contest and ideas every week, and encourage yourself to think mo
44

55
leetcode url: <https://leetcode.cn/u/cctest/>
66

7+
* 🐑 [weekly contest 310](src/main/java/weekly/wk310.java) 排序、hash表 | 贪心 | 贪心、差分数组 | 线段树+区间最大值
78
* 🐼 [weekly contest 309](src/main/java/weekly/wk309.java) 数组 | DP/记忆化搜索 | 滑动窗口 | 双堆
89
* 🐷 [weekly contest 308](src/main/java/weekly/wk308.java) 排序+前缀和 | 栈 | 贪心 | 拓扑排序
910
* 🐻 [weekly contest 307](src/main/java/weekly/wk307.java) 贪心 | 贪心 | 图 | 堆
@@ -36,7 +37,7 @@ leetcode url: <https://leetcode.cn/u/cctest/>
3637
* 🐸 [biweekly contest 78](src/main/java/weekly/wkb78.java)
3738
* 🐯 [biweekly contest 77](src/main/java/weekly/wkb77.java)
3839

39-
🐽 🐮 🐗 🐵 🐒 🐴 🐎 🐫 🐑
40+
🐽 🐮 🐗 🐵 🐒 🐴 🐎 🐫
4041

4142

4243

src/main/java/weekly/wk310.java

+237
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,237 @@
1+
package weekly;
2+
3+
import tool.tool;
4+
5+
import java.util.Arrays;
6+
import java.util.PriorityQueue;
7+
8+
public class wk310 {
9+
10+
//ranking: 243 / 6081
11+
12+
13+
//简单题,排序+统计连续相等的数字数目
14+
//hash表也可以
15+
public int mostFrequentEven(int[] nums) {
16+
Arrays.sort(nums);
17+
int pre = nums[0];
18+
int count = 1;
19+
int ans = -1;
20+
int c = 0;
21+
for (int i = 1; i < nums.length; i++) {
22+
if (nums[i] == pre) {
23+
count++;
24+
} else {
25+
if (pre % 2 == 0 && count > c) {
26+
c = count;
27+
ans = pre;
28+
}
29+
pre = nums[i];
30+
count = 1;
31+
}
32+
}
33+
if (pre % 2 == 0 && count > c) {
34+
c = count;
35+
ans = pre;
36+
}
37+
return ans;
38+
}
39+
40+
41+
//贪心,统计次数,碰到一样大的就重新计数
42+
public int partitionString(String s) {
43+
int[] count = new int[26];
44+
int ans = 1;
45+
for (int i = 0; i < s.length(); i++) {
46+
char c = s.charAt(i);
47+
if (count[c - 'a'] > 0) {
48+
ans++;
49+
count = new int[26];
50+
}
51+
count[c - 'a']++;
52+
}
53+
return ans;
54+
}
55+
56+
57+
//贪心+排序
58+
//按照左区间+右区间从小到大排序
59+
//然后用最小堆记录,每次取最小的一个,若不满足就要加新的,满足就弹出并加新的
60+
//也可以差分数组
61+
public int minGroups(int[][] intervals) {
62+
Arrays.sort(intervals, (a, b) -> a[0] == b[0] ? a[1] - b[1] : a[0] - b[0]);
63+
64+
PriorityQueue<Integer> priorityQueue = new PriorityQueue<>();
65+
66+
for (int i = 0; i < intervals.length; i++) {
67+
if (priorityQueue.isEmpty() || priorityQueue.peek() < intervals[i][0]) {
68+
priorityQueue.poll();
69+
}
70+
priorityQueue.add(intervals[i][1]);
71+
}
72+
return priorityQueue.size();
73+
}
74+
75+
76+
//线段树优化, 区间查询最大值
77+
public int lengthOfLIS(int[] nums, int k) {
78+
if (nums.length == 0) return 0;
79+
int max = 0;
80+
for (int i = 0; i < nums.length; i++) {
81+
max = Math.max(max, nums[i]);
82+
}
83+
int[] arr = new int[max + 1];
84+
int ans=1;
85+
SegmentTree segmentTree = new SegmentTree(arr);
86+
for (int i = 0; i < nums.length; i++) {
87+
int left = Math.max(0, nums[i] - k);
88+
int right = Math.max(0, nums[i] - 1);
89+
int len = segmentTree.queryMax(left, right);
90+
segmentTree.modify(nums[i],len+1);
91+
ans=Math.max(ans,len+1);
92+
}
93+
return ans;
94+
}
95+
96+
public class SegmentTree {
97+
private SegmentTreeNode root;
98+
99+
public SegmentTree(int[] arr) {
100+
this.root = build(arr);
101+
}
102+
103+
public SegmentTreeNode getRoot() {
104+
return this.root;
105+
}
106+
107+
private SegmentTreeNode build(int[] arr) {
108+
if (arr == null || arr.length == 0) {
109+
return null;
110+
}
111+
112+
return buildHelpler(arr, 0, arr.length - 1);
113+
}
114+
115+
private SegmentTreeNode buildHelpler(int[] arr, int start, int end) {
116+
if (start > end) {
117+
return null;
118+
}
119+
120+
SegmentTreeNode root = new SegmentTreeNode(start, end);
121+
if (start == end) {
122+
root.min = arr[start];
123+
root.max = arr[start];
124+
root.sum = arr[start];
125+
return root;
126+
}
127+
128+
int mid = start + (end - start) / 2;
129+
root.left = buildHelpler(arr, start, mid);
130+
root.right = buildHelpler(arr, mid + 1, end);
131+
root.min = Math.min(root.left.min, root.right.min);
132+
root.max = Math.max(root.left.max, root.right.max);
133+
root.sum = root.left.sum + root.right.sum;
134+
return root;
135+
}
136+
public int queryMax(int start, int end) {
137+
return queryMax(this.root, start, end);
138+
}
139+
140+
public int queryMax(SegmentTreeNode root, int start, int end) {
141+
if (root == null) {
142+
return 0;
143+
}
144+
145+
// case 1: search range is same with the range of root node
146+
if (root.start == start && root.end == end) {
147+
return root.max;
148+
}
149+
150+
int mid = root.start + (root.end - root.start) / 2;
151+
if (end <= mid) {
152+
// case 2: search range is in the range of left child node
153+
return queryMax(root.left, start, end);
154+
} else if (start > mid) {
155+
// case 3: search range is in the range of right child node
156+
return queryMax(root.right, start, end);
157+
} else {
158+
//case 4: search range crosses both left and right children
159+
int leftmax = queryMax(root.left, start, mid);
160+
int rightmax = queryMax(root.right, mid + 1, end);
161+
return Math.max(leftmax, rightmax);
162+
}
163+
}
164+
165+
public int queryMin(int start, int end) {
166+
return queryMin(this.root, start, end);
167+
}
168+
169+
private int queryMin(SegmentTreeNode root, int start, int end) {
170+
if (root == null) {
171+
return 0;
172+
}
173+
174+
// case 1: search range is same with the range of root node
175+
if (root.start == start && root.end == end) {
176+
return root.min;
177+
}
178+
179+
int mid = root.start + (root.end - root.start) / 2;
180+
if (end <= mid) {
181+
// case 2: search range is in the range of left child node
182+
return queryMin(root.left, start, end);
183+
} else if (start > mid) {
184+
// case 3: search range is in the range of right child node
185+
return queryMin(root.right, start, end);
186+
} else {
187+
//case 4: search range crosses both left and right children
188+
int leftmin = queryMin(root.left, start, mid);
189+
int rightmin = queryMin(root.right, mid + 1, end);
190+
return Math.min(leftmin, rightmin);
191+
}
192+
}
193+
194+
public void modify(int index, int value) {
195+
modify(this.root, index, value);
196+
}
197+
198+
private void modify(SegmentTreeNode root, int index, int value) {
199+
if (root == null) {
200+
return;
201+
}
202+
203+
if (root.start == root.end && root.start == index) {
204+
root.min = value;
205+
root.max = value;
206+
root.sum = value;
207+
return;
208+
}
209+
210+
int mid = root.start + (root.end - root.start) / 2;
211+
if (index <= mid) {
212+
modify(root.left, index, value);
213+
} else {
214+
modify(root.right, index, value);
215+
}
216+
217+
root.min = Math.min(root.left.min, root.right.min);
218+
root.max = Math.max(root.left.max, root.right.max);
219+
root.sum = root.left.sum + root.right.sum;
220+
}
221+
222+
public class SegmentTreeNode {
223+
public int start, end;
224+
public int max, min, sum; // You can add additional attributes
225+
public SegmentTreeNode left, right;
226+
227+
public SegmentTreeNode(int start, int end) {
228+
this.start = start;
229+
this.end = end;
230+
this.left = null;
231+
this.right = null;
232+
}
233+
}
234+
}
235+
236+
237+
}

0 commit comments

Comments
 (0)