第一题
思路:二分答案 + 滑动窗口
public class 第一题01 {
public static void main(String[] args) {
int[] a = {2,4,5,6};
int[] b = {8,7,1,3};
int res = lessGap(a, b, 7);
System.out.println(res);
}
/**
*
* @param a 愉悦值
* @param b 财富值
* @param k 愉悦阈值
* @return
*/
//二分答案
public static int lessGap(int[] a,int[] b,long k){
int n = a.length;
int[][] f = new int[n][2];
int min = b[0];
int max = b[0];
for (int i = 0;i < n;i++){
f[i][0] = a[i];
f[i][1] = b[i];
min = Math.min(min,b[i]);
max = Math.max(max,b[i]);
}
Arrays.sort(f,(x,y) -> x[1] - y[1]);
int l = 0;
int r = max - min;
int ans = -1;
while (l <= r){
int mid = (l + r) / 2;
if (maxHappy(f,mid) >= k){
ans = mid;
r = mid - 1;
}else {
l = mid + 1;
}
}
return ans;
}
//滑动窗口
private static int maxHappy(int[][] f, int limit) {
int n = f.length;
int sum = 0;
int ans = 0;
for (int l = 0,r = 0;l < n;l++){
while (r < n && f[r][1] - f[l][1] <= limit){
sum += f[r++][0];
}
ans = Math.max(ans,sum);
sum -= f[l][0];
}
return ans;
}
}
第二题
思路:二分答案法
public class 第二题01 {
public static void main(String[] args) {
int[] arr = {3,3,3};
long res = maxRunTime(2, arr);
System.out.println(res);
}
public static long maxRunTime(int n,int[] batteries){
Arrays.sort(batteries);
int size = batteries.length;
long[] pre = new long[size + 1];
for (int i = 1;i <= size;i++){
pre[i] = batteries[i - 1] + pre[i - 1];
}
long l = 0;
long r = pre[size];
long ans = 0;
while (l <= r){
long mid = (l + r) / 2;
if (/*ok1(batteries,pre,n,mid)*/ok2(batteries,pre,n,mid)){
ans = mid;
l = mid + 1;
}else {
r = mid - 1;
}
}
return ans;
}
private static boolean ok2(int[] arr, long[] pre, int k, long limit) {
int l = 0;
int r = arr.length - 1;
int index = arr.length;
while (l <= r){
int m = (l + r) / 2;
if (arr[m] >= limit){
index = m;
r = m - 1;
}else {
l = m + 1;
}
}
long sum = pre[index];
int count = k - (arr.length - index);
return sum >= count * limit;
}
private static boolean ok1(int[] arr, long[] pre, int k, long limit) {
int index = 1;
while (index < pre.length){
if (pre[index] - pre[index - 1] >= limit){
break;
}
index++;
}
long sum = pre[index - 1];
int count = k - (pre.length - index);
if (sum < count * limit){
return false;
}
return true;
}
}
第三题
思路:二分答案法 + 数学公式(找规律)
public class 第三题01 {
public static int reachNumber(int target) {
if (target == 0){
return -1;
}
target = Math.abs(target);
long l = 0;
long r = target;
long index = 0;
while (l <= r){
long mid = (l + r) / 2;
if (sum(mid) >= target){
index = mid;
r = mid - 1;
}else {
l = mid + 1;
}
}
if (sum(index) == target){
return (int)index;
}
if ((sum(index) - target) % 2 == 1){
index++;
}
if ((sum(index) - target) % 2 == 1){
index++;
}
return (int)index;
}
private static long sum(long mid) {
return mid * (mid + 1) / 2;
}
}