Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 930012e

Browse files
committed
1918-2015-2021-2031-2036-2046-2052-2067-2077-2083-2093-2098-2107 (13)
1 parent 7e0a879 commit 930012e

27 files changed

+1026
-1
lines changed
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
import java.util.Arrays;
2+
3+
public class Solution1918 {
4+
public int kthSmallestSubarraySum(int[] nums, int k) {
5+
int mn = Arrays.stream(nums).min().orElseThrow();
6+
int sum = Arrays.stream(nums).sum();
7+
8+
int left = mn;
9+
int right = sum;
10+
while (left < right) {
11+
int mid = left + (right - left) / 2;
12+
// 边界二分 F, F,..., F, [T, T,..., T]
13+
// ----------------------^
14+
if (checkMid(nums, k, mid)) {
15+
right = mid;
16+
} else {
17+
left = mid + 1;
18+
}
19+
}
20+
return left;
21+
}
22+
23+
private boolean checkMid(int[] nums, int k, int threshold) {
24+
int tot = 0;
25+
int sum = 0;
26+
int l = 0, r = 0;
27+
while (r < nums.length) {
28+
sum += nums[r];
29+
while (sum > threshold) {
30+
sum -= nums[l];
31+
l++;
32+
}
33+
tot += r - l + 1;
34+
r++;
35+
}
36+
return tot >= k;
37+
}
38+
}
39+
/*
40+
1918ドル. 第 K 小的子数组和
41+
https://leetcode.cn/problems/kth-smallest-subarray-sum/description/
42+
43+
给你一个 长度为 n 的整型数组 nums 和一个数值 k ,返回 第 k 小的子数组和。
44+
子数组 是指数组中一个 非空 且不间断的子序列。 子数组和 则指子数组中所有元素的和。
45+
提示:
46+
n == nums.length
47+
1 <= n <= 2 * 10^4
48+
1 <= nums[i] <= 5 * 10^4
49+
1 <= k <= n * (n + 1) / 2
50+
51+
二分答案。
52+
时间复杂度 O(nlogS)。其中 S = sum(nums[i])。
53+
*/
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import org.junit.jupiter.api.Assertions;
2+
import org.junit.jupiter.api.Test;
3+
4+
public class Solution1918Tests {
5+
private final Solution1918 solution1918 = new Solution1918();
6+
7+
@Test
8+
public void example1() {
9+
int[] nums = {2, 1, 3};
10+
int k = 4;
11+
int expected = 3;
12+
Assertions.assertEquals(expected, solution1918.kthSmallestSubarraySum(nums, k));
13+
}
14+
15+
@Test
16+
public void example2() {
17+
int[] nums = {3, 3, 5, 5};
18+
int k = 7;
19+
int expected = 10;
20+
Assertions.assertEquals(expected, solution1918.kthSmallestSubarraySum(nums, k));
21+
}
22+
}
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
import java.util.ArrayList;
2+
import java.util.HashMap;
3+
import java.util.List;
4+
import java.util.Map;
5+
import java.util.TreeMap;
6+
7+
public class Solution2015 {
8+
// 2021
9+
public int[][] averageHeightOfBuildings(int[][] buildings) {
10+
TreeMap<Integer, Integer> diff = new TreeMap<>();
11+
Map<Integer, Integer> cnts = new HashMap<>();
12+
for (int[] p : buildings) {
13+
int st = p[0], end = p[1], hi = p[2];
14+
diff.merge(st, hi, Integer::sum);
15+
diff.merge(end, -hi, Integer::sum);
16+
cnts.merge(st, 1, Integer::sum);
17+
cnts.merge(end, -1, Integer::sum);
18+
}
19+
20+
int sumD = 0, cnt = 0;
21+
int last = 0, last_p = 0;
22+
List<int[]> ans = new ArrayList<>();
23+
for (Map.Entry<Integer, Integer> entry : diff.entrySet()) {
24+
int k = entry.getKey();
25+
sumD += entry.getValue();
26+
if (last != 0) {
27+
if (!ans.isEmpty() && ans.get(ans.size() - 1)[1] == last_p && ans.get(ans.size() - 1)[2] == last / cnt) {
28+
ans.get(ans.size() - 1)[1] = k;
29+
} else {
30+
ans.add(new int[]{last_p, k, last / cnt});
31+
}
32+
}
33+
cnt += cnts.get(k);
34+
last = sumD;
35+
last_p = k;
36+
}
37+
return ans.toArray(int[][]::new);
38+
}
39+
}
40+
/*
41+
2015ドル. 每段建筑物的平均高度
42+
https://leetcode.cn/problems/average-height-of-buildings-in-each-segment/description/
43+
44+
一条完全笔直的街道由一条数字线表示。街道上有建筑物,由二维整数阵列 buildings 表示,其中 buildings[i] = [starti, endi, heighti]。这意味着在 半封闭的位置[starti,endi) 有一座高度为 heighti 的建筑。
45+
你想用 最少 数量的非重叠 部分 来 描述 街道上建筑物的高度。街道可以用2D整数数组 street 来表示,其中 street[j] = [leftj, rightj, averagej] 描述了道路的 半封闭区域 [leftj, rightj) ,该段中建筑物的 平均 高度为 averagej 。
46+
- 例如,如果 buildings = [[1,5,2],[3,10,4]] , street = [[1,3,2],[3,5,3],[5,10,4]] 可以表示街道,因为:
47+
- 从 1 到 3 ,只有第一栋建筑的平均高度为 2 / 1 = 2 。
48+
- 从 3 到 5 ,第一和第二栋建筑的平均高度均为 (2+4) / 2 = 3 。
49+
- 从 5 到 10 ,只有第二栋建筑的平均高度为 4 / 1 = 4 。
50+
给定 buildings ,返回如上所述的二维整数矩阵 street ( 不包括 街道上没有建筑物的任何区域)。您可以按 任何顺序 返回数组。
51+
n 个元素的 平均值 是 n 个元素除以 n 的 总和 (整数除法)。
52+
半闭合段 [a, b) 是点 a 和 b 之间的数字线的截面,包括 点 a ,不包括 点 b 。
53+
提示:
54+
1 <= buildings.length <= 10^5
55+
buildings[i].length == 3
56+
0 <= starti < endi <= 10^8
57+
1 <= heighti <= 10^5
58+
59+
差分数组。
60+
相似题目: 2021ドル. 街上最亮的位置
61+
https://leetcode.cn/problems/brightest-position-on-street/description/
62+
*/
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
import java.util.Arrays;
2+
import java.util.HashSet;
3+
import java.util.Map;
4+
import java.util.Set;
5+
import java.util.TreeMap;
6+
7+
public class Solution2021 {
8+
// 146ms
9+
public int brightestPosition(int[][] lights) {
10+
TreeMap<Integer, Integer> diff = new TreeMap<>();
11+
for (int[] p : lights) {
12+
int l = p[0] - p[1], r = p[0] + p[1];
13+
diff.merge(l, 1, Integer::sum);
14+
diff.merge(r + 1, -1, Integer::sum);
15+
}
16+
int sumD = 0;
17+
int max = 0, ans = -1;
18+
for (Map.Entry<Integer, Integer> entry : diff.entrySet()) {
19+
int k = entry.getKey();
20+
sumD += entry.getValue();
21+
if (sumD > max) {
22+
max = sumD;
23+
ans = k;
24+
}
25+
}
26+
return ans;
27+
}
28+
29+
// 128ms
30+
public int brightestPosition2(int[][] lights) {
31+
// 离散化
32+
int[] yArr = getDiscrete(lights);
33+
34+
int[] diff = new int[yArr.length];
35+
for (int[] p : lights) {
36+
int l = getId(yArr, p[0] - p[1]);
37+
int r = getId(yArr, p[0] + p[1] + 1);
38+
diff[l]++;
39+
diff[r]--;
40+
}
41+
int sumD = 0;
42+
int max = 0, ans = -1;
43+
for (int i = 0; i < yArr.length; i++) {
44+
sumD += diff[i];
45+
if (sumD > max) {
46+
max = sumD;
47+
ans = yArr[i];
48+
}
49+
}
50+
return ans;
51+
}
52+
53+
// x:type=0, y:type=1
54+
private int[] getDiscrete(int[][] lights) {
55+
Set<Integer> set = new HashSet<>();
56+
for (int[] p : lights) {
57+
set.add(p[0] - p[1]);
58+
set.add(p[0] + p[1] + 1);
59+
}
60+
int sz = set.size();
61+
int[] arr = new int[sz];
62+
int id = 0;
63+
for (Integer x : set) arr[id++] = x;
64+
Arrays.sort(arr);
65+
return arr;
66+
}
67+
68+
private int getId(int[] arr, int x) {
69+
return Arrays.binarySearch(arr, x);
70+
}
71+
}
72+
/*
73+
2021ドル. 街上最亮的位置
74+
https://leetcode.cn/problems/brightest-position-on-street/description/
75+
76+
一条街上有很多的路灯,路灯的坐标由数组 lights 的形式给出。 每个 lights[i] = [positioni, rangei] 代表坐标为 positioni 的路灯照亮的范围为 [positioni - rangei, positioni + rangei] (包括顶点)。
77+
位置 p 的亮度由能够照到 p的路灯的数量来决定的。
78+
给出 lights, 返回最亮的位置 。如果有很多,返回坐标最小的。
79+
提示:
80+
1 <= lights.length <= 10^5
81+
lights[i].length == 2
82+
-10^8 <= positioni <= 10^8
83+
0 <= rangei <= 10^8
84+
85+
差分数组。
86+
时间复杂度 O(nlogn)。
87+
相似题目: 2015ドル. 每段建筑物的平均高度
88+
https://leetcode.cn/problems/average-height-of-buildings-in-each-segment/description/
89+
*/
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import java.util.HashMap;
2+
import java.util.Map;
3+
4+
public class Solution2031 {
5+
private static final int MOD = (int) (1e9 + 7);
6+
7+
// 将 0 用 -1 替代, s[i] 表示 nums[0, i] 的和
8+
// 若 nums[i] = 0, 则 s[i] = s[i-1]-1, cnt -= mp[s[i]]
9+
// 若 nums[i] = 1, 则 s[i] = s[i-1]+1, cnt += mp[s[i-1]]
10+
public int subarraysWithMoreZerosThanOnes(int[] nums) {
11+
int n = nums.length;
12+
Map<Integer, Integer> mp = new HashMap<>();
13+
mp.put(n, 1);
14+
int s = n;
15+
long ans = 0, cnt = 0;
16+
for (int v : nums) {
17+
if (v == 1) cnt += mp.getOrDefault(s++, 0);
18+
else cnt -= mp.getOrDefault(--s, 0);
19+
mp.merge(s, 1, Integer::sum);
20+
ans = (ans + cnt) % MOD;
21+
}
22+
return (int) ans;
23+
}
24+
}
25+
/*
26+
2031ドル. 1 比 0 多的子数组个数
27+
https://leetcode.cn/problems/count-subarrays-with-more-ones-than-zeros/description/
28+
29+
给你一个只包含 0 和 1 的数组 nums,请返回 1 的数量 大于 0 的数量的子数组的个数。由于答案可能很大,请返回答案对 109 + 7 取余 的结果。
30+
一个 子数组 指的是原数组中连续的一个子序列。
31+
提示:
32+
1 <= nums.length <= 10^5
33+
0 <= nums[i] <= 1
34+
35+
前缀和。
36+
时间复杂度 O(n)。
37+
*/
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
public class Solution2036 {
2+
public long maximumAlternatingSubarraySum(int[] nums) {
3+
int n = nums.length;
4+
// f[i][0] 表示以 i 结尾的子数组最后操作为 - 的结果
5+
// f[i][1] 表示以 i 结尾的子数组最后操作为 + 的结果
6+
long[][] f = new long[n][2];
7+
f[0][1] = nums[0];
8+
f[0][0] = 0;
9+
long ans = nums[0];
10+
for (int i = 1; i < n; i++) {
11+
f[i][0] = f[i - 1][1] - nums[i];
12+
f[i][1] = Math.max(f[i - 1][0] + nums[i], nums[i]);
13+
ans = Math.max(ans, Math.max(f[i][0], f[i][1]));
14+
}
15+
return ans;
16+
}
17+
}
18+
/*
19+
2036ドル. 最大交替子数组和
20+
https://leetcode.cn/problems/maximum-alternating-subarray-sum/description/
21+
22+
子数组是以0下标开始的数组的连续非空子序列,从 i 到 j(0 <= i <= j < nums.length)的 子数组交替和 被定义为 nums[i] - nums[i+1] + nums[i+2] - ... +/- nums[j] 。
23+
给定一个以0下标开始的整数数组nums,返回它所有可能的交替子数组和的最大值。
24+
提示:
25+
1 <= nums.length <= 10^5
26+
-10^5 <= nums[i] <= 10^5
27+
28+
动态规划。
29+
时间复杂度 O(n)。
30+
*/
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import java.util.ArrayList;
2+
import java.util.List;
3+
4+
public class Solution2046 {
5+
public ListNode sortLinkedList(ListNode head) {
6+
List<Integer> list = new ArrayList<>();
7+
while (head != null) {
8+
list.add(head.val);
9+
head = head.next;
10+
}
11+
list.sort(null);
12+
13+
ListNode dummy = new ListNode(-1);
14+
ListNode h0 = dummy;
15+
for (int num : list) {
16+
h0.next = new ListNode(num);
17+
h0 = h0.next;
18+
}
19+
return dummy.next;
20+
}
21+
}
22+
/*
23+
2046ドル. 给按照绝对值排序的链表排序
24+
https://leetcode.cn/problems/sort-linked-list-already-sorted-using-absolute-values/description/
25+
26+
给你一个链表的头结点 head ,这个链表是根据结点的绝对值进行升序排序, 返回重新根据节点的值进行升序排序的链表。
27+
提示:
28+
链表节点数的范围是 [1, 10^5].
29+
-5000 <= Node.val <= 5000
30+
head 是根据结点绝对值升序排列好的链表.
31+
进阶:
32+
你可以在O(n)的时间复杂度之内解决这个问题吗?
33+
34+
数组
35+
时间复杂度 O(nlogn)。
36+
*/
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
import java.util.Arrays;
2+
3+
public class Solution2052 {
4+
private int k, n;
5+
private int[] ps, memo;
6+
7+
public int minimumCost(String sentence, int k) {
8+
this.k = k;
9+
String[] sp = sentence.split(" ");
10+
n = sp.length;
11+
ps = new int[n + 1];
12+
for (int i = 0; i < n; i++) {
13+
ps[i + 1] = ps[i] + sp[i].length();
14+
}
15+
16+
memo = new int[n];
17+
Arrays.fill(memo, -1);
18+
return dfs(0);
19+
}
20+
21+
private int dfs(int i) {
22+
if (ps[n] - ps[i] + n - 1 - i <= k) return 0;
23+
if (memo[i] != -1) return memo[i];
24+
int res = Integer.MAX_VALUE;
25+
for (int j = i + 1; j < n && ps[j] - ps[i] + j - 1 - i <= k; j++) {
26+
int nxt = ps[j] - ps[i] + j - 1 - i;
27+
res = Math.min(res, (k - nxt) * (k - nxt) + dfs(j));
28+
}
29+
return memo[i] = res;
30+
}
31+
}
32+
/*
33+
2052ドル. 将句子分隔成行的最低成本
34+
https://leetcode.cn/problems/minimum-cost-to-separate-sentence-into-rows/description/
35+
36+
给定一个由空格分隔的单词组成的字符串 sentence 和一个整数 k。你的任务是将 sentence 分成多行,每行中的字符数最多为 k。你可以假设 sentence 不以空格开头或结尾,并且 sentence 中的单词由单个空格分隔。
37+
你可以通过在 sentence 中的单词间插入换行来分隔 sentence 。一个单词不能被分成两行。每个单词只能使用一次,并且单词顺序不能重排。同一行中的相邻单词应该由单个空格分隔,并且每行都不应该以空格开头或结尾。
38+
一行长度为 n 的字符串的分隔成本是 (k - n)^2 ,总成本就是除开最后一行以外的其它所有行的分隔成本之和。
39+
- 以 sentence = "i love leetcode" 和k = 12为例:
40+
- 将sentence 分成 "i", "love", 和"leetcode" 的成本为 (12 - 1)^2 + (12 - 4)^2 = 185。
41+
- 将sentence 分成 "i love", 和"leetcode" 的成本为 (12 - 6)^2 = 36。
42+
- 将sentence 分成 "i", 和"love leetcode" 是不可能的,因为 "love leetcode" 的长度大于 k。
43+
返回将sentence分隔成行的最低的可能总成本。
44+
提示:
45+
1 <= sentence.length <= 5000
46+
1 <= k <= 5000
47+
sentence 中每个单词长度最大为 k.
48+
sentence 只包含小写字母和空格.
49+
sentence 不会以空格开头或结尾.
50+
sentence 中的单词以单个空格分隔.
51+
52+
记忆化搜索。
53+
时间复杂度 O(n^2)。
54+
*/

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /