每日一题20220623
- 2022-06-17:给定一个数组arr,含有n个数字,可能有正、有负、有0,
给定一个正数k。
返回所有子序列中,累加和最大的前k个子序列累加和。
假设K不大,怎么算最快?
来自Amazon。
/**
* 模型:求前k个前缀和最大的数组
*
* @param arr
* @param k
* @return
*/
public static int[] topMaxSum(int[] arr, int k) {
ArrayList<Integer> allAns = new ArrayList<>();
process(arr, 0, 0, allAns);
allAns.sort((a,b)->a.compareTo(b));
int[] ans = new int[k];
for (int i = allAns.size() -1,j=0;j<k;i--,j++){
ans[j] = allAns.get(i);
}
return ans;
}
/**
* 模型:递归模型:把数组的各个前缀和记录下来
*
* @param arr
* @param index
* @param sum
* @param ans
*/
public static void process(int[] arr, int index, int sum, ArrayList<Integer> ans) {
if (index == arr.length) {
ans.add(sum);
} else {
process(arr, index + 1, sum, ans);
process(arr, index + 1, sum + arr[index], ans);
}
}
- 2022-06-15:薯队长最近在参加了一个活动,主办方提供了N个礼物以供挑选,
每个礼物有一个价值,范围在0 ~ 10^9之间,
薯队长可以从中挑选k个礼物。
返回:其中价值最接近的两件礼物之间相差值尽可能大的结果。
小红书第二题。
薯队长最近在玩一个游戏,这个游戏桌上会有一排不同颜色的方块,
每次薯队长可以选择一个方块,便可以消除这个方块以及和他左右相临的
若干的颜色相同的方块,而每次消除的方块越多,得分越高。
具体来说,桌上有以个方块排成一排 (1 <= N <= 200),
每个方块有一个颜色,用1~N之间的一个整数表示,相同的数宇代表相同的颜色,
每次消除的时候,会把连续的K个相同颜色的方块消除,并得到K*K的分数,
直到所有方块都消除。显然,不同的消除顺序得分不同,薯队长希望您能告诉他,这个游戏最多能得到多少分。
小红书第三题。
————————————————
版权声明:本文为CSDN博主「福大大架构师每日一题」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_48502062/article/details/125304986
/**
* 模型:二分
*
* @param arr
* @param k
* @return
*/
public static int maxNear(int[] arr, int k) {
if (arr.length < k) {
return -1;
}
Arrays.sort(arr);
int n = arr.length;
int l = 0;
int r = arr[n - 1] - arr[0];
int m = 0;
int ans = 0;
while (l <= r) {
m = (l + r) / 2;
if (yeah(arr, k, m)) {
ans = m;
l = m + 1;
} else {
r = m - 1;
}
}
return ans;
}
/**
* 模型:判断是否合格
*
* @param arr
* @param k
* @param limit
* @return
*/
public static boolean yeah(int[] arr, int k, int limit) {
int last = arr[0];
int pick = 1;
for (int i=1;i<arr.length;i++){
if (arr[i] -last>=limit){
pick++;
last = arr[i];
}
}
return pick>=k;
}
- 2022-06-14:数组的最大与和。
给你一个长度为 n 的整数数组 nums 和一个整数 numSlots ,满足2 * numSlots >= n 。总共有 numSlots 个篮子,编号为 1 到 numSlots 。
你需要把所有 n 个整数分到这些篮子中,且每个篮子 至多 有 2 个整数。一种分配方案的 与和 定义为每个数与它所在篮子编号的 按位与运算 结果之和。
比方说,将数字 [1, 3] 放入篮子 1 中,[4, 6] 放入篮子 2 中,这个方案的与和为 (1 AND 1) + (3 AND 1) + (4 AND 2) + (6 AND 2) = 1 + 1 + 0 + 2 = 4 。
请你返回将 nums 中所有数放入 numSlots 个篮子中的最大与和。
力扣2172。
答案2022-06-14:
km算法。
————————————————
版权声明:本文为CSDN博主「福大大架构师每日一题」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_48502062/article/details/125286059
/**
* 模型:km模型 最优匹配问题
*
* @param arr
* @param m
* @return
*/
public static int maximumANDSum(int[] arr, int m) {
m <<= 1;
int[][] graph = new int[m][m];
for (int i = 0; i < arr.length; i++) {
for (int j = 0, num = 1; j < m; num++, j += 2) {
graph[i][j] = arr[i] & num;
graph[i][j + 1] = arr[i] & num;
}
}
return km(graph);
}
/**
* 模型:km模型
*
* @param graph
* @return
*/
public static int km(int[][] graph) {
int N = graph.length;
int[] match = new int[N];
int[] lx = new int[N];
int[] ly = new int[N];
boolean[] x = new boolean[N];
boolean[] y = new boolean[N];
int[] slack = new int[N];
int invalid = Integer.MAX_VALUE;
for (int i = 0; i < N; i++) {
match[i] = -1;
lx[i] = -invalid;
for (int j = 0; j < N; j++) {
lx[i] = Math.max(lx[i], graph[i][j]);
}
ly[i] = 0;
}
for (int from = 0; from < N; from++) {
for (int i = 0; i < N; i++) {
slack[i] = invalid;
}
Arrays.fill(x, false);
Arrays.fill(y, false);
//判断是否冲突
while (!dfs(from, x, y, lx, ly, match, slack, graph)) {
int d = invalid;
for (int i = 0; i < N; i++) {
if (!y[i] && slack[i] < d) {
d = slack[i];
}
}
for (int i = 0; i < N; i++) {
if (x[i]) {
lx[i] = lx[i] - d;
}
if (y[i]) {
ly[i] = ly[i] + d;
}
}
Arrays.fill(x, false);
Arrays.fill(y, false);
}
}
int ans = 0;
for (int i = 0; i < N; i++) {
ans += (lx[i] + ly[i]);
}
return ans;
}
/**
* 模型:dfs模型。
*
* @param from
* @param x
* @param y
* @param lx
* @param ly
* @param match 表示连接
* @param slack 最大值数组
* @param map 连接点
* @return
*/
public static boolean dfs(int from, boolean[] x, boolean[] y, int[] lx, int[] ly, int[] match, int[] slack, int[][] map) {
int N = map.length;
x[from] = true;
for (int to = 0; to < N; to++) {
if (!y[to]) {
int d = lx[from] + ly[to] - map[from][to];
if (d != 0) {
slack[to] = Math.min(slack[to], d);
} else {
y[to] = true;
if (match[to] == -1 || dfs(match[to], x, y, lx, ly, match, slack, map)) {
match[to] = from;
return true;
}
}
}
}
return false;
}

浙公网安备 33010602011771号