kk
This commit is contained in:
55
src/main/java/com/dota/binarySearch/_2071/Solution.java
Normal file
55
src/main/java/com/dota/binarySearch/_2071/Solution.java
Normal file
@@ -0,0 +1,55 @@
|
||||
package com.dota.binarySearch._2071;
|
||||
|
||||
import java.util.ArrayDeque;
|
||||
import java.util.Arrays;
|
||||
import java.util.Deque;
|
||||
|
||||
class Solution {
|
||||
public static void main(String[] args) {
|
||||
new Solution().maxTaskAssign(new int[]{15, 10, 30}, new int[]{10, 10, 10}, 3, 10);
|
||||
}
|
||||
|
||||
public int maxTaskAssign(int[] tasks, int[] workers, int pills, int strength) {
|
||||
Arrays.sort(tasks);
|
||||
Arrays.sort(workers);
|
||||
|
||||
int left = 0;
|
||||
int right = Math.min(tasks.length, workers.length) + 1;
|
||||
while (left + 1 < right) {
|
||||
int mid = (left + right) >>> 1;
|
||||
if (check(tasks, workers, pills, strength, mid)) {
|
||||
left = mid;
|
||||
} else {
|
||||
right = mid;
|
||||
}
|
||||
}
|
||||
return left;
|
||||
}
|
||||
|
||||
private boolean check(int[] tasks, int[] workers, int pills, int strength, int k) {
|
||||
int i = 0;
|
||||
Deque<Integer> stack = new ArrayDeque<>();
|
||||
for (int j = workers.length - k; j < workers.length; j++) {
|
||||
int w = workers[j];
|
||||
while(i < k && w + strength >= tasks[i]) {
|
||||
stack.add(tasks[i]);
|
||||
i++;
|
||||
}
|
||||
|
||||
if (stack.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
if (w >= stack.peekFirst()) {
|
||||
stack.pollFirst();
|
||||
continue;
|
||||
}
|
||||
if (pills ==0) {
|
||||
return false;
|
||||
}
|
||||
pills--;
|
||||
stack.pollLast();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
43
src/main/java/com/dota/binarySearch/_3007/Solution.java
Normal file
43
src/main/java/com/dota/binarySearch/_3007/Solution.java
Normal file
@@ -0,0 +1,43 @@
|
||||
package com.dota.binarySearch._3007;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
class Solution {
|
||||
Map<Long, Long> map ;
|
||||
public long findMaximumNumber(long k, int x) {
|
||||
map = new HashMap<>();
|
||||
long l = 1, r = (k + 1) << x;
|
||||
while(l + 1 < r) {
|
||||
long mid = l + (r - l) / 2;
|
||||
if (check(k, x, mid)) {
|
||||
l = mid;
|
||||
} else {
|
||||
r = mid;
|
||||
}
|
||||
}
|
||||
return l;
|
||||
}
|
||||
boolean check(long k, int x, long num) {
|
||||
long res = 0;
|
||||
for (long i = 1; i <= num ; i++) {
|
||||
res += df(i, x);
|
||||
}
|
||||
return res <= k;
|
||||
}
|
||||
|
||||
// 计算n的价值
|
||||
long df(long n ,int x) {
|
||||
if (map.containsKey(n)) {
|
||||
return map.get(n);
|
||||
}
|
||||
long res = 0;
|
||||
n >>>= x-1;
|
||||
while(n != 0) {
|
||||
res += n&1;
|
||||
n >>>= x;
|
||||
}
|
||||
map.put(n, res);
|
||||
return res;
|
||||
}
|
||||
}
|
38
src/main/java/com/dota/binarySearch/_78/Solution.java
Normal file
38
src/main/java/com/dota/binarySearch/_78/Solution.java
Normal file
@@ -0,0 +1,38 @@
|
||||
package com.dota.binarySearch._78;
|
||||
|
||||
class Solution {
|
||||
public static void main(String[] args) {
|
||||
new Solution().rampartDefensiveLine(new int[][]{{0,3},{4,5},{7,9}});
|
||||
}
|
||||
public int rampartDefensiveLine(int[][] rampart) {
|
||||
int n = rampart.length;
|
||||
int l = 0, r = rampart[n - 1][1] + 1;
|
||||
while(l+1<r){
|
||||
int mid = l+(r-l)/2;
|
||||
if (check(rampart, mid)) {
|
||||
l = mid;
|
||||
} else {
|
||||
r = mid;
|
||||
}
|
||||
}
|
||||
return l;
|
||||
}
|
||||
|
||||
boolean check(int[][] rampart, int k) {
|
||||
int l = rampart[1][0] - rampart[0][1];
|
||||
int r;
|
||||
for (int i = 1; i < rampart.length - 1; i++) {
|
||||
r = rampart[i+1][0] - rampart[i][1];
|
||||
if (l >= k) {
|
||||
l = r;
|
||||
continue;
|
||||
}
|
||||
r -= (k-l);
|
||||
if (r < 0) {
|
||||
return false;
|
||||
}
|
||||
l = r;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
25
src/main/java/com/dota/deep/_386/Solution.java
Normal file
25
src/main/java/com/dota/deep/_386/Solution.java
Normal file
@@ -0,0 +1,25 @@
|
||||
package com.dota.deep._386;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
class Solution {
|
||||
public List<Integer> lexicalOrder(int n) {
|
||||
var res = new ArrayList<Integer>();
|
||||
for (int i = 1; i < 10; i++) {
|
||||
df(res, i, n);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
void df(List<Integer> list, int num, int n) {
|
||||
if (num > n) return;
|
||||
list.add(num);
|
||||
num *= 10;
|
||||
for (int i = 0; i < 10; i++) {
|
||||
num += i;
|
||||
df(list, num, n);
|
||||
num -= i;
|
||||
}
|
||||
}
|
||||
}
|
98
src/main/java/com/dota/week/_158/Solution.java
Normal file
98
src/main/java/com/dota/week/_158/Solution.java
Normal file
@@ -0,0 +1,98 @@
|
||||
package com.dota.week._158;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
class Solution {
|
||||
public int maximumProfit(int[] prices, int k) {
|
||||
int n = prices.length;
|
||||
|
||||
// 处理边缘情况:如果没有价格数据或 k 为 0,则无法进行交易,利润为 0。
|
||||
if (n == 0 || k == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// 当 k 足够大时(例如 k >= n - 1),意味着我们可以进行任意多次交易。
|
||||
// 由于允许普通交易和做空交易,我们可以抓住任何价格波动来盈利。
|
||||
// 例如,如果 prices[i+1] > prices[i],可以通过买入 prices[i] 卖出 prices[i+1] 赚取 prices[i+1] - prices[i]。
|
||||
// 如果 prices[i+1] < prices[i],可以通过做空 prices[i] 买回 prices[i+1] 赚取 prices[i] - prices[i+1]。
|
||||
// 两种情况下的利润都是 |prices[i+1] - prices[i]|。
|
||||
// 因此,当 k 足够大时,最大利润是所有相邻价格绝对差的总和。
|
||||
// 理论上,n-1 是最大可能利用的“单步”价格变动机会。
|
||||
if (k >= n - 1) {
|
||||
int maxProfit = 0;
|
||||
for (int i = 1; i < n; i++) {
|
||||
maxProfit += Math.abs(prices[i] - prices[i - 1]);
|
||||
}
|
||||
return maxProfit;
|
||||
}
|
||||
|
||||
// k 不够大,使用动态规划。
|
||||
// 状态定义:
|
||||
// noPos[j]: 完成 j 笔交易后,当前没有持仓的最大利润。
|
||||
// hasLong[j]: 完成 j 笔交易后,当前持有多头仓位(即为第 j+1 笔普通交易买入)的最大利润。
|
||||
// hasShort[j]: 完成 j 笔交易后,当前持有空头仓位(即为第 j+1 笔做空交易卖出)的最大利润。
|
||||
|
||||
// 初始化为极小的负数,表示不可达状态。
|
||||
// 使用 Integer.MIN_VALUE / 2 来避免在加减价格时发生溢出。
|
||||
final long INF = Long.MIN_VALUE / 2;
|
||||
|
||||
long[] noPos = new long[k + 1];
|
||||
long[] hasLong = new long[k + 1];
|
||||
long[] hasShort = new long[k + 1];
|
||||
|
||||
// 将所有状态初始化为不可达(负无穷大),除了初始基准状态。
|
||||
Arrays.fill(noPos, INF);
|
||||
Arrays.fill(hasLong, INF);
|
||||
Arrays.fill(hasShort, INF);
|
||||
|
||||
// 第 0 天的初始状态:
|
||||
noPos[0] = 0; // 完成 0 笔交易,无持仓,利润 0。
|
||||
hasLong[0] = -prices[0]; // 完成 0 笔交易,买入第一支股票(开启第 1 笔普通交易),利润为 -prices[0]。
|
||||
hasShort[0] = prices[0]; // 完成 0 笔交易,做空第一支股票(开启第 1 笔做空交易),利润为 prices[0]。
|
||||
|
||||
// 遍历每一天(从第 1 天开始到最后一天)
|
||||
for (int i = 1; i < n; i++) {
|
||||
int currentPrice = prices[i];
|
||||
|
||||
// 更新完成 0 笔交易的状态:
|
||||
// noPos[0] 保持 0,因为在没有交易的情况下无法产生利润。
|
||||
// hasLong[0]: 保持原有长仓利润,或者在当前价格买入(开启第一笔交易)。
|
||||
hasLong[0] = Math.max(hasLong[0], noPos[0] - currentPrice);
|
||||
// hasShort[0]: 保持原有短仓利润,或者在当前价格做空(开启第一笔交易)。
|
||||
hasShort[0] = Math.max(hasShort[0], noPos[0] + currentPrice);
|
||||
|
||||
// 遍历已完成的交易数 j(从 1 到 k)
|
||||
for (int j = 1; j <= k; j++) {
|
||||
// 保存当前 noPos[j] 的值,它代表了前一天的状态。
|
||||
// 这一点很重要,因为 hasLong[j] 和 hasShort[j] 的计算需要基于前一天的 noPos[j]。
|
||||
long prevNoPos_j = noPos[j];
|
||||
|
||||
// 更新 noPos[j]: 完成 j 笔交易,无持仓。
|
||||
// 1. 保持不变(从前一天的 noPos[j] 保持)。
|
||||
// 2. 从持有长仓状态(hasLong[j-1])卖出,完成第 j 笔交易。
|
||||
// 3. 从持有短仓状态(hasShort[j-1])买回,完成第 j 笔交易。
|
||||
// 注意:hasLong[j-1] 和 hasShort[j-1] 在当前 j 的迭代中尚未被更新,因此它们代表的是前一天的状态。
|
||||
noPos[j] = Math.max(noPos[j], hasLong[j-1] != INF ? hasLong[j-1] + currentPrice : INF);
|
||||
noPos[j] = Math.max(noPos[j], hasShort[j-1] != INF ? hasShort[j-1] - currentPrice : INF);
|
||||
|
||||
// 更新 hasLong[j]: 完成 j 笔交易,当前持有长仓。
|
||||
// 1. 保持不变(从前一天的 hasLong[j] 保持)。
|
||||
// 2. 从无持仓状态(prevNoPos_j,即前一天的 noPos[j])买入,开始第 j+1 笔普通交易。
|
||||
hasLong[j] = Math.max(hasLong[j], prevNoPos_j != INF ? prevNoPos_j - currentPrice : INF);
|
||||
|
||||
// 更新 hasShort[j]: 完成 j 笔交易,当前持有短仓。
|
||||
// 1. 保持不变(从前一天的 hasShort[j] 保持)。
|
||||
// 2. 从无持仓状态(prevNoPos_j,即前一天的 noPos[j])做空,开始第 j+1 笔做空交易。
|
||||
hasShort[j] = Math.max(hasShort[j], prevNoPos_j != INF ? prevNoPos_j + currentPrice : INF);
|
||||
}
|
||||
}
|
||||
|
||||
// 最终结果是所有 noPos[j] 中的最大值,因为我们希望最终不持有任何仓位以获得最大利润。
|
||||
long maxTotalProfit = 0; // 利润可以为 0(不交易)或负数(所有交易都亏损)。
|
||||
for (int j = 0; j <= k; j++) {
|
||||
maxTotalProfit = Math.max(maxTotalProfit, noPos[j]);
|
||||
}
|
||||
|
||||
return (int)maxTotalProfit;
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user