parent
e8d2eae9e7
commit
a64b46ff5a
@ -0,0 +1,72 @@
|
||||
package class_2023_07_4_week;
|
||||
|
||||
import java.util.PriorityQueue;
|
||||
|
||||
// 给你一个正整数数组 nums
|
||||
// 每一次操作中,你可以从 nums 中选择 任意 一个数并将它减小到 恰好 一半
|
||||
//(注意,在后续操作中你可以对减半过的数继续执行操作)
|
||||
// 请你返回将 nums 数组和 至少 减少一半的 最少 操作数
|
||||
// 测试链接 : https://leetcode.cn/problems/minimum-operations-to-halve-array-sum/
|
||||
public class Code01_MinimumOperationsToHalveArraySum {
|
||||
|
||||
public static int halveArray1(int[] nums) {
|
||||
PriorityQueue<Double> heap = new PriorityQueue<>((a, b) -> b.compareTo(a));
|
||||
double sum = 0;
|
||||
for (int num : nums) {
|
||||
heap.add((double) num);
|
||||
sum += num;
|
||||
}
|
||||
sum /= 2;
|
||||
int ans = 0;
|
||||
for (double minus = 0, cur; minus < sum; ans++, minus += cur) {
|
||||
cur = heap.poll() / 2;
|
||||
heap.add(cur);
|
||||
}
|
||||
return ans;
|
||||
}
|
||||
|
||||
public static int MAXN = 100001;
|
||||
|
||||
public static long[] heap = new long[MAXN];
|
||||
|
||||
public static int size;
|
||||
|
||||
public static int halveArray2(int[] nums) {
|
||||
size = nums.length;
|
||||
long sum = 0;
|
||||
for (int i = size - 1; i >= 0; i--) {
|
||||
heap[i] = (long) nums[i] << 20;
|
||||
sum += heap[i];
|
||||
heapify(i);
|
||||
}
|
||||
sum /= 2;
|
||||
int ans = 0;
|
||||
for (long minus = 0; minus < sum; ans++) {
|
||||
heap[0] /= 2;
|
||||
minus += heap[0];
|
||||
heapify(0);
|
||||
}
|
||||
return ans;
|
||||
}
|
||||
|
||||
public static void heapify(int i) {
|
||||
int l = i * 2 + 1;
|
||||
while (l < size) {
|
||||
int best = l + 1 < size && heap[l + 1] > heap[l] ? l + 1 : l;
|
||||
best = heap[best] > heap[i] ? best : i;
|
||||
if (best == i) {
|
||||
break;
|
||||
}
|
||||
swap(best, i);
|
||||
i = best;
|
||||
l = i * 2 + 1;
|
||||
}
|
||||
}
|
||||
|
||||
public static void swap(int i, int j) {
|
||||
long tmp = heap[i];
|
||||
heap[i] = heap[j];
|
||||
heap[j] = tmp;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,132 @@
|
||||
package class_2023_07_4_week;
|
||||
|
||||
// 多维费用背包(概念没用)
|
||||
// 给你一个二进制字符串数组 strs 和两个整数 m 和 n
|
||||
// 请你找出并返回 strs 的最大子集的长度,该子集中 最多 有 m 个 0 和 n 个 1
|
||||
// 如果 x 的所有元素也是 y 的元素,集合 x 是集合 y 的 子集
|
||||
// 测试链接 : https://leetcode.cn/problems/ones-and-zeroes/
|
||||
public class Code04_OnesAndZeroes {
|
||||
|
||||
public static int findMaxForm1(String[] strs, int m, int n) {
|
||||
int len = strs.length;
|
||||
int[][] arr = new int[len][2];
|
||||
for (int i = 0, zeros, ones; i < strs.length; i++) {
|
||||
zeros = 0;
|
||||
ones = 0;
|
||||
for (int j = 0; j < strs[i].length(); j++) {
|
||||
if (strs[i].charAt(j) == '0') {
|
||||
zeros++;
|
||||
} else {
|
||||
ones++;
|
||||
}
|
||||
}
|
||||
arr[i][0] = zeros;
|
||||
arr[i][1] = ones;
|
||||
}
|
||||
return process1(arr, 0, m, n);
|
||||
}
|
||||
|
||||
public static int process1(int[][] arr, int i, int z, int o) {
|
||||
if (i == arr.length) {
|
||||
return 0;
|
||||
}
|
||||
int p1 = process1(arr, i + 1, z, o);
|
||||
int p2 = 0;
|
||||
if (arr[i][0] <= z && arr[i][1] <= o) {
|
||||
p2 = 1 + process1(arr, i + 1, z - arr[i][0], o - arr[i][1]);
|
||||
}
|
||||
return Math.max(p1, p2);
|
||||
}
|
||||
|
||||
public static int findMaxForm2(String[] strs, int m, int n) {
|
||||
int len = strs.length;
|
||||
int[][] arr = new int[len][2];
|
||||
for (int i = 0, zeros, ones; i < strs.length; i++) {
|
||||
zeros = 0;
|
||||
ones = 0;
|
||||
for (int j = 0; j < strs[i].length(); j++) {
|
||||
if (strs[i].charAt(j) == '0') {
|
||||
zeros++;
|
||||
} else {
|
||||
ones++;
|
||||
}
|
||||
}
|
||||
arr[i][0] = zeros;
|
||||
arr[i][1] = ones;
|
||||
}
|
||||
int[][][] dp = new int[len][m + 1][n + 1];
|
||||
for (int i = 0; i < len; i++) {
|
||||
for (int j = 0; j <= m; j++) {
|
||||
for (int k = 0; k <= n; k++) {
|
||||
dp[i][j][k] = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
return process2(arr, 0, m, n, dp);
|
||||
}
|
||||
|
||||
// "101010101" -> 0 4个 1 5个 [4,5]
|
||||
// "000111" -> [3,3]
|
||||
public static int process2(int[][] arr, int i, int z, int o, int[][][] dp) {
|
||||
if (i == arr.length) {
|
||||
return 0;
|
||||
}
|
||||
if (dp[i][z][o] != -1) {
|
||||
return dp[i][z][o];
|
||||
}
|
||||
int p1 = process2(arr, i + 1, z, o, dp);
|
||||
// 要当前字符串
|
||||
int p2 = 0;
|
||||
if (arr[i][0] <= z && arr[i][1] <= o) {
|
||||
p2 = 1 + process2(arr, i + 1, z - arr[i][0], o - arr[i][1], dp);
|
||||
}
|
||||
int ans = Math.max(p1, p2);
|
||||
dp[i][z][o] = ans;
|
||||
return ans;
|
||||
}
|
||||
|
||||
public static int findMaxForm3(String[] strs, int m, int n) {
|
||||
int len = strs.length;
|
||||
int[][][] dp = new int[len + 1][m + 1][n + 1];
|
||||
for (int i = len - 1; i >= 0; i--) {
|
||||
zeroAndOne(strs[i]);
|
||||
for (int z = 0; z <= m; z++) {
|
||||
for (int o = 0; o <= n; o++) {
|
||||
dp[i][z][o] = dp[i + 1][z][o];
|
||||
if (zeros <= z && ones <= o) {
|
||||
dp[i][z][o] = Math.max(dp[i][z][o], 1 + dp[i + 1][z - zeros][o - ones]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return dp[0][m][n];
|
||||
}
|
||||
|
||||
public static int zeros, ones;
|
||||
|
||||
public static void zeroAndOne(String str) {
|
||||
zeros = 0;
|
||||
ones = 0;
|
||||
for (int i = 0; i < str.length(); i++) {
|
||||
if (str.charAt(i) == '0') {
|
||||
zeros++;
|
||||
} else {
|
||||
ones++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static int findMaxForm4(String[] strs, int m, int n) {
|
||||
int[][] dp = new int[m + 1][n + 1];
|
||||
for (String s : strs) {
|
||||
zeroAndOne(s);
|
||||
for (int i = m; i >= zeros; i--) {
|
||||
for (int j = n; j >= ones; j--) {
|
||||
dp[i][j] = Math.max(dp[i][j], dp[i - zeros][j - ones] + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
return dp[m][n];
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in new issue